[[383773]] この記事はWeChatの公開アカウント「Ask Qi」から転載したもので、著者はChen Shaowenです。記事を転載する場合は公式アカウントまでご連絡ください。 1. Docker への移行は CICD に新たな課題をもたらす CICD シナリオでは、パイプラインでイメージをビルドしてプッシュする必要があることがよくあります。 以前のドキュメント「Kubernetes上でJenkinsスレーブを動的に作成する」[1]では、/var/run/docker.sockファイルをマウントして、DockerベースのKubernetesクラスターでイメージをビルドおよびプッシュできるようにする方法について説明しました。 DockerのDockerの使い方[2]という文書では、これについてさらに詳しく説明しています。原則としては、ホスト Docker デーモンを共有することです。 バージョン 1.20 以降、Kubernetes コミュニティは Docker のサポートを放棄し、その後他のコミュニティが引き継いだため、Docker に影が落ちました。このような状況の中で、私たちは非Docker環境でCICDを実践する方法を検討し始めました。 非 Docker 環境では、/var/run/docker.sock をマウントする以前の方法は無効であり、新しい解決策を見つける必要があります。 2. クラスタ環境をテストする 2.1 Kubernetes - 1.17.9 Kubernetes のバージョンを表示するには、次のコマンドを実行します。 - kubectl バージョン
-
- クライアント バージョン: version.Info{メジャー: "1" 、マイナー: "17" 、GitVersion: "v1.17.9" 、GitCommit: "4fb7ed12476d57b8437ada90b4f93b17ffaeed99" 、GitTreeState: "clean" 、BuildDate: "2020-07-15T16:18:16Z" 、GoVersion: "go1.13.9" 、コンパイラ: "gc" 、プラットフォーム: "linux/amd64" }
- サーバー バージョン: version.Info{メジャー: "1" 、マイナー: "17" 、GitVersion: "v1.17.9" 、GitCommit: "4fb7ed12476d57b8437ada90b4f93b17ffaeed99" 、GitTreeState: "clean" 、BuildDate: "2020-07-15T16:10:45Z" 、GoVersion: "go1.13.9" 、コンパイラ: "gc" 、プラットフォーム: "linux/amd64" }
2.2 コンテナ - 1.4.3 containerd のバージョンを表示するには、次のコマンドを実行します。 - コンテナ
-
- コンテナd github.com/containerd/containerd v1.4.3 269548fa27e0089a8b8278fc4fc781d7f65a939b
3. 画像管理ツールPodman Containerd は Docker API をサポートしていないため、docker build や docker push などの一般的なコマンドは Containerd 環境では使用できません。そのため、Docker に依存しない OCI 標準に基づいたイメージを構築およびプッシュするためのツールが必要です。 3.1 Podmanの紹介 Podman は、OCI 標準を実装するコンテナおよびイメージ管理ツールです。また、デーモンレスであり、デーモン プロセスを必要とせず、特権のないユーザーによる使用をサポートします。 Podman は Docker CLI と同様の機能を提供します。ほとんどの場合、 alias docker=podman を実行すると、問題なく Docker を Podman に置き換えることができます。 3.2 ポッドマンのインストール - Podmanコマンドラインツールをインストールする
インストール手順についてはPodmanのインストールガイド[3]を参照してください。ここでは CentOS 7 を例に挙げます。 - curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
- yum -y ポッドマンをインストールします
- podman
-
- ポッドマン バージョン 3.0.1
簡単に参照できるように、完全なヘルプ ドキュメントがここに掲載されています。 - ポッドマン
- ポッドとイメージを管理する
-
- 使用法:
- ポッドマン [フラグ]
- podman [コマンド]
-
- 使用可能なコマンド:
- 実行中のコンテナにアタッチする
- ビルドContainerfilesの指示に従ってイメージをビルドする
- 専念 変更されたコンテナに基づいて新しいイメージを作成する
- コンテナ コンテナの管理
- cpコンテナとローカルファイルシステム間でファイル/フォルダをコピーする
- 作成する コンテナを作成するが起動しない
- diffコンテナのファイルシステムの変更を検査する
- イベント podman イベントを表示
- exec実行中のコンテナ内でプロセスを実行する
- エクスポート コンテナのファイルシステムの内容をtar アーカイブとしてエクスポートします。
- 生成された構造化データ
- ヘルスチェック ヘルスチェックの管理
- ヘルプコマンドに関するヘルプ
- 履歴指定した画像の履歴を表示する
- 画像 画像を管理する
- 画像 画像を一覧表示する ローカルストレージ
- import tarballをインポートする ファイルシステムイメージを作成する
- info podman システム情報を表示する
- init 1つ以上のコンテナを初期化する
- コンテナまたはイメージの構成を表示する
- kill特定のシグナルで実行中のコンテナを1つ以上強制終了します
- 負荷 コンテナアーカイブからイメージをロードする
- ログインコンテナレジストリにログイン
- ログアウトコンテナレジストリからログアウトする
- コンテナのログを取得する
- マウント 作業コンテナのルートファイルシステムをマウントする
- ネットワーク ネットワークの管理
- 1つまたは複数のコンテナ内のすべてのプロセスを一時停止します
- ポッドを再生する
- ポッド ポッドを管理する
- portコンテナのポートマッピングまたは特定のマッピングを一覧表示します
- ps コンテナを一覧表示する
- pullレジストリからイメージをプルする
- プッシュ指定された宛先にイメージをプッシュする
- 再起動 1つ以上のコンテナを再起動する
- rm 1つまたは複数のコンテナを削除する
- rmi 1つまたは複数の画像を削除します ローカルストレージ
- 実行新しいコンテナでコマンドを実行する
- 保存 画像をアーカイブに保存する
- レジストリで画像を検索
- 開始 1つ以上のコンテナを起動する
- 統計コンテナリソースの使用統計のライブストリームを表示します
- 1つ以上のコンテナを停止する
- システム管理 podman
- タグ追加の名前を追加する ローカルイメージに
- コンテナの実行中のプロセスを表示する
- umount 作業コンテナのルートファイルシステムをアンマウントします
- 一時停止解除1つ以上のコンテナ内のプロセスの一時停止を解除します
- unshare変更されたユーザー名前空間でコマンドを実行する
- varlink varlinkインターフェースを実行する
- version Podmanのバージョン情報を表示する
- ボリュームを管理する
- 1つ以上のコンテナでブロックを待機する
-
- フラグ:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -v,
-
- 「podman [コマンド] --help」を使用します コマンドの詳細については、こちらをご覧ください。
Podman は Docker コマンドをカバーし、Pod 操作のサポートを追加します。 3.3 ホスト上でコンパイルをテストし、イメージをプッシュする docker コマンドを podman に直接置き換えることができます。 - echo -e 'FROMbusybox\nRUN echo "hello world"' | podman ビルド -t docker.io/shaowenchen/myimage:latest -
-
- ステップ1:ビジーボックスから
- 画像ソース署名の取得
- ブロブ 5c4213be9af9 のコピーが完了しました
- 設定 491198851f のコピーが完了しました
- マニフェストをイメージの保存先に書き込む
- 署名の保存
- ステップ 2: echo "hello world"を実行します。
- こんにちは世界
- ステップ3:コミット
- 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c
- 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c
- ポッドマン イメージ |grep シャオウェンチェン
- docker.io/shaowenchen/myimage 最新 4c8794086d9d 4 分前 1.46 MB
- ポッドマン ログイン docker.io -u シャオウェンチェン
-
- パスワード:
- ログインに成功しました!
- ポッドマンプッシュ docker.io/shaowenchen/myimage:latest
-
- 画像ソース署名の取得
-
- BLOB 2893437c336c のコピーが完了しました
- BLOB 84009204da3f のコピーが完了しました
- 設定 4c8794086d のコピーが完了しました
- マニフェストをイメージの保存先に書き込む
- 署名の保存
4. Podmanを使用してJenknsでイメージを構築する 4.1 キー設定 - hostPathを使用してホストに/var/lib/containersをマウントします
PVC を使用することもできますが、PVC には追加のパラメータが必要になる場合があります。以下を参照してください。 そうでない場合は、次のエラーが発生します。 - エラー: 'オーバーレイ' は overlayfs ではサポートされていないため、mount_programが必要です。このグラフ ドライバーでは、バックアップ ファイル システムがサポートされていません。
そうでない場合は、次のエラーが発生します。 - エラー: カーネルはオーバーレイ fs: 'overlay'をサポートしていません は extfsではサポートされていません "/var/lib/containers/storage/overlay" :このグラフ ドライバーでは、バックアップ ファイル システムはサポートされていません
- Podman パラメータ --cgroup-manager=cgroupfs
PVC をストレージ ディレクトリとして使用する場合は、この構成を考慮する必要があります。カーネルは、Cgroup ドライバーを通じてリソースのグループを分離します。オプションのパラメータは cgroupfs と systemd であり、これらは同じカーネルを共有するため、クラスタ環境と一貫性を保つ必要があります。私のテスト環境では cgroupfs を使用しています。 そうでない場合は、次のエラーが発生します。 - システムイベントを書き込めません: "write unixgram @0011c->/run/systemd/journal/socket: sendmsg:そのようなファイルまたはディレクトリはありません
- Podman パラメータ --events-backend=file
この構成は通常、実行プロセスをブロックしませんが、ログをよりクリーンな状態に保ちたい場合に追加できます。 そうでない場合は、次のエラーが発生します。 - システムイベントを書き込めません: "write unixgram @0011c->/run/systemd/journal/socket: sendmsg:そのようなファイルまたはディレクトリはありません
4.2 例1: JenkinsfileでYAMLテンプレートを明示的に使用する ここで、コンテナ /var/lib/containers はホストの /var/lib/containers ディレクトリにマウントされます。ホストの /tmp ディレクトリにマウントすることもできます。必須要件はありません。ホスト ディレクトリは、単にデータを保存する場所を提供します。 - パイプライン
- エージェント
- Kubernetes {
- yaml "" "
- APIバージョン: v1
- 種類: ポッド
- 仕様:
- コンテナ:
- -名前: centos
- 画像: centos:7
- 指示:
- - 猫
- 端末:真
- セキュリティコンテキスト:
- 特権: true
- ボリュームマウント:
- -名前: ストレージ
- マウントパス: /var/lib/containers
- ボリューム:
- -名前: ストレージ
- ホストパス:
- パス: /var/lib/containers
- 「」 「 」
- }}
- ステージ {
- ステージ( 'こんにちは' ){
- 手順 {
- コンテナ( 'centos' ) {
- sh '' '
- curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_7/devel:kubic:libcontainers:stable.repo
- yum -y ポッドマンをインストールします
- echo -e 'FROMbusybox\nRUN echo "hello world"' | podman
- podman
- '' '
- }
- }
- }
- }
- }
Jenkins 実行ログ: - ···
- 依存関係が更新されました:
- systemd.x86_64 0:219-78.el7_9.3 システムd-libs.x86_64 0:219-78.el7_9.3
-
- 完了!
- + podman
- + echo -e 'ビジーボックスから
- 実行エコー「hello world」 '
- ステップ1:ビジーボックスから
- ステップ 2: echo "hello world"を実行します。
-
- ステップ3: docker.io/shaowenchen1/myimage:latestをコミットする
-
- 4c8794086d9de80f71d182457b6d2cb18b9d61975b98bcd4cb167bdcabae5b2c
- + podman
- + grep shaowenchen1
- docker.io/shaowenchen1/myimage 最新 4c8794086d9d 19 時間前 1.46 MB
4.3 例2: PVCを使用して/var/lib/containersディレクトリをマウントする PVC を使用して Podman データを保存する場合は、事前にクラスター ストレージを準備する必要があります。 - クラスターにデフォルトのStorageClassがあるかどうかを確認する
- kubectl 取得 sc
-
- 名前プロビジョナー RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
- openebs-device openebs.io/ローカル WaitForFirstConsumerを削除false 19d
- openebs-hostpath (デフォルト) openebs.io/ local WaitForFirstConsumerを削除false 19d
- openebs-jiva-デフォルトopenebs.io/provisioner-iscsi即時削除false 19d
- openebs-snapshot-promoter volumesnapshot.external-storage.k8s.io/snapshot-promoter即時削除false 19d
ここでの名前空間は、Jenkins の動的エージェントが配置されている名前空間と一致している必要があります。 - 猫 <<EOF | kubectl を適用 -f -
- APIバージョン: v1
- 種類: PersistentVolumeClaim
- メタデータ:
- 名前: ストレージ
- 名前空間:デフォルト
- 仕様:
- アクセスモード:
- -一度だけ読み書き可能
- リソース:
- リクエスト:
- ストレージ: 30Gi
- 終了
- kubectl -nデフォルトでPVCを取得する
-
- 名前ステータス ボリューム 容量 アクセス モード
- ストレージ保留中 openebs-hostpath 11s
WaitForFirstConsumer モードが使用されるため、Pod が PVC を使用するまで PV はバインドされません。 - パイプライン
- エージェント
- Kubernetes {
- yaml "" "
- APIバージョン: v1
- 種類: ポッド
- 仕様:
- コンテナ:
- -名前: centos
- 画像: centos:7
- 指示:
- - 猫
- 端末:真
- セキュリティコンテキスト:
- 特権: true
- ボリュームマウント:
- -名前: ストレージ
- マウントパス: /var/lib/containers
- ボリューム:
- -名前: ストレージ
- 永続ボリュームクレーム:
- クレーム名: ストレージ
- 「」 「 」
- }}
- ステージ {
- ステージ( 'こんにちは' ){
- 手順 {
- コンテナ( 'centos' ) {
- sh '' '
- curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_7/devel:kubic:libcontainers:stable.repo
- yum -y ポッドマンをインストールします
- echo -e 'FROMbusybox\nRUN echo "hello world"' | podman
- podman
- '' '
- }
- }
- }
- }
- }
Jenkins 実行ログ: - ···
- 依存関係が更新されました:
- systemd.x86_64 0:219-78.el7_9.3 システムd-libs.x86_64 0:219-78.el7_9.3
-
- 完了!
- + echo -e 'ビジーボックスから
- 実行エコー「hello world」 '
- + podman
- ステップ1:ビジーボックスから
- ステップ 2: echo "hello world"を実行します。
-
- ステップ 3: docker.io/shaowenchen2/myimage:latestをコミットします。
-
- f4676f5b5e47a78970f2d97f4a5b77423f381e9742faae06d8c1a2d93bdb27c2
- + podman
- + grep shaowenchen2
- docker.io/shaowenchen2/myimage 最新 f4676f5b5e47 2 時間前 1.46 MB
5. 結論 この記事では主に、Docker の代わりに Podman を使用して、非 Docker 駆動の Kubernetes クラスターで CICD イメージを構築するアイデアを提供します。 Podman を選択した理由は、その使用方法が Docker に近いためです。一方、Buildah では buildah bud を使用するため、ユーザーはイメージのコンパイル手順を変更する必要があります。 実際の運用では、Podman コマンドを CI エージェントのベース イメージにパッケージ化する必要があります。 Docker コマンドに基づいてパイプラインを置き換えるには、エイリアス docker=podman を使用します。 Podman を使用する際の重要なポイントを簡単にまとめると次のようになります。 - キャッシュをサポートします。 /var/lib/containers ディレクトリをマウントすることで、イメージをキャッシュし、業務に応じて異なるディレクトリに分割することができます。
- Docker のシームレスな代替品。フックがあれば、ユーザーは気づかれずに切り替えができます。
- より多用途に。これは OCI 標準に従って実装されており、特定のコンポーネントに依存しません。
- 特権モード。コンテナ内で Podman を実行するには特権モードが必要です。入れ子人形がこの動作モードから抜け出すのは困難です。
6. 参考文献 https://github.com/kubernetes-sigs/cri-tools http://docs.podman.io/en/latest/ 参考文献 [1] 「Kubernetes上でJenkinsスレーブを動的に作成する」:https://www.chenshaowen.com/blog/creating-jenkins-slave-dynamically-on-kubernetes.html [2] DockerでDockerを使用する方法: https://www.chenshaowen.com/blog/how-to-use-docker-in-docker.html [3] Podmanのインストール手順: https://podman.io/getting-started/installation |