docker executor 与 docker dind 镜像

Rad*_*ad4 7 gitlab-ci

我是 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安装在运行运行程序的主机上。

dind 服务如何解决这个问题

该服务是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 守护进程直接运行。

  • @LeiYang如果 _docker_ 执行器运行一个作业,该作业将始终在容器中运行。如果您希望作业直接在主机上运行,​​则应使用 [_shell_ executor](https://docs.gitlab.com/runner/executors/shell.html) 类型。 (2认同)
  • @LeiYang 跑步者管理员完全决定。项目用户无法更改执行器类型。项目对此唯一的控制方法是(1)在作业中指定“tags:”(但这依赖于预先存在具有指定标签的注册运行器),和/或(2)注册项目锁定专用于该项目的运行器(如果使用未标记的作业,则禁用共享运行器)。 (2认同)