在一个 Docker 容器中运行着几个进程,它们的 PID 被隔离在容器命名空间中,有没有办法找出它们在 Docker 主机上的 PID 是什么?
例如,有一个 Apache Web 服务器在 Docker 容器中运行,
(我使用来自 Docker Hub 的 Apache+PHP 镜像),Apache 在启动时会在容器内创建更多工作进程。这些工作进程实际上正在处理传入的请求。要查看这些进程,我在 docker 容器中运行 pstree
:
# pstree -p 1
apache2(1)-+-apache2(8)
|-apache2(9)
|-apache2(10)
|-apache2(11)
|-apache2(12)
`-apache2(20)
父 Apache 进程在容器进程命名空间内的 PID 1 上运行。但是从主机的角度来看,它也可以访问,
但是它在宿主机上的PID不同,可以通过运行docker compose
命令来确定:
$ docker inspect --format '{{.State.Pid}}' container
17985
由此我们可以看到,容器进程命名空间中的 PID 1 映射到主机上的 PID 17985。所以我可以在主机上运行 pstree
,列出 Apache 进程的子进程:
$ pstree -p 17985
apache2(17985)─┬─apache2(18010)
├─apache2(18011)
├─apache2(18012)
├─apache2(18013)
├─apache2(18014)
└─apache2(18164)
据此,我假设容器中的 PID 1 映射到主机上的 PID 17985 的方式相同,它也映射:
- 容器中的 PID 8 到主机上的 PID 18010,并且
- PID 9 到 PID 18011;
- PID 10 到 PID 18012 等等……
(这允许我从 docker 容器中调试进程,使用仅在主机上可用的工具,而不是在容器中可用的工具,如 strace)
问题是我不知道假设 pstree 在容器和主机中以相同的顺序列出进程有多安全。
如果有人能提出一种更可靠的方法来检测在 Docker 容器内运行的特定进程的主机上的 PID 是什么,那就太好了。
最佳答案
您可以查看/proc/<pid>/status
文件来确定命名空间 PID 和全局 PID 之间的映射。例如,如果在一个 docker 容器中我启动了几个 sleep 900
流程,如下所示:
# docker run --rm -it alpine sh
/ # sleep 900 &
/ # sleep 900 &
/ # sleep 900 &
我可以看到它们在容器中运行:
/ # 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
我可以在主机上查看这些:
# 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
对于其中任何一个,我可以查看 status
文件以查看命名空间 pid:
# grep -i pid /proc/10394/status
Pid: 10394
PPid: 10366
TracerPid: 0
NSpid: 10394 7
看NSpid
行,我可以看到在 PID 命名空间内,这个进程的 pid 为 7。事实上,如果我杀死进程 10394
在主机上:
# kill 10394
然后在容器中我看到 PID 7 不再运行:
/ # 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
关于linux - 在 Docker 容器中运行的进程的主机中的 PID 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39931316/