背景:
在編寫(xiě) CI 時(shí)通過(guò)聲明鏡像作為 job 的執(zhí)行環(huán)境,每個(gè) job 都在一個(gè)純凈的容器中執(zhí)行。
有時(shí),我們需要一個(gè) docker 容器環(huán)境來(lái)執(zhí)行 docker build、docker push 等操作。查看官方的 docker 鏡像,我們發(fā)現(xiàn)存在兩個(gè)主要的版本:docker:latest、docker:dind 和 docker:git。
(推薦教程:docker教程)
docker:dind
該鏡像包含 Docker 客戶(hù)端(命令行工具)和 Docker daemon。
通過(guò) docker history docker:dind 命令我們發(fā)現(xiàn) docker:dind 是在 docker:latest 基礎(chǔ)上又安裝了 Docker daemon,并且最后兩個(gè)構(gòu)建命令為:
IMAGE CREATED CREATED BY SIZE COMMENT 66dc2d45749a 8 weeks ago /bin/sh -c #(nop) CMD [] 0B <missing> 8 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["dockerd-entr… 0B ...
在 run 該鏡像時(shí),不能指定 sh CMD 參數(shù),dockerd-entrypoint.sh 命令接收到該參數(shù)并不會(huì)啟動(dòng) Docker daemon。想要正確啟動(dòng)容器里的 Docker daemon 并且進(jìn)入容器需要分步進(jìn)行:
$ docker run -d --name dind --privileged docker:dind # 啟動(dòng)容器 $ docker logs -f dind # 查看啟動(dòng)日志 $ docker exec -it dind sh # 進(jìn)入容器
啟動(dòng) docker:dind 容器時(shí),參數(shù) –privileged 必須加上,否則 Docker daemon 啟動(dòng)時(shí)會(huì)報(bào)錯(cuò)。
docker:latest
該鏡像只包含 Docker 客戶(hù)端,需要有 Docker daemon 支持,可以使用 docker:dind 的,也可以?huà)燧d宿主機(jī)的 /var/run/docker.sock。
該鏡像啟動(dòng)不需要 –privileged 參數(shù)。
通過(guò) docker history docker:latest 命令發(fā)現(xiàn) CMD 默認(rèn)為 sh:
81f5749c9058 3 months ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 3 months ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B ...
啟動(dòng)方式一:掛載宿主機(jī) sock 文件
$ docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock docker:latest
啟動(dòng)方式二:配合 docker:dind
將 docker:dind 和 docker:latest 放入相同網(wǎng)絡(luò),并且指定 dind 容器在該網(wǎng)絡(luò)中的別名為 docker,因?yàn)?latest 容器中默認(rèn)設(shè)定的 daemon host 就叫 docker。
另外需要注意 證書(shū) 問(wèn)題,新版本 Docker 客戶(hù)端與 Docker daemon 通訊需要 TLS 證書(shū)保證通訊安全,docker:dind 容器會(huì)生成證書(shū)到環(huán)境變量 DOCKER_TLS_CERTDIR 指定的目錄,需將證書(shū)掛載并提供給 docker:latest 容器使用。
$ docker run --privileged --name some-docker -d --network some-network --network-alias docker -e DOCKER_TLS_CERTDIR=/certs -v some-docker-certs-ca:/certs/ca -v some-docker-certs-client:/certs/client docker:dind $ docker run --rm --network some-network -e DOCKER_TLS_CERTDIR=/certs -v some-docker-certs-client:/certs/client:ro docker:latest
docker:git
docker:git 是包含了 git 命令的 docker:latest,方便 CI 時(shí)使用 Git。