Dockerイメージのビルドにはkanikoを使用します。
GitLab 11.2で導入されました。GitLab Runner 11.2以降が必要です。
kanikoはコンテナやKubernetesクラスタ内でDockerファイルからコンテナイメージをビルドするツールです。
kanikoはDocker-in-Dockerビルドの2つの問題を解決します:
- Docker-in-Dockerを機能させるには特権モードが必要であり、これはセキュリティ上の重大な問題です。
- Docker-in-Dockerは一般的にパフォーマンス・ペナルティが発生し、かなり遅くなる可能性があります。
前提条件
GitLabでkanikoを使用するには、以下のいずれかのExecutorを持つRunnerが必要です:
kanikoを使ったDockerイメージの構築
kanikoとGitLab CI/CDを使ってイメージをビルドする際には、いくつかの重要な点に注意する必要があります:
- kaniko debug イメージを推奨します (
gcr.io/kaniko-project/executor:debug
)。これは Shell があるからで、GitLab CI/CD で使うイメージには Shell が必要です。 - エントリーポイントはオーバーライドする必要があり、そうしないとビルドスクリプトが実行されません。
以下の例では、kanikoを使用しています:
- Dockerイメージをビルドします。
- それをGitLabコンテナレジストリにプッシュします。
ジョブはタグがプッシュされた時だけ実行されます。/kaniko/.docker
、GitLab CI/CDが提供する定義済みのCI/CD変数から必要なGitLabコンテナレジストリの認証情報を取得したconfig.json
ファイルが作成されます。これらはKanikoツールによって自動的に読み込まれます。
最後のステップで、kanikoはプロジェクトのルートディレクトリ下のDockerfile
、Dockerイメージをビルドし、Gitタグを付けながらプロジェクトのコンテナレジストリにプッシュします:
build:
stage: build
image:
name: gcr.io/kaniko-project/executor:v1.14.0-debug
entrypoint: [""]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG
依存プロキシに対して認証を行う場合は、config.json
ファイルに認証に対応する CI/CD 変数を追加する必要があります:
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"},\"$(echo -n $CI_DEPENDENCY_PROXY_SERVER | awk -F[:] '{print $1}')\":{\"auth\":\"$(printf "%s:%s" ${CI_DEPENDENCY_PROXY_USER} "${CI_DEPENDENCY_PROXY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
このコマンドはCI_DEPENDENCY_PROXY_SERVER
から:443
などのポートを取り除きます。
プロキシの背後で kaniko を使って画像を構築する場合
カスタム GitLab Runner を http(s) プロキシの後ろで使う場合は、kaniko もそれに合わせて設定する必要があります。つまり
-
http_proxy
の環境変数をビルドの引数として渡すことで、Dockerfile の指示がイメージのビルド時にプロキシを使えるようにします。
前の例は次のように拡張できます:
build:
stage: build
variables:
http_proxy: <your-proxy>
https_proxy: <your-proxy>
no_proxy: <your-no-proxy>
image:
name: gcr.io/kaniko-project/executor:v1.14.0-debug
entrypoint: [""]
script:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--build-arg http_proxy=$http_proxy
--build-arg https_proxy=$https_proxy
--build-arg no_proxy=$no_proxy
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
rules:
- if: $CI_COMMIT_TAG
マルチアーチ・イメージの構築
コンテナ内部でマルチアーキイメージを構築するには、manifest-tool
を使用します。
multi-arch イメージの構築方法の詳細については、「Building a multi-arch container image in unprivileged containers」を参照してください。
カスタム証明書によるレジストリの使用
カスタムCAによって署名された証明書を使用しているDockerレジストリにプッシュしようとすると、以下のエラーが発生することがあります:
$ /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --no-push
INFO[0000] Downloading base image registry.gitlab.example.com/group/docker-image
error building image: getting stage builder for stage 0: Get https://registry.gitlab.example.com/v2/: x509: certificate signed by unknown authority
これはあなたのCAの証明書をkaniko証明書ストアに追加することで解決できます:
before_script:
- |
echo "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----" >> /kaniko/ssl/certs/ca-certificates.crt
動作例のビデオ・ウォークスルー
TheLeast Privilege Container Builds with Kaniko on GitLabvideo is a walkthrough of theKaniko Docker BuildGuided Exploration project pipeline.テストは
このサンプルは、自分のグループやインスタンスにコピーしてテストすることができます。 他のGitLab CIパターンがどのようにデモされているかの詳細は、プロジェクトページで確認できます。
トラブルシューティング
403エラー:”プッシュ権限のチェックエラー”
このエラーが表示される場合、外部のプロキシが原因である可能性があります。http_proxy
とhttps_proxy
環境変数を設定することで問題を解決できます。
エラー:kaniko should only be run inside of a container, run with the --force flag if you are sure you want to continue
Docker Engine 20.10には既知の非互換性があります。
ホストがDocker Engine 20.10以降を使用している場合、v1.9.0より古いバージョンのgcr.io/kaniko-project/executor:debug
。
イメージをビルドしようとすると、Kanikoは次のように失敗します:
kaniko should only be run inside of a container, run with the --force flag if you are sure you want to continue
このイシューを解決するには、gcr.io/kaniko-project/executor:debug
コンテナを少なくとも v1.9.0 のバージョンに更新してください。例えば、gcr.io/kaniko-project/executor:v1.14.0-debug
.
逆の設定(gcr.io/kaniko-project/executor:v1.14.0-debug
イメージとバージョン 19.06.x またはそれ以前のホスト上の Docker Engine)は問題なく動作します。最良の戦略のためには、ジョブ環境のバージョンを頻繁にテストし、最新のものに更新する必要があります。これにより、新機能やセキュリティの向上がもたらされ、この特定のケースでは、ランナーのホスト上のDocker Engineのアップグレードがジョブに対して透過的になります。