我已经读过 任何人都可以解释 docker.sock 来理解
/var/run/docker.sock
的作用,但是它在 GitLab CI 的 使用 Docker 套接字绑定 中的使用让我感到困惑。
这是他们用于
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
。
/var/run/docker.sock
。docker
二进制文件docker:19.03.12
。这不是
PATH
冲突吗?我认为应该是其中之一,我可以从主机的 unix 套接字或基本映像中获得使用 docker
的能力。
我认为
--docker-image
应该是 ubuntu:latest
或者类似 docker
不附带的东西,因为 PATH
的 docker
已经来自主机套接字。或者,可以删除 docker 套接字安装。
关于
docker
的双重包含,这里实际发生了什么?
Unix 套接字文件
/var/run/docker.sock
通常由 Docker 守护进程创建。如果您运行其他程序作为主容器进程,则不会创建套接字。你可以直接运行一个非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
的映像,其中 image 有一个 /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 设置似乎相当做作。使用
docker
图像来运行作业意味着构建步骤几乎只能运行 docker
命令。在技术层面上,如果没有 docker
二进制文件并访问正在运行的 Docker 守护进程,则无法启动 docker
容器;该页面顶部描述的 shell 执行器方法似乎更简单,并且实际上没有任何缺点。您还可能会发现拥有构建时依赖项(编译器、头文件、静态检查工具等)的 Docker 映像很方便。这将使您可以更新这些依赖项,而无需对整个构建集群进行更新。如果您的构建脚本本身需要调用 docker
,那么您的构建工具映像需要安装 Docker,只需使用普通的
RUN apt-get install
命令即可。您需要以同样的方式将主机的 Docker 套接字推送到容器中,因此不需要启动单独的 Docker 守护进程。docker-cli
并且
docker daemon
客户端使用 APIS
与 docker 守护进程进行通信。docker.sock
是UNIX套接字,确保docker客户端和守护进程(服务器)之间的连接。
由于 docker 容器与虚拟机不同,没有kernel
,因此在 docker 中运行的每个容器都使用主机的内核,并在主机的内核之上构建容器。 容器本身没有内核,因此除非使用主机的内核,否则您无法在 docker 内构建 docker。
gitlab-runner 有很多执行器:shell
ssh
docker
等等...使用 docker 执行器意味着运行器将创建一个容器,然后将您的存储库克隆到该容器内并运行您传递的脚本,然后销毁该容器。
gitlan-runner 需要一个基础镜像才能创建运行脚本的容器。您不必使用
docker:19.03.12
或挂载
/var/run/docker.sock
卷,除非您的脚本具有 docker 命令(或者通常您需要访问 docker ),并且这两种策略是不同的,您应该知道安装 docker.sock
不是 docker 中的 docker。为了在 docker 中实现 docker,您需要向容器添加 --privileged
标志,这基本上使容器中的 root 成为主机上的完整 root。它可以管理内核参数,它具有所有功能。
这是关于这个主题的一个很好的参考