将进程从一个Docker容器附加到另一个Docker容器

将进程从一个Docker容器附加到另一个Docker容器

我试图揭示 CircleCI 功能实现的技术细节,该功能调用多图像

它们允许通过这种方式指定多幅图像:

  test-job:
    docker:
    - image: nginx
    - image: circleci/mariadb:10.2

然后他们根据第一个镜像在 Docker 容器中运行构建(nginx在本例中)。如果你连接到nginx容器,你mysqld也可能会看到那里的进程:

  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
...
    7     0 999      S    2518m   2%  31   0% mysqld
...

看起来他们把一个进程从mariadb容器附加到nginx容器中。

这怎么可能呢?我在 docker 中没有看到这样的功能。

我以为它就像同一个 Kubernetes pod 中的多个容器一样工作,但事实并非如此。您看不到同一个 pod 上一个容器中的其他进程。

有任何想法吗?

答案1

kubernetes pod 的概念最初建立在 docker 之上,利用选项来重用另一个容器的命名空间。默认情况下,docker 中的每个容器都将以其自己的命名空间启动,包括文件系统、pid、网络接口、主机名和用户。但是,对于其中许多,您可以更改命名空间。通常这样做是为了从隔离的容器命名空间切换到使用主机命名空间,例如--net host查看所有主机 NIC 并访问主机上 localhost 上运行的内容。但是,有一个较少使用的选项可以附加到另一个容器的命名空间:

$ docker run -d -p 8888:80 --name web nginx
dcea1ada5d033a1fa7c14a3c2c9ee26d94924b883004dedc3e897389fd4e46cb

$ docker run -it --rm --net container:web --pid container:web nicolaka/netshoot sh

/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process nginx -g daemon off;
    6 101       0:00 nginx: worker process
    7 root      0:00 sh
   12 root      0:00 ps -ef

/ # ss -lntp
State     Recv-Q   Send-Q   Local Address:Port   Peer Address:Port
LISTEN    0        128              0.0.0.0:80           0.0.0.0:*     users:(("nginx",pid=1,fd=6))

/ # curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

/ # 

您可以在示例中看到,我们可以在 localhost 上看到 nginx Web 服务器进程和开放端口,就像主机命名空间中的多个进程可以在主机上互相看到对方一样。更改命名空间使用语法,container:$container其中$container是容器 ID 或容器名称。

答案2

请注意,我没有确切的答案,但我可能有一个猜测 - 它可能使用“Docker-in-Docker”(又名 DIND)。即它以第一个映像为基础启动,然后从第一个映像内部启动所有其余映像。

但请注意,这只是一个猜测,我不知道 CircleCI 是如何实现这一点的。

相关内容