3

I'm trying to reveal technical detail of CircleCI feature implementation which calls Multi-Image.

They allow specifying multiple images this way:

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

Then they run build in the Docker container based on the first image (nginx in this case). And if you connect to nginx container you may see mysqld process there too:

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

It seems like they attach a process from the mariadb container to the nginx container.

How it even possible? I do not see such ability in docker.

I thought it works like multiple containers in the same Kubernetes pod but it is not. You do not see processes in one container from others on the same pod.

Any ideas?

2 Answers 2

7
+50

The concept of a kubernetes pod is originally built on top of docker leveraging options to reuse the namespaces of another container. By default, each container in docker will start with it's own namespaces for the filesystem, pids, network interfaces, hostname, and users. However, for many of these you can change the namespace. Often this is done to switch from the isolated container namespace to use the host namespace, e.g. --net host to see all of the host NIC's and access things running on localhost on the host. However, there's a less used option to attach to the namespaces of another container:

$ 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>

/ # 

You can see in that example that we can see the nginx web server process and open port on localhost, just like multiple processes in the host namespace can each see each other on the host. Changing the namespace uses the container:$container syntax where $container is either the container id or container name.

1
  • Works like a charm for me. Thank you BMitch, you are awesome! Jun 10, 2020 at 6:38
0

Note that I do not have an exact answer, but I may have a guess - it may be using "Docker-in-Docker" (aka DIND). I.e. it starts the first image as a base one, and then it starts all the rest from inside the first image.

But please note that this is merely a guess and I have no ideas how CircleCI implemented this.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .