在Docker容器中运行的进程的主机中的PID是什么? [英] What is the PID in the host, of a process running inside a Docker container?

查看:632
本文介绍了在Docker容器中运行的进程的主机中的PID是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



例如,一个Apache Web服务器在Docker容器内运行,
(我使用Apache + PHP映像从 Docker Hub ),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进程的子进程:

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


$ b $从这一点我假设容器中的PID 1如何映射到主机上的PID 17985一样,也映射:




  • 容器中的PID 8在主机上为PID 18010,而

  • PID 9到PID 18011;

  • PID 10到PID 18012
    等等...



(这允许我从docker容器调试进程,使用只能在主机,而不是在容器中,像strace)



问题是,我不知道如何安全地假设pstree列出同一个目录中的进程r在容器和主机中。



如果有人可以建议更可靠的方式来检测主机上的特定进程正在运行的是什么,那将是很棒的在Docker容器内部。

解决方案

您可以查看 / 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根0:00睡眠900
9根0:00睡眠900
10根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睡眠900

对于任何一个,我可以看看状态文件来查看命名空间pid:

 #cat / proc / 10394 / status | grep -i pid 
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


There are several processes running in a Docker container, their PIDs are isolated in the container namespace, is there a way to figure out what are their PIDs on the Docker host?

For example there is an Apache web server running inside a Docker container, (I use Apache+PHP image from Docker Hub), and the Apache, when it starts, creates more worker processes inside the container. Those worker processes are actually handling incoming requests. To view these processes I run pstree inside the docker container:

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

The parent Apache process runs on PID 1 inside of the container process namespace. However from the host's perspective it can be also accessed, but its PID on the host is different and can be determined by running docker compose command:

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

From this we can see that the PID 1 from within the container process namespace maps to PID 17985 on the host. So I can run pstree on the host, to list the children of the Apache process:

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

From this I assume that the same way how PID 1 in the container maps to PID 17985 on the host, it also maps:

  • PID 8 in container to PID 18010 on host, and
  • PID 9 to PID 18011;
  • PID 10 to PID 18012 and so on...

(This allows me to debug the processes from docker container, using tools that are only available only on the host, and not the in the container, like strace)

The problem is that I don't know how safe is to assume that pstree lists the processes in the same order both in the container and in the host.

Would be great if someone could suggest a more reliable way to detect what is a PID on the host of a specific process running inside the Docker container.

解决方案

You can look at the /proc/<pid>/status file to determine the mapping between the namespace PID and the global PID. For example, if in a docker container I start several sleep 900 processes, like this:

# docker run --rm -it alpine sh
/ # sleep 900 &
/ # sleep 900 &
/ # sleep 900 &

I can see them running in the container:

/ # 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

I can look at these on the host:

# 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

And for any one of those, I can look at the status file to see the namespace pid:

# cat /proc/10394/status | grep -i pid
Pid:    10394
PPid:   10366
TracerPid:  0
NSpid:  10394   7

Looking at the NSpid line, I can see that within the PID namespace this process has pid 7. And indeed, if I kill process 10394 on the host:

# kill 10394

Then in the container I see that PID 7 is no longer running:

/ # 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容器中运行的进程的主机中的PID是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆