1

I'm trying to find out the name of a docker container given the pid of the docker exec command on the host. host system is MacOS (Catalina, but that shouldn't matter). This information is available in a script I am writing, but it's the starting point, just as if you would do

localhost $ ps ax | grep docker | grep what-i-am-looking.for
 8968 ... docker exec [args...] [optional command]

If I inspect the running containers, the pid is not listed there.

 localhost $ docker ps -q | xargs docker inspect | grep 8968
 # nothing, so the PID is not stored

There's a different PID however

 localhost $ docker ps -q | xargs docker inspect '{{.State.Pid}}'
 31093
 6836

which has nothing to do with anything running on the host, nor inside docker (pids don't exist).

I can retrieve the Exec-IDs of running containers by

docker ps -q | xargs docker inspect -f '{{.ExecIDs}}'

or a bit more handy to work with

docker ps -q | xargs docker inspect | jq -r '.[0].ExecIDs[] | .'

and get some info about this via

curl --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://docker/exec/$EXEC_ID/json

There's also a PID listed (a different one, like 31166), but this number has again nothing to do with the host.

Any idea how to find out which container the command on the host belongs to?

The alternative is to parse the docker exec / run command string, but due to the variety of arguments possible and optional commands that may be given I don't think it's a good idea. For that I could check each word in the command string against the name found in one of the docker inspect calls, but I think it's too brittle.

BTW: CoreOS - get docker container name by PID? doesn't help since PIDs are different (see text( and there's no /proc on in MacOS.

Karsten S.
  • 2,349
  • 16
  • 32

1 Answers1

4

The approach you're taking won't work on MacOS. Parsing the docker exec command to find the first non-option argument is probably the only way to find this.

On MacOS, there is a hidden Linux VM that actually runs the containers. This means there are three process ID namespaces (the host's, the VM's, and the container's). The other important distinction is that the docker exec process isn't the same process as the process that's running inside the container. So you're trying to match the MacOS host pid of the docker exec process against the Linux VM pid of the main container process, and they'll never match up.

You can get a shell inside the Linux VM (see for example this answer) and then the docker inspect pids will be visible. But now, because of Docker's client-server architecture, there is no docker exec process; it only exists on the MacOS host. You should be able to see the process it launches but it's hard to know that process comes from docker exec.

                   +------------------------------+
                   |             ................ |
docker exec ... ------> dockerd ---> process    : |
(host pid)         |   (VM pid)  :  (cont. pid) : |
                   |             ................ |
                   | Linux VM        (VM pid)     |
                   +------------------------------+
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thanks for the well done explanation. I was trying to figure out how to reach out to the VM, but as you stated there won't be any possibility to really match with the host pid. I did a greedy approach now matching all the arguments in the command line with any running docker container name and pick the one that fits first. Not perfect, but I think easier than trying to parse with optional and variable length command arguments. – Karsten S. Aug 11 '20 at 07:20