序文Kubernetes に必要なコンテナイメージを構築するにはどうすればよいでしょうか?答えは Docker だと思います。はい、Docker がまさに第一の選択肢です。 CI/CD に Jenkins を使用してコンテナ イメージを構築する場合、通常は Jenkins サービスを物理マシンにデプロイし、物理マシンの docker build コマンドを使用してイメージを構築します。ただし、Jenkins on K8s 環境では、Jenkins マスターと Jenkins スレーブの両方が Kubernetes クラスターのノード上でポッドとして実行されます。私たちのビルド環境はすべて Pod であり、docker コマンドはありません。 ご存知のとおり、Kubernetes はバージョン V1.24.x 以降ではデフォルトで containerd をコンテナ ランタイムとして使用しており、Docker はサポートされなくなりました。ホスト上で /var/run/docker.sock は使用できなくなりました。 Kubernetes クラスターでコンテナ イメージを構築するには別の方法が必要です。この記事では Kaniko ツールを紹介します。 カニコとはGithubアドレス: https://github.com/GoogleContainerTools/kaniko Kaniko は、Kubernetes でコンテナ イメージを構築するために Google がオープンソース化したツールです。 Kaniko は Docker と同様に Dockerfile からコンテナ イメージを構築するためのツールですが、主な違いは Kaniko はコンテナ内で実行できること、つまり Kubernetes クラスター内で実行できることです。特権モードは必要なく、ソケットを公開する必要もありません。クラスターのノードで Docker を実行する必要はないため、コンテナの実行にどのコンテナ エンジンを使用するかは問題ではありません。重要なのは、Kaniko がコンテナ内にコンテナ イメージを構築し、それをホスト マシン上の Docker から切り離された Kubernetes クラスター内に自動的に構築できることです。これにより、より安全で信頼性が高まります。特徴は次のとおりです。 - docker 内の docker
- Dockerデーモンに依存しない
- 権限不要、安全な構築
- 必要なコマンドは1つだけです
- Dockerfileビルドをサポート
それでは、カニコを段階的に探索してみましょう。 Kubernetes で Kaniko を使用するKaniko はコンテナとして実行され、Dockerfile、コンテキスト、リモート イメージ リポジトリのアドレスという 3 つのパラメータが必要です。 動作原理: - 指定されたDockerfileを読み込んで解析する
- ベースイメージ(DockerfileのFROMイメージ)のファイルシステムを抽出します。
- 各コマンドを別々のDockerfileで個別に実行する
- 各実行後にユーザー空間ファイルシステムのスナップショットが取得されます。
- 実行するたびに、スナップショットレイヤーをベースレイヤーに追加し、イメージメタデータを更新します。
- 最後に画像をプッシュします
前提条件: - 実行中のKubernetesクラスタが必要です
- イメージ レジストリにプッシュするために必要な認証情報を含む Kubernetes シークレットを作成する必要があります。
- Dockerfileを準備する必要があります
Dockerfileを作成するDockerfile を記述し、k8s で configmap を作成します。 [root@localhost ~]# cat Dockerfile FROM ubuntu ENTRYPOINT ["/bin/bash", "-c", "echo hello"] [root@localhost ~]# kubectl create configmap kaniko-dockerfile --from-file=./Dockerfile configmap/kaniko-dockerfile created イメージリポジトリの認証情報用のシークレットを作成するAlibaba Cloud イメージ リポジトリに資格情報をプッシュし、Docker がインストールされているマシンを見つけて、リポジトリにログインするための構成 kaniko を作成します。 [root@localhost ~]# docker login --username=xxx registry.cn-shanghai.aliyuncs.com Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded ログインが成功すると、config.json ファイルが生成されます。このファイルを使用して、kaniko コンテナーが使用するシークレットを作成します。 - Centos 環境でのファイルの場所: /root/.docker/config.json
- Ubuntu 環境でのファイルの場所: /home/ubuntu/.docker/config.json
[root@localhost ~]# kubectl create secret generic kaniko-secret --from-file=/root/.docker/config.json secret/kaniko-secret created kanikoコンテナを起動してイメージをビルドしますkaniko_build_image.yaml: apiVersion: v1 kind: Pod metadata: name: kaniko spec: containers: - name: kaniko image: gcr.io/kaniko-project/executor:latest args: ["--dockerfile=/workspace/Dockerfile", "--context=dir://workspace", "--destination=registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo:1.0"] # 替换成自己的仓库地址volumeMounts: - name: kaniko-secret mountPath: /kaniko/.docker - name: dockerfile mountPath: /workspace volumes: - name: kaniko-secret secret: secretName: kaniko-secret items: - key: config.json path: config.json - name: dockerfile configMap: name: kaniko-dockerfile - args 部分: この部分は上で説明したものです。 Kaniko を実行するには、Dockerfile (--dockerfile)、コンテキスト (--context)、リモート イメージ リポジトリ (--destination) の 3 つのパラメータが必要です。
- シークレット部分:指定したリモートイメージリポジトリへのプッシュには認証が必要なので、シークレットとして/kaniko/.docker/ディレクトリにマウントされ、ファイル名はconfig.jsonとなる
ポッドを作成し、ステータスを確認して、ログが正常に完了しているかどうかを確認します。 [root@localhost ~]# kubectl apply -f kaniko_build_image.yaml pod/kaniko created [root@localhost ~]# kubectl get pod NAME READY STATUS RESTARTS AGE kaniko 1/1 Running 0 3s [root@localhost ~]# kubectl logs -f kaniko INFO[0000] Retrieving image manifest ubuntu INFO[0000] Retrieving image ubuntu from registry index.docker.io INFO[0003] Built cross stage deps: map[] INFO[0003] Retrieving image manifest ubuntu INFO[0003] Returning cached image manifest INFO[0003] Executing 0 build triggers INFO[0003] Building stage 'ubuntu' [idx: '0', base-idx: '-1'] INFO[0003] Skipping unpacking as no commands require it. INFO[0003] ENTRYPOINT ["/bin/bash", "-c", "echo hello"] INFO[0003] Pushing image to registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo:1.0 INFO[0004] Pushed registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo@sha256:d1855cc00550f9048c88b507626e0f24acf4c22e02856e006b2b9fdb0b80e567 Alibaba Cloud イメージリポジトリがアップロードされていることを確認します。 kaniko によって生成されたイメージを使用して、それが利用可能かどうかをテストします。 [root@localhost ~]# docker run -it --rm registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo:1.0 Unable to find image 'registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo:1.0' locally 1.0: Pulling from kubesre02/kaniko-demo 445a6a12be2b: Pull complete Digest: sha256:49bb962115b70a15a99b87e48fda28a883758081e41aef14766833d3a1578069 Status: Downloaded newer image for registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko-demo:1.0 hello helloが出たら成功です。 Kaniko イメージのカスタマイズ公式の kaniko イメージはゼロから構築されており、シェルはありません。 kanikoネイティブイメージでシェルコマンドを呼び出すのは非常に面倒です。つまり、自分だけのプライベート Kaniko イメージをカスタマイズできるのです。 kaniko のキー ファイルは、実際には /kaniko ディレクトリ内のバイナリ ファイルです。公式の推奨事項は、gcr.io/kaniko-project/executor イメージを使用することです。 /kaniko ディレクトリ内の executor を独自のプライベート イメージ Dockerfile にコピーできます。 FROM gcr.io/kaniko-project/executor:latest AS plugin FROM ubuntu ENV DOCKER_CONFIG /kaniko/.docker COPY --from=plugin /kaniko/executor /usr/local/bin/kaniko RUN mkdir -p /kaniko/.docker/ COPY config.json /kaniko/.docker/ 上記の Dockerfile は、Ubuntu をベースにした Docker イメージを構築します。 (1) gcr.io/kaniko-project/executor:latest ASプラグインから - gcr.io/kaniko-project/executor:latest という名前の Docker イメージから一時ステージの構築を開始し、plugin という名前を付けます。
- このステップでは、Kaniko ツールがすでに含まれている Docker イメージ内に中間コンテナを構築します。
(2)Ubuntuから 次に、公式の Ubuntu ベースイメージに基づいて新しい Docker イメージを作成します。 (3) ENV DOCKER_CONFIG /kaniko/.docker 環境変数 DOCKER_CONFIG を、Kaniko ツールで使用される Docker 構成ディレクトリである /kaniko/.docker に設定します。これは、Kaniko が必要な Docker 構成情報を確実に見つけられるようにするためです。 (4) コピー --from=plugin /kaniko/executor /usr/local/bin/kaniko 以前にビルドしたプラグイン フェーズ イメージから /kaniko/executor ファイルを新しいイメージの /usr/local/bin/kaniko パスにコピーします。これにより、Kaniko バイナリが新しい Ubuntu イメージにコピーされ、後でそのイメージで使用できるようになります。 (5) mkdir -p /kaniko/.docker/を実行する Docker 構成ファイルを保存するために、新しいイメージに /kaniko/.docker/ ディレクトリを作成します。 (6) config.jsonをコピーする /kaniko/.docker/ ローカルの config.json ファイルを新しいイメージの /kaniko/.docker/ ディレクトリにコピーします。この config.json ファイルには、Kaniko が Docker イメージにアクセスしてプッシュできるようにするための Docker リポジトリの資格情報やその他の構成が含まれている可能性があります。 最終的には、この Docker イメージに Ubuntu オペレーティング システムと Kaniko ツールが含まれ、Kaniko に必要な Docker 環境が構成され、Kaniko を使用してコンテナー内に Docker イメージを構築し、ある程度の分離性とセキュリティを維持しながらシェル環境を構築できるようになります。イメージをビルドしてアップロードします。 [root@localhost ~]# docker build -t registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko:latest . Sending build context to Docker daemon 212.1MB Step 1/6 : FROM gcr.io/kaniko-project/executor:latest AS plugin ---> 03375da0f864 Step 2/6 : FROM ubuntu ---> aa786d622bb0 Step 3/6 : ENV DOCKER_CONFIG /kaniko/.docker ---> Using cache ---> f7cd726aa130 Step 4/6 : COPY --from=plugin /kaniko/executor /usr/local/bin/kaniko ---> Using cache ---> 8fcac536196f Step 5/6 : RUN mkdir -p /kaniko/.docker/ ---> Using cache ---> 1afce75446a3 Step 6/6 : COPY config.json /kaniko/.docker/ ---> Using cache ---> 4a2873a75a7c Successfully built 4a2873a75a7c Successfully tagged registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko:latest [root@localhost ~]# docker push registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko:latest The push refers to repository [registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko] 0cb4fb37580b: Pushed c9dbd3644e5a: Pushed 33a2214b827c: Pushed c5077dd8160b: Pushed 948c7f86fd48: Pushed 403aab81b15b: Pushed 7bff100f35cb: Pushed latest: digest: sha256:b5642885f1333a757625cbe36a9b1102aba27646f2572acab79861a74dba1050 size: 1783 カニコ その他のパラメータ- --context: ビルド コンテキストへのパスを指定します。デフォルトでは、コンテキストは Dockerfile が配置されているディレクトリです。 -c と省略可能
- --dockerfile: 使用する Dockerfile へのパスを指定します。デフォルトでは、Kaniko はコンテキスト内で Dockerfile という名前のファイルを検索します。 -f と省略可能
- --destination: ビルドが完了した後の Docker イメージの名前を指定します。タグを含めることができます。たとえば、myregistry/myimage:tag などです。 -dと省略可能
- --cache: Kaniko のビルド キャッシュ機能を有効または無効にします。デフォルトでは、キャッシュは有効になっています。
- --cache-ttl: ビルド キャッシュの有効期間を設定します。たとえば、--cache-ttl=10h は、ビルドが完了してから 10 時間キャッシュが有効であることを意味します。
- --cache-repo: ビルド キャッシュを保存するために使用する Docker リポジトリを指定します。デフォルトでは、キャッシュはローカルに保存されます。
- --cache-dir: ビルド キャッシュを保存するためのローカル ディレクトリ パスを指定します。
- --skip-tls-verify: 安全でない Docker リポジトリの場合、TLS 証明書の検証をスキップします。
- --build-arg: Dockerfile 内の ARG 命令にビルド パラメータを渡します。たとえば、--build-arg key=value です。
- --insecure: 信頼されていないレジストリからベースイメージをプルすることを許可します。
- --insecure-registry: 信頼されていないレジストリへの接続を許可します。
- --verbosity: ビルドの詳細度を設定します。パニック、エラー、警告、情報、デバッグ、またはトレースを指定できます。
- --digest-file: ビルドされたイメージのダイジェストを保存するファイルを指定します。
- --oci-layout-path: ビルド プロセスのメタデータを保存するために使用される OCI (Open Container Initiative) レイアウト ファイルへのパスを指定します。
詳細については、公式ウェブサイトをご覧ください:https://github.com/GoogleContainerTools/kaniko#additional-flags Kanikoビルドキャッシュ--cache-copy-layers このパラメータにより、kaniko はコマンドを実行する前にレイヤーのキャッシュをチェックします。存在する場合、kaniko はコマンドを実行する代わりに、キャッシュされたレイヤーをプルして抽出します。そうでない場合、kaniko はコマンドを実行し、新しく作成されたレイヤーをキャッシュにプッシュします。ユーザーは、--cache=true パラメータを設定することでキャッシュを有効にするかどうかを決定でき、--cache-repo フラグを介してキャッシュ レイヤーを保存するためのリモート リポジトリを提供できます。このフラグが指定されていない場合、キャッシュされたリポジトリは指定された --destination から推測されます。通常、--cache=true と --cache-copy-layers=true が一緒に使用されます。 CI/CD での Kaniko の使用Jenkins パイプラインでの使用: 以下は、Kubernetes の動的に生成された Jenkins スレーブ ポッド CI/CD に基づいた、簡略化されたパイプラインの例です。 // 镜像仓库地址def registry = "registry.cn-shanghai.aliyuncs.com/kubesre02/demo" pipeline { agent { kubernetes { yaml """ kind: Pod metadata: name: kaniko spec: containers: - name: kaniko # 使用自定义的kaniko 镜像image: registry.cn-shanghai.aliyuncs.com/kubesre02/kaniko:latest imagePullPolicy: Always command: - cat tty: true """ } } stages { stage('拉代码') { steps { git clone ... } } stage('构建镜像') { steps { // 使用kaniko 来构建镜像container(name: 'kaniko') { Dockerfile 内容... sh "kaniko -f Dockerfile -c ./ -d $registry:$BUILD_NUMBER --force" } } } stage('部署') { steps {部署... } } } } Kaniko は Kubernetes プラットフォーム上でコンテナ イメージを構築するのに非常に適しており、DevOps Jenkins パイプラインに簡単に統合できることがわかります。さて、カニコについては以上です。 |