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

根据官方的 Gitlab 文档,在 ci管道中启用 docker build的一种方法是利用 dind服务(就 gitlab-ci 服务而言)。

但是,由于 ci 作业总是在 docker 执行器上运行,因此还需要 docker:latest映像。

谁能解释一下:

  • docker:dinddocker:latest图像的区别是什么?
  • (最重要的) : 为什么都有所需的服务和码头映像(例如,如指示的 在这个例子中,从 github 文档链接)执行,例如在 ci 作业中执行 docker build?不是 docker:latest图像(作业将在其中执行!)合并 docker 守护进程(我认为还包括 docker-compose) ,它们是我们需要的命令所必需的工具(例如 docker builddocker push等等) ?

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

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

30327 次浏览

The container will contain only things defined in a docker image. You know you can install anything, starting from a base image. But you can also install Docker (deamon and client) in a container, that is to say a Docker IN Docker (dind). So the container will be able to run other containers. That's why gitlab need this.

what is the difference between the docker:dind and the docker:latest images?

  • docker:latest contains everything necessary to connect to a docker daemon, i.e., to run docker build, docker run and such. It also contains the docker daemon but it's not started as its entrypoint.
  • docker:dind builds on docker:latest and starts a docker daemon as its entrypoint.

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.

why are both the service and the docker image needed […]?

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 services: 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.)

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.