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

标签 linux docker process pid

在一个 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/

相关文章:

docker - 如何在 docker 1.9+ 中列出命名卷的内容?

php - 将FFmpeg作为php中的进程运行时出现超时错误

linux - 用于将日志文件复制到单个压缩文件中的 shell 脚本

Linux内核中Dentry和 super block 结构之间的循环依赖

c - 如何在 IPv4/v6)地址(和端口)和字符串之间进行转换?

android - Android中的每个Activity都是一个进程,或者一个应用程序是一个进程

Java:除非手动刷新,否则无法从进程获取标准输出数据

c++ - 分析嵌入式应用程序

docker - 在Docker构建期间名称解析失败

docker - 没有互联网的 Alpine Linux 安装包(docker)