我是 gitlabci 的新手。我想了解为什么我们需要 docker dind 镜像才能在 GitLab CI 作业中构建 docker 镜像。为什么我们不能使用docker执行器,在脚本下运行docker命令呢?
当我们注册 docker executor gitlab runner 时,我们选择一个镜像。再次在 gitlabci 中,我们在image:或services:字段下选择一个镜像。那么这是否意味着这个 GitLab CI 作业容器在 docker 执行器容器内运行?
syt*_*ech 13
为什么我们需要 docker dind 镜像才能在 GitLab CI 作业中构建 docker 镜像。为什么我们不能使用docker执行器,在脚本下运行docker命令呢?
这部分取决于您如何配置 GitLab 运行程序。
docker在容器内不起作用当您调用命令时,它们实际上是在与执行构建和执行其他 docker 命令所需的docker守护进程docker进行通信。通常,在 docker 执行器下运行的作业默认无权访问任何 docker 守护进程。如果您尝试在本地启动的 docker 容器内运行,您会遇到同样的问题。docker
即使我可以docker在我的主机上成功运行:
$ docker run --rm docker /bin/sh -c 'hello from container $HOSTNAME'
hello from container 2b51479b11b1
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
尝试运行任何其他重要的 docker 命令(如 、 等)也会发生相同的build错误run。
一个例外是,如果您将 GitLab 运行程序配置为在特权模式下运行容器并挂载/var/run/docker.sock到所有作业(这是不可取的),在这种情况下,您的所有作业都可以直接与主机上的 docker 守护进程通信。另一个例外可能是,如果您使用shell执行程序,并且您已docker安装在运行运行程序的主机上。
该服务是专docker:dind为您的工作而创建的守护程序。这是非常重要的,因为它可以防止并发作业相互干扰,或者能够在原本无法访问的地方升级访问权限。
当构建开始时,GitLab 运行器将创建两个容器:您的作业容器和容器docker:dind;它们是联系在一起的。当您的作业调用docker命令时,您的作业将连接到docker:dind容器,然后容器执行请求的命令。
由您的作业(例如,通过调用docker run或作为作业的一部分)创建的任何容器均由容器上运行的守护程序(而不是主机守护程序)docker build管理。docker:dind如果您在作业中运行,您会注意到没有列出在主机docker ps守护进程上运行的任何容器,尽管事实上,如果您在主机上运行,您会看到作业容器、dind 容器和任何其他正在运行的容器。容器。docker ps
为了澄清您的其他问题:
当我们注册 docker executor gitlab runner 时,我们选择一个镜像
如果作业未声明任何密钥,则运行程序配置中指定的映像只是要使用的默认image:docker 映像。它不会以任何方式影响跑步者的跑步方式。
在 gitlabci 中,我们在 image: 或 services: fields 下选择一个图像
当 docker 执行器运行你的作业时,它会这样做docker run。键image:决定使用哪个映像来运行您的作业。类似地,services:定义用于服务容器的镜像——服务容器是作业容器的同级容器,并通过链接连接。
那么这是否意味着这个 GitLab CI 作业容器在 docker 执行器容器内运行?
不,我还想澄清一下:运行器/执行器不一定在容器中运行。运行程序可以安装为 Windows 服务,甚至可以简单地安装为直接在系统上运行的进程。您可以使用容器内的运行程序,但这不会对作业的运行方式产生重大影响。
无论如何,运行作业的容器通常总是由主机 docker 守护进程直接运行。