What Is the Pid in the Host, of a Process Running Inside a Docker Container

What is the PID in the host, of a process running inside a Docker container?

You can look at the /proc/<pid>/status file to determine the mapping between the namespace PID and the global PID. For example, if in a docker container I start several sleep 900 processes, like this:

# docker run --rm -it alpine sh
/ # sleep 900 &
/ # sleep 900 &
/ # sleep 900 &

I can see them running in the container:

/ # ps -fe
PID USER TIME COMMAND
1 root 0:00 sh
7 root 0:00 sleep 900
8 root 0:00 sleep 900
9 root 0:00 sleep 900
10 root 0:00 ps -fe

I can look at these on the host:

# ps -fe | grep sleep
root 10394 10366 0 09:11 pts/10 00:00:00 sleep 900
root 10397 10366 0 09:12 pts/10 00:00:00 sleep 900
root 10398 10366 0 09:12 pts/10 00:00:00 sleep 900

And for any one of those, I can look at the status file to see the namespace pid:

# grep -i pid /proc/10394/status
Pid: 10394
PPid: 10366
TracerPid: 0
NSpid: 10394 7

Looking at the NSpid line, I can see that within the PID namespace this process has pid 7. And indeed, if I kill process 10394 on the host:

# kill 10394

Then in the container I see that PID 7 is no longer running:

/ # ps -fe
PID USER TIME COMMAND
1 root 0:00 sh
8 root 0:00 sleep 900
9 root 0:00 sleep 900
11 root 0:00 ps -fe

How to find a process's pid in docker host namespace from inside a container in which it is running

The purpose of this approach was to make sure that only one instance of a process is running at time on a docker host. So the idea is to store the pid of the process at docker host level, so that it can be checked before starting a new instance.
I found another way to do so by using container id. You can do docker ps from inside the container and it will list all the containers running on docker host. Moreover container id does not change with namespace unlike pid. That solves my problem.

docker find container by pid of inside process

Thank you @Alex Past and @Stanislav for the help. But I did not get full answers for me. I combined them.

In summary I has got next.

First

pstree -sg <PID>

where PID is the process's PID from the command top

In output I am getting parent PID for the systemd parent process. This PID is docker container's PID.

After I execute

docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}' | grep "^%PID%"

where %PID% is this parent PID.

In result I have docker's CONTAINER ID.

That's what I wanted

Why do pids jump in a container?

Talked with once of runc's maintainers, Aleksa Sarai, and he explained why this is happening.

By design, the golang runtime spawns several threads to manage a process. runc is written in golang, and when building/execing into the container, there is a short time where the runc process is running inside the container (before execing the user requested executable, e.g. bash in docker exec bash). In Linux, threads and processes are both identified with ids from the same pool, so the go runtime threads are counted in the container pid namespace, leading to the pid jump I described.

How to retrieve docker container name from pid of docker exec on the host (MacOS)

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) |
+------------------------------+


Related Topics



Leave a reply



Submit