在主机中,在Docker容器内运行的进程的PID是什么?

有几个进程在Docker容器中运行,它们的PID在容器名称空间中是隔离的,有没有办法找出Docker主机上的PID是什么?

例如,在Docker容器中运行Apache Web服务器(我使用Docker Hub的 Apache + PHP镜像),而Apache在启动时在容器内创build更多的工作进程。 这些工作进程实际上是处理传入的请求。 要查看这些进程,我在Docker容器中运行pstree

 # pstree -p 1 apache2(1)-+-apache2(8) |-apache2(9) |-apache2(10) |-apache2(11) |-apache2(12) `-apache2(20) 

父级Apache进程在容器进程名称空间内的PID 1上运行。 但是从主机的angular度来看,也可以访问它,但是主机上的PID是不同的,可以通过运行docker compose命令来确定:

  $ docker inspect --format '{{.State.Pid}}' container 17985 

从这里我们可以看到容器进程名字空间中的PID 1映射到主机上的PID 17985。 所以我可以在主机上运行pstree来列出Apache进程的subprocess:

 $ pstree -p 17985 apache2(17985)─┬─apache2(18010) ├─apache2(18011) ├─apache2(18012) ├─apache2(18013) ├─apache2(18014) └─apache2(18164) 

从这个angular度来看,我们假设容器中的PID 1如何映射到主机上的PID 17985,它也映射:

  • 主机上的PID为18010的容器中的PID 8,以及
  • PID 9至PID 18011;
  • PID 10到PID 18012等等…

(这允许我debuggingdocker容器中的进程,使用只在主机上可用的工具,而不是容器中的工具,比如strace)

问题是,我不知道如何安全地假设pstree在容器和主机中以相同的顺序列出进程。

如果有人能够build议一个更可靠的方法来检测在Docker容器内部运行的特定进程的主机上的PID是什么,那将是非常好的。

您可以查看/proc/<pid>/status文件以确定名称空间PID和全局PID之间的映射。 例如,如果在泊坞窗容器中,我启动几个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