我是gitlabci的新手。我想了解为什么在GitLab CI作业中构建Docker镜像需要使用docker dind镜像,为什么不能在脚本下使用docker executor并运行docker命令?
当我们注册docker executor gitlab runner时,我们选择一个镜像。再次在gitlabci中,在image:
或services:
字段下选择一个镜像。这是否意味着该GitLab CI作业容器在docker executor容器内运行?
我是gitlabci的新手。我想了解为什么在GitLab CI作业中构建Docker镜像需要使用docker dind镜像,为什么不能在脚本下使用docker executor并运行docker命令?
当我们注册docker executor gitlab runner时,我们选择一个镜像。再次在gitlabci中,在image:
或services:
字段下选择一个镜像。这是否意味着该GitLab CI作业容器在docker executor容器内运行?
为什么在GitLab CI作业中构建Docker镜像需要使用Docker DIND镜像?为什么不能使用Docker执行程序并在脚本下运行Docker命令?
这部分取决于您如何配置GitLab Runner。
docker
当您调用docker
命令时,它们实际上是在和一个Docker 守护进程交互,该守护进程需要执行构建和执行其他docker命令。通常,在Docker执行程序下运行的作业默认情况下没有访问任何Docker守护进程。这与您尝试在本地启动的Docker容器内运行docker
时遇到的问题相同。
即使我可以在主机上成功运行docker
:
$ docker run --rm docker /bin/sh -c 'hello from container $HOSTNAME'
hello from container 2b51479b11b1
我无法在容器内运行 docker
$ docker run --rm docker /bin/sh -c 'docker info'
errors pretty printing info
Client:
Context: default
Debug Mode: false
Server:
ERROR: error during connect: Get "http://docker:2375/v1.24/info": dial tcp: lookup docker on 192.168.65.5:53: no such host
尝试运行任何其他重要的Docker命令(例如build
,run
等)将导致相同的错误。
唯一的例外是,如果您将GitLab runner配置为在特权模式下运行容器并将/var/run/docker.sock
挂载到所有作业中(这不是建议),则所有作业都可以直接与主机上的Docker守护程序通信。另一个例外可能是,如果您使用shell
执行程序,并且在运行runner的主机上安装了docker
,则也可能出现此情况。
docker:dind
服务是仅为您的作业创建的守护程序。这非常重要,因为它可以防止并发作业互相干扰或能够升级访问权限。
当构建开始时,GitLab runner将创建两个容器:作业容器和docker:dind
容器; 它们链接在一起。当您的作业调用docker
命令时,您的作业连接到docker:dind
容器,后者执行所请求的命令。
由您的作业创建的任何容器(例如,通过作业的docker run
或docker build
调用)由运行在docker:dind
容器上的守护程序管理,而不是主机守护程序。如果在作业内部运行docker ps
,您将注意到没有在主机上运行的容器。此时,尽管如果您在主机上运行docker ps
,您将看到作业容器、dind容器和任何其他正在运行的容器。
为了澄清您的其他问题:
当我们注册具有Docker执行程序的GitLab runner时,我们选择一个映像
在您的runner配置中指定的镜像仅是要使用的默认Docker镜像,如果作业未声明任何image:
键,则使用该镜像。它不会以任何方式影响runner的运行。
在gitlabci中,我们在image:或services:字段下选择一个映像
当Docker执行程序运行作业时,它使用docker run
来运行作业。 image:
键确定要用于运行作业的镜像。类似地,services:
定义用于服务容器的镜像——服务容器是作业容器的同级,并且与links连接。
那是否意味着这个GitLab CI作业容器在docker执行程序容器内运行?
不是。我还想澄清:runner / executor并不一定在容器中运行。Runner可以安装为Windows服务,或者甚至直接在系统上运行的进程。您可以使用恰好位于容器内的runner,但它不会实质性地影响作业如何运行。
无论如何,运行作业的容器通常始终由主机Docker守护程序直接运行。
dind
,对吗?我认为在大多数情况下,建议Runner在Docker中运行,以实现隔离等功能?我是日常用户,但从未担任过GitLab CI管理员。 - Lei Yanggitlab-ci.yml
中指定? - Lei Yang