docker-in-docker (dind) 服务在 gitlab ci 中的作用

Posted

技术标签:

【中文标题】docker-in-docker (dind) 服务在 gitlab ci 中的作用【英文标题】:Role of docker-in-docker (dind) service in gitlab ci 【发布时间】:2018-04-27 02:45:10 【问题描述】:

根据官方gitlab documentation,在ci管道中启用docker build的一种方法是使用dind服务(在gitlab-ciservices方面)。

但是,与在 docker 执行器上运行的 ci 作业一样,docker:latest 映像也是必需的。

谁能解释一下:

docker:dinddocker:latest 图像有什么区别? (最重要的是):为什么both服务和需要的docker镜像(例如,如in this example所示,链接自github文档)执行例如一个docker build 有一个ci 工作吗? docker:latest 图像(将在其中执行作业!)是否包含 docker 守护进程(我认为 docker-compose 也是),这是我们需要的命令所必需的工具(例如docker builddocker push 等)?

除非我错了,否则问题或多或少变成:

为什么 docker 客户端和 docker 守护进程不能驻留在同一个 docker(启用)容器中

【问题讨论】:

【参考方案1】:

docker:dind 和 docker:latest 图片有什么区别?

docker:latest 包含连接到 docker 守护进程所需的一切,即运行 docker builddocker run 等。它还包含 docker 守护进程,但并未作为入口点启动。 docker:dind 建立在 docker:latest 之上,并启动一个 docker 守护进程作为其入口点。

因此,它们的内容几乎相同,但通过它们的入口点,一个被配置为作为客户端连接到tcp://docker:2375,而另一个被用于守护进程。

为什么需要服务和 docker 映像 [...]?

你不需要两者。您可以使用两者中的任何一个,首先启动dockerd,然后像我做here 一样像往常一样运行docker builddocker run 命令;显然这是 gitlab at some point 中的原始方法。但我发现只写service: docker:dind 而不是用before_script 来设置dockerd 更简洁。此外,您不必弄清楚如何在基本映像中正确启动和安装dockerd(如果您不使用docker:latest。)

如果您知道您的跑步者正在将其/var/run/docker.sock 安装到您的映像中,那么在您的.gitlab-ci.yml 中声明该服务还可以让您轻松地更换 docker-in-docker。您可以将 protected variable DOCKER_HOST 设置为 unix:///var/run/docker.sock 以获得更快的构建。其他无法访问此类运行程序的人仍然可以分叉您的存储库并回退到 dind 服务,而无需修改您的 .gitlab-ci.yml

【讨论】:

添加到@saraedum 的帖子,如果我没记错的话,如果你指定DOCKER_HOST var 是服务所期望的,我认为是DOCKER_HOST: "tcp://$DOCKER_REGISTRY__library__docker:2375"(你这样做not 将其挂载到主机的套接字上),这将 禁用 docker 层缓存(只是关于使用与不使用服务的实际差异的旁注) 感谢您的精彩解释!一个后续问题,如果唯一的区别是docker:dind已经启动了docker daemon作为入口点,为什么我们不能直接使用docker:dind作为镜像呢?是不是因为在docker:dind中,也被配置为连接到tcp://docker:2375而不是tcp://localhost:2375【参考方案2】:

容器将仅包含 docker 映像中定义的内容。你知道你可以安装任何东西,从基础镜像开始。 但是你也可以在一个容器中安装Docker(deamon和client),也就是说一个Docker IN Docker(dind)。所以容器将能够运行其他容器。这就是为什么 gitlab 需要这个。

【讨论】:

是的,但是 dind 容器与 docker:latest 容器有什么关系?它在里面运行吗? gitlab 的唯一解释是服务可用于启动和链接辅助容器,例如数据库。我没有看到仅仅拥有一个可用和链接的 dind 容器会如何改变任何事情。 是的 docker 安装在 dind 镜像中。你到底是什么问题?

以上是关于docker-in-docker (dind) 服务在 gitlab ci 中的作用的主要内容,如果未能解决你的问题,请参考以下文章

Docker-in-Docker: Jenkins CI 内部如何运行 docker

Docker 容器网络与 Docker-in-Docker

无需 Docker-in-Docker 的私有 Gitlab Runner 代码质量

从 GitLab CI 运行器连接到 docker-in-docker

docker-dind

在Docker容器中操作Docker (dind)