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
How to Mount One Partition from an Image File That Contains Multiple Partitions on Linux
Merge Multiple Jpgs into Single PDF in Linux
How to Do Division with Variables in a Linux Shell
Architecture of I386 Input File Is Incompatible with I386:X86-64
Magic Numbers of the Linux Reboot() System Call
How to Get My Golang Web Server to Run in the Background
Number of Processors/Cores in Command Line
Must My Pidfile Be Located in /Var/Run
How to Convert a PDF into Jpg with Command Line in Linux
How to Include a Pipe | in My Linux Find -Exec Command
Get Filesystem Mount Point in Kernel Module
How to Use Grep to Match But Without Printing the Matches
Is Kernel Space Mapped into User Space on Linux X86
Deleting String Up to the First Occurrence of Certain Character