【发布时间】:2017-02-17 06:48:39
【问题描述】:
在一个 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 是什么,那就太好了。
【问题讨论】:
-
pid 也可以表示操作系统线程,至少在 linux 上是这样。您可以通过创建多个线程并计算您获得的 PIDS 来检查 java(或其他语言)。