docker-in-docker (dind) 服务在 gitlab ci 中的作用 [英] Role of docker-in-docker (dind) service in gitlab ci
问题描述
根据官方 gitlab 文档,在 ci
管道中启用 docker build
的一种方法是利用 dind
服务(在 gitlab-ci
服务).
According to the official gitlab documentation, one way to enable docker build
within ci
pipelines, is to make use of the dind
service (in terms of gitlab-ci
services).
但是,由于在 docker 执行器上运行 ci 作业总是如此,因此还需要 docker:latest
映像.
However, as it is always the case with ci jobs running on docker executors, the docker:latest
image is also needed.
谁能解释一下:
docker:dind
和docker:latest
镜像有什么区别?- (最重要的是):为什么是两者所需的服务和 docker 映像(例如,如 在这个例子中,链接到 github 文档)执行例如一个 ci 工作的
docker build
?docker:latest
图像(将在其中执行作业!)是否包含 docker 守护进程(我认为docker-compose
还有),哪些是我们需要的命令所必需的工具(例如docker build
、docker push
等)?
- what is the difference between the
docker:dind
and thedocker:latest
images? - (most importantly): why are both the service and the docker image needed (e.g. as indicated in this example, linked to from the github documentation) to perform e.g. a
docker build
whithin a ci job? doesn't thedocker:latest
image (within which the job will be executed!) incorporate the docker daemon (and I think thedocker-compose
also), which are the tools necessary for the commands we need (e.g.docker build
,docker push
etc)?
除非我错了,否则问题或多或少变成:
Unless I am wrong, the question more or less becomes:
为什么 docker 客户端和 docker 守护进程不能驻留在同一个 docker(启用)容器中
Why a docker client and a docker daemon cannot reside in the same docker (enabled) container
推荐答案
docker:dind 和 docker:latest 图片有什么区别?
what is the difference between the docker:dind and the docker:latest images?
docker:latest
包含连接到 docker 守护程序所需的一切,即运行docker build
、docker run
等.它还包含 docker 守护进程,但并未作为入口点启动.docker:dind
基于docker:latest
构建并启动一个 docker 守护进程作为其入口点.docker:latest
contains everything necessary to connect to a docker daemon, i.e., to rundocker build
,docker run
and such. It also contains the docker daemon but it's not started as its entrypoint.docker:dind
builds ondocker:latest
and starts a docker daemon as its entrypoint.
因此,它们的内容几乎相同,但是通过它们的入口点,一个被配置为作为客户端连接到 tcp://docker:2375
,而另一个则用于守护进程.
So, their content is almost the same but through their entrypoints one is configured to connect to tcp://docker:2375
as a client while the other is meant to be used for a daemon.
为什么需要服务和 docker 映像 [...]?
why are both the service and the docker image needed […]?
你不需要两者.您可以使用两者中的任何一个,首先启动 dockerd
,然后像往常一样运行 docker build
和 docker run
命令我做了 这里;显然这是 gitlab 在某些时候中的原始方法.但我发现只编写 service: docker:dind
而不是使用 before_script
来设置 dockerd
更简洁.此外,您不必弄清楚如何开始 &在你的基础镜像中正确安装 dockerd
(如果你没有使用 docker:latest
.)
You don't need both. You can just use either of the two, start dockerd
as a first step, and then run your docker build
and docker run
commands as usual like I did here; apparently this was the original approach in gitlab at some point. But I find it cleaner to just write service: docker:dind
instead of having a before_script
to setup dockerd
. Also you don't have to figure out how to start & install dockerd
properly in your base image (if you are not using docker:latest
.)
在 .gitlab-ci.yml
中声明服务还可以让您轻松换出 docker-in-docker 如果您知道您的运行器正在安装它的 /var/run/docker.sock
到你的图像中.您可以设置 保护变量 DOCKER_HOST
到 unix:///var/run/docker.sock
以获得更快的构建.其他无法访问此类运行器的人仍然可以分叉您的存储库并回退到 dind
服务,而无需修改您的 .gitlab-ci.yml
.
Declaring the service in your .gitlab-ci.yml
also lets you swap out the docker-in-docker easily if you know that your runner is mounting its /var/run/docker.sock
into your image. You can set the protected variable DOCKER_HOST
to unix:///var/run/docker.sock
to get faster builds. Others who don't have access to such a runner can still fork your repository and fallback to the dind
service without modifying your .gitlab-ci.yml
.
这篇关于docker-in-docker (dind) 服务在 gitlab ci 中的作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!