在 Docker 场景中的 Docker 中安装 `/var/run/docker.sock` 的结果是什么?

What is the result of mounting `/var/run/docker.sock` in a Docker in Docker scenario?

我读过 Can anyone explain docker.sock to understand what /var/run/docker.sock does, but its use in GitLab CI's Use Docker socket binding 让我感到困惑。

这是他们用于 gitlab-runner 注册的示例命令:

sudo gitlab-runner register -n \
  --url https://gitlab.com/ \
  --registration-token REGISTRATION_TOKEN \
  --executor docker \
  --description "My Docker Runner" \
  --docker-image "docker:19.03.12" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

我看到生成的容器可以从两个地方获得 docker

  1. unix套接字/var/run/docker.sock.
  2. 基本映像 docker:19.03.12 中包含的 docker 二进制文件。

这不是PATH冲突吗?我认为它应该是其中之一,我可以从主机的 unix 套接字或基本映像中获得使用 docker 的能力。

我认为 --docker-image 应该改为 ubuntu:latest 或者 docker 中没有的那些,因为 PATHdocker 已经来自主机套接字。或者,docker 套接字支架将被移除。

关于 docker 的双重包含,这里实际发生了什么?

Unix 套接字文件/var/run/docker.sock 通常由Docker 守护程序创建。如果您 运行 其他东西作为主容器进程,则不会创建套接字。你可以通过 运行ning 一个非 Docker 主进程的容器直接查看,比如 /bin/ls:

docker run --rm docker:19.03.12 ls -l /var/run
docker run --rm docker:19.03.12 ls -l /run

/usr/bin/docker 二进制文件必须存在于容器文件系统中,如果您要使用它的话。容器永远不能调用主机上的二进制文件,套接字 API 也不会生成二进制文件。 (一些非常早期的“使用主机的 Docker 套接字”帖子提倡将二进制文件绑定安装到容器中,但这会导致库依赖性出现问题并使图像无法自包含。)

因此,如果您真正需要的只是一个 Docker 容器,带有 docker 二进制文件,可以调用主机的 Docker 套接字,您需要一个像 docker 其中 图像 有一个 /usr/bin/docker,另外你需要将主机的 /var/run/docker.sock 绑定挂载到容器中。

docker run \
  --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  docker:19.03.12 \
  docker ps

GitLab 设置您 link 似乎相当做作。将 docker 图像用于 运行 作业意味着几乎 只有 构建步骤可以 运行 的东西是 docker 命令。在技​​术层面上,如果没有 docker 二进制文件和访问 运行ning Docker 守护进程,则无法启动 docker 容器;该页面顶部描述的 shell-executor 方法似乎更简单,而且实际上没有任何缺点。

您可能还会发现拥有构建时依赖项(编译器、头文件、静态检查工具...)的 Docker 图像很方便。这样一来,您就可以更新这些依赖项,而无需对整个构建集群进行更新。如果您的构建脚本本身需要调用 docker,那么您的构建工具映像需要安装 Docker,只需使用普通的 RUN apt-get install 命令即可。您需要以相同的方式将主机的 Docker 套接字推送到容器中,因此您不需要启动单独的 Docker 守护进程。

首先您需要了解 docker 的工作原理才能理解此流程 docker 有服务器和客户端 docker-clidocker daemon 客户端使用 APIS.

与 docker 守护程序通信

docker.sock 是确保 docker 客户端和守护程序(服务器)之间连接的 UNIX 套接字。

因为 docker 容器不像虚拟机没有 kernel docker 中的每个容器 运行 使用主机的内核并在顶部构建容器主机内核。 容器本身没有内核,因此除非使用主机的内核,否则无法在 docker 中构建 docker。

gitlab-运行ner 有很多执行器:shell ssh docker 等...

使用 docker 执行器意味着 运行ner 将创建一个容器,然后将你的 repo 克隆到这个容器中,运行 你传递的脚本然后销毁这个容器。

gitlan-运行ner 需要一个基础镜像来创建将 运行 脚本的容器。你不必使用 docker:19.03.12 或挂载 /var/run/docker.sock 卷,除非你的脚本有 docker 命令(或者通常你需要访问 docker )并且两者策略不同你应该知道安装 docker.sock 不是 docker in docker.

为了在 docker 中实现 docker,您需要将 --privileged 标志添加到容器中,这基本上使容器中的根目录成为主机上的完全根目录。它可以管理内核参数,它具有所有功能。

这里有一篇关于这个主题的好文章reference