Docker - 套接字文件的卷映射是否为覆盖行为?

Docker - Is volume mapping of socket file an override behavior?

下面是从 here:

中截取的 jenkins 图像的代码片段
# Install Docker Engine
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D && \
    echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | tee /etc/apt/sources.list.d/docker.list && \
    apt-get update -y && \
    apt-get purge lxc-docker* -y && \
    apt-get install docker-engine=${DOCKER_ENGINE:-1.10.2}-0~trusty -y && \
    usermod -aG docker jenkins && \
    usermod -aG users jenkins

在 jenkins 映像中安装 docker 引擎。我的理解是,由于安装了 docker 引擎,var/run/docker.sock 是使用 Jenkins 容器创建的。


下面是 卷映射语法 摘自 here:

volumes:
  - jenkins_home:/var/jenkins_home
  - /var/run/docker.sock:/var/run/docker.sock

在 EC2 主机上启动 jenkins 容器(上图)。

EC2 主机也有 docker 守护进程 运行。

因此,EC2 主机中有 docker 守护程序 运行。 docker container(Jenkins)

中还有一个 docker 守护进程 运行

在 docker-compose(以上)套接字文件中使用此语法(/var/run/docker.sock:/var/run/docker.sock),

Jenkins 容器中的 docker 守护进程是否使用 EC2 主机中存在的套接字文件覆盖其自身的套接字文件?如果是...它的含义是什么?

容器中的

/var/run/docker.sock 是主机的 Docker 套接字,除此之外别无他物。这是因为:

  1. Docker 容器不会 运行 除了在其入口点 and/or 命令中明确启动的程序之外的任何程序,而且几乎总是只有一个应用程序。
  2. 您可能不会特意启动 Docker 守护进程,因此它已安装但未 运行ning。
  3. Unix 套接字文件只有在守护程序启动后才会创建,并且它绑定(2) 套接字到特定文件。
  4. docker run -v 选项总是 "push" 主机的内容到容器中,这发生在任何容器进程之前 运行。

所以在您描述的场景中,它不能是主机 Docker 套接字以外的任何东西,因为没有第二个 Docker 守护进程。


为了争论起见,假设您实际上正在以这种方式启动第二个守护进程。

这里的操作顺序是 (1) Docker 设置容器文件系统,(2) Docker 启动 运行ning 入口点,(3) 入口点启动守护进程,(4) 守护进程尝试创建套接字文件。在守护进程启动时,它的套接字文件已经存在。我相信这会导致 bind(2) 调用失败并显示 EADDRINUSE,并且守护进程不会启动。希望这会导致您的容器启动失败。

你可能想在容器中启动一个守护进程,它发布一个你想从主机访问的 Unix 套接字。要完成这项工作,您需要将一个目录挂载到容器中,并将守护进程指向它。它可能不能在任何一侧 /var/run (主机 /var/run 中有很多东西;安装目录会隐藏容器中的现有内容,您可能需要容器的 /var/run也)。它必须是目录而不是套接字文件名,因为 Docker 如果它不存在将创建一个空目录; 某些东西 将存在于该路径的容器中,绑定将失败。

因此,如果您想在容器内启动一个假设的 foo 守护进程,它大致如下所示

docker run \
  --name foo \                   # container name
  -v $PWD/socket:/socket \       # bind mount a directory
  foo \                          # image name
  food \                         # command to run in the container
    --foreground \               # don't daemonize; keep the container alive
    --bind fd://socket/foo.sock  # put the socket in the shared directory

在主机上,您需要设置 FOO_SOCKET_PATH=$PWD/socket/foo.sock 或指向此特定文件。

来自docs

Docker-engine is a client-server application

请注意,当您安装 docker-engine 时,您会安装 docker-daemon(服务器)和 docker cli(客户端)。

这意味着如果 docker 守护进程不是 运行ning 你仍然可以 运行 docker cli 命令:

docker info
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

您共享的 Jenkins 映像没有 运行 docker 引擎的说明。所以我假设它不在容器内 运行ning。

/var/run/docker.sock:/var/run/docker.sock 卷映射 docker 主机的 docker 引擎套接字到容器。

所以容器中的 docker cli 命令 运行 控制 docker 引擎 运行 在 docker 主机上运行。

如果您从容器化的 Jenkins 中在您的主机上执行 CI/CD,这是有道理的。

Jenkins 管道可以使用 docker、docker-compose 和 docker swarm 命令来 运行 测试、构建工件和部署新版本的应用程序。