Docker-in-Docker

最終更新: 2022-09-14 14:25:00 +0800 +0800
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

Docker-in-Docker(DinD)はコンテナ内で Docker デーモンを実行します。イメージをビルドまたはテストする使い捨て CI ジョブには有用な場合がありますが、 特権カーネルアクセス、入れ子になったストレージ、キャッシュの複雑さが加わります。docker を呼び出すすべてのジョブで既定の選択にすべきではありません。

適切なビルドモデルの選択 #

一般的なモデルは 3 つあります。

  1. DinD: 専用デーモンがジョブのネットワーク名前空間で動作します。ホストデーモンから分離できますが、通常は特権モードが必要です。
  2. Docker-outside-of-Docker: ジョブがホストの Docker ソケットをマウントします。単純で高速ですが、ソケットを使えるプロセスはホストの Docker デーモンを制御できます。
  3. デーモンレスビルダー: BuildKit、Kaniko、Buildah、またはマネージドビルダーが、汎用ホストデーモンを公開せずに OCI イメージを作成します。

ビルドを支えられる中で最小権限の選択肢を使います。rootless BuildKit またはリモート BuildKit ビルダーなら、 CI ジョブにランナーの Docker ソケットへのアクセスを与えず、キャッシュ効率を維持できます。

TLS 付き DinD サービスの実行 #

公式の docker:dind イメージは dockerd を起動し、独立した Docker CLI コンテナまたは CI ジョブと組み合わせて使うことを想定しています。 デーモンを隔離ネットワークに置き、TCP リスナーには TLS を使います。

sh
docker network create ci-build
docker volume create dind-certs

docker run -d --name dind --privileged --network ci-build \
  -e DOCKER_TLS_CERTDIR=/certs \
  -v dind-certs:/certs/client \
  docker:27-dind

docker run --rm --network ci-build \
  -e DOCKER_HOST=tcp://dind:2376 \
  -e DOCKER_TLS_VERIFY=1 \
  -e DOCKER_CERT_PATH=/certs/client \
  -v dind-certs:/certs/client:ro \
  docker:27-cli version

--privileged フラグはサービスにホストカーネルの広範な機能を与えます。隔離された使い捨てランナーでのみ実行してください。 認証されていない dockerd の TCP ポートを公開してはいけません。到達できる人は特権コンテナを作成でき、通常はホストを制御できます。

キャッシュとクリーンアップの扱い #

DinD のイメージとレイヤーのキャッシュはサービスコンテナの /var/lib/docker にあります。 永続キャッシュボリュームは繰り返しビルドを高速化しますが、信頼できるプロジェクトまたはテナントに限定してください。 イメージレイヤーにはソースコードやビルドシークレットが含まれる可能性があります。共有 CI 基盤ではレジストリ対応の BuildKit キャッシュを優先します。

不変のコミット識別子に基づく一意のタグを使い、テスト合格後だけプッシュし、ランナーの保持ポリシーに従って一時コンテナとイメージを削除します。 Dockerfile の ARG や ENV でシークレットを渡してはいけません。代わりに BuildKit のシークレットマウントまたは CI システムのシークレット機構を使います。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)