为什么 Python 进程的父 pid 在具有 docker-compose 的 Docker 容器中有时为 0?

Why is the parent pid of a Python process sometimes 0 in Docker containers with docker-compose?

当运行直接从docker-compose run中调用pythonshell时,父PID显示为0,感觉很不对。我在下面整理了一个非常简单、可重现的案例:

# Dockerfile
FROM python:3.7-buster
COPY . /code/
WORKDIR /code
# docker-compose.yml
version: '3'

services:
  thing:
    build: .
    volumes:
      - .:/code

当我从这个里面运行一个pythonshell时,它的ppid是0;同样以这种方式 python 代码 运行ning(如果 运行ning 使用 pytest 进行测试):

$ docker-compose run thing python
>>> import os
>>> os.getpid()
1
>>> os.getppid()
0

当我从 bash shell 中 运行 python shell 时,我看到了一个更理智的值...

$ docker-compose run thing bash
root@<id> # python
>>> import os
>>> os.getpid()
6
>>> os.getppid()
1

当我直接在主机上 运行 python shell 时,我也看到了更合理的 PID 值...

$ python
>>> import os
>>> os.getpid()
25552
>>> os.getppid()
1133

我确定这是关于 docker 如何处理 运行ning 容器中的进程的一些奇怪行为,但在我看来 PID 不应该为 0。是这种预期的行为,如果是这样,是否有 Python 代码 运行 以这种方式依赖于父 PID 的解决方法?

这是预期的行为。容器内的主进程是 PID 1 并且没有父进程。这是容器隔离的一部分——进程似乎是整个系统中唯一的进程。

When I run a python shell from within a bash shell, I see a more sane value...

在那种情况下,根进程是 bash 并且它有一个 python 子进程。

这既不奇怪也不错误 -- 父 PID 为 0,因为 Docker 容器中没有父进程

当 运行 类似 docker-compose run thing python 时,有史以来第一个进程 在该容器中启动(或更准确地说,在 PID namespace 中)将是 python 进程本身。因此,它将获得 PID 1,并且没有父进程。

注意:完全相同的事情也会发生在常规(非容器化)Linux 系统上; PID 为 1 的进程也是第一个进程(在这种情况下由内核在启动后启动)并且通常是一个像 systemd. The init system then handles the user-space part of booting your Linux system (like setting up your network, mounting file systems and starting system services) -- in a Docker container, there's typically no need for any of this, which also eliminates the need for any init system. However, there are init systems like dumb-init 这样的初始化系统,它是专门为容器中的 运行 创建的。

当容器中有 运行 一个 shell,并从 shell 开始 Python 时,shell 将是 PID 1。在这种情况下, 运行 os.getppid() 从你的 Python 脚本应该 return 1.

Is this expected behavior, and if so is there a workaround for Python code running this way that relies on a parent PID?

如前所述,您可以从shell(或任何其他进程)启动您的Python环境,然后获得PID 1 而不是 python。您还可以使用专为 dumb-init.

等容器设计的初始化系统