Docker-in-Docker(DinD)會在容器內執行 Docker daemon。對於必須建置或測試映像的可丟棄 CI 工作,有時使用 DinD 很有幫助,但它會增加特權核心存取權、巢狀儲存空間與快取複雜度。每個會呼叫 docker 的工作都不應預設採用 DinD。
選擇適當的建置模型 #
常見模型有三種:
- DinD: 專用 daemon 在工作網路命名空間中執行。它與主機 daemon 隔離,但通常需要特權模式。
- Docker-outside-of-Docker: 工作掛載主機 Docker socket。這種方式簡單且快速,但任何能使用該 socket 的程序都能控制主機 Docker daemon。
- 無 daemon 建置器: BuildKit、Kaniko、Buildah 或受管理的建置器會建立 OCI 映像,而不暴露通用主機 daemon。
使用能支援建置的最低特權選項。無根 BuildKit 或遠端 BuildKit 建置器可以保留快取效率,而不授予 CI 工作存取 runner Docker socket 的權限。
使用 TLS 執行 DinD 服務 #
官方 docker:dind 映像會啟動 dockerd;它預期與獨立的 Docker CLI 容器或 CI 工作搭配使用。讓 daemon 位於隔離網路中,並對其 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 旗標會授予服務廣泛的主機核心功能。只能在隔離且可丟棄的 runner 上執行。不要暴露未驗證身分的 dockerd TCP 埠:任何能連線到該埠的人都能建立特權容器,通常也能控制其主機。
處理快取與清理 #
DinD 的映像與層快取位於服務容器的 /var/lib/docker。持久化快取磁碟區能加速重複建置,但必須限定在受信任的專案或租戶範圍內;映像層可能包含原始碼與建置密鑰。對共用 CI 基礎架構,優先使用由登錄站支援的 BuildKit 快取。
使用根據不可變提交識別碼建立的唯一標籤,只有測試通過後才推送,並依 runner 的保留政策移除暫存容器與映像。絕不要透過 Dockerfile 的 ARG 或 ENV 傳遞密鑰;改用 BuildKit 密鑰掛載或 CI 系統的密鑰機制。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)