1

下面是从这里获取的詹金斯图像的代码片段:

# 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 引擎。我的理解是var/run/docker.sock,由于安装了 docker 引擎,它是使用 Jenkins 容器创建的。


下面是从这里获取的卷映射语法

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

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

EC2 主机还运行着 docker 守护进程。

因此,在 EC2 主机中运行了 docker 守护进程。还有一个在 docker 容器(Jenkins)中运行的 docker 守护进程


/var/run/docker.sock:/var/run/docker.sock使用docker-compose(above) 中的这个语法( ) 处理套接字文件,

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

4

2 回答 2

2

/var/run/docker.sock容器中是主机的 Docker 套接字,仅此而已。这是因为:

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

因此,在您描述的场景中,它只能是主机 Docker 套接字,因为没有第二个 Docker 守护程序。


假设您实际上是在以这种方式启动第二个守护进程。

这里的操作顺序是(1)Docker建立容器文件系统,(2)Docker开始运行入口点,(3)入口点启动守护进程,(4)守护进程尝试创建socket文件。在守护进程启动时,它的套接字文件已经存在。我相信这会导致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或以其他方式指向此特定文件。

于 2019-11-02T10:10:29.403 回答
1

文档

Docker-engine 是一个客户端-服务器应用程序

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

这意味着如果 docker 守护程序没有运行,您仍然可以运行 docker cli 命令:

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

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

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

因此,在容器内运行的 docker cli 命令控制在 docker 主机上运行的 docker-engine。

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

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

于 2019-11-02T11:05:32.137 回答