Warm tip: This article is reproduced from serverfault.com, please click

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

(linux - What is the PID in the host, of a process running inside a Docker container?)

发布于 2016-10-08 10:33:09

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

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

# 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等...

(这允许我使用仅在主机上可用,而在容器中不可用的工具(例如strace)从docker容器调试进程)

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

如果有人可以提出一种更可靠的方法来检测运行在Docker容器内的特定进程的主机上的PID的话,那就太好了。

Questioner
Luke 10X
Viewed
0
9,768 2017-09-05 21:53:42

你可以查看/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名称空间中,该进程具有pid7。确实,如果我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