当前位置: 首页 > 面试题库 >

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

龙毅
2023-03-14
问题内容

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的话,那就太好了。


问题答案:

您可以查看/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


 类似资料:
  • 我在分析运行在docker容器和主机上的Java应用程序的内存消耗时遇到了一个有趣的问题。 Java应用程序是Jetty server 9.4.9上的web应用程序 Java版本:1.8 主机:Mac Docker Images:Jetty:9.4-jre8 docker守护进程是18.03.1-CE版本。 在主机上,我使用Yourkit工具来分析内存消耗。 假设提供了错误的结果,我尝试使用标志限

  • 问题内容: 我看到很多人都在为此苦苦挣扎,好像在redis容器映像中可能有一个错误,而其他人似乎在追寻类似的问题。 我在DockerHub上使用标准Redis映像。(https://github.com/dockerfile/redis) 像这样运行它: 进入服务器后,就可以启动服务器,并从容器映像进行Redis ping了。 不幸的是,我无法从主机连接到Redis容器。 我已经尝试设置,例如下面

  • 我找到了很多关于如何在中运行的博客,但没有一个真正解释这样做的好处。 1)我希望服务器的大部分配置都在版本控制之下。 2)当我尝试新功能或配置时,我希望能够在我的计算机上本地运行构建服务器 3)我希望能够轻松地在一个新的环境中建立一个构建服务器(例如。在本地服务器上,或在云环境(如AWS)中)

  • 问题内容: 我找不到这个问题的直接答案,但是这里是: 假设我有一台主机,最多可打开1024个文件: 和在该主机中运行的docker容器,其中包含: 如果我尝试打开1024个以上的文件,那么容器中会有问题吗?我认为在这种情况下,容器的实际限制将是1024个文件。你怎么看? 问题答案: 虽然有点晚,但我只想清除对ulimit差异的怀疑。 如果在运行容器时确实设置了该值,则容器内显示的ulimit值来自

  • 问题内容: 说,如果我在Docker容器中使用此命令。 这里的本地主机指的是什么?主机的IP还是Docker容器自己的IP? 问题答案: 从容器内部开始 ,始终引用当前容器。它永远不会引用另一个容器,也永远不会引用物理系统中运行的不在同一容器中的任何其他内容。建立与数据库主机的出站连接或将其配置为数据库主机通常没有用。 从主机系统上的Shell中 ,可以指代在Docker之外的系统上运行的守护程序

  • 问题内容: 标题基本上说明了一切:在单个Docker主机上同时运行的容器数量是否有限制? 问题答案: 您可以遇到(和解决)许多系统限制,但根据 您如何配置Docker容器。 您正在容器中运行的内容。 您所使用的内核,发行版和Docker版本。 下图来自基于Tiny Core Linux 7的boot2docker 1.11.1 vm映像。内核是4.4.8 码头工人 在您在容器内部运行的基础之上,D