【问题标题】:Why is the parent pid of a Python process sometimes 0 in Docker containers with docker-compose?为什么使用 docker-compose 在 Docker 容器中 Python 进程的父 pid 有时为 0?
【发布时间】:2020-01-03 20:49:16
【问题描述】:

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

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

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

当我在其中运行 python shell 时,它的 ppid 为 0;以这种方式运行的任何 python 代码也是如此(例如,如果使用 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 如何处理正在运行的容器中的进程的一些奇怪行为,但在我看来,PID 不应该为 0。这是预期的行为吗,如果是的话,是否存在以这种方式运行依赖父 PID 的 Python 代码的解决方法?

【问题讨论】:

    标签: python docker docker-compose pid multiple-processes


    【解决方案1】:

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

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

    注意:在常规(非容器化)Linux 系统上也会发生完全相同的事情; PID 为 1 的进程也是第一个进程(在这种情况下由内核启动后启动),通常是一个像 systemd 这样的初始化系统。然后 init 系统处理启动 Linux 系统的用户空间部分(例如设置网络、挂载文件系统和启动系统服务)——在 Docker 容器中,通常不需要任何这些,这也消除了需要任何初始化系统。但是,有一些像 dumb-init 这样的初始化系统是专门为在容器中运行而设计的。

    当在容器中运行 shell 并从该 shell 启动 Python 时,shell 的 PID 为 1。在这种情况下,从 Python 脚本运行 os.getppid() 应该返回 1

    这是预期的行为吗?如果是这样,是否有解决方法让 Python 代码以这种方式运行并依赖于父 PID?

    如前所述,您可以从 shell(或任何其他进程,就此而言)启动 Python 环境,然后获取 PID 1 而不是 python。您还可以使用为 dumb-init 等容器设计的初始化系统。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 现在,值得一提的是,如果您的程序需要使用子进程并且表现不佳,那么您的程序“pid=1”这一事实可能会导致“zombie”出现问题进程”在容器中。
      猜你喜欢
      • 1970-01-01
      • 2022-12-05
      • 2023-01-22
      • 2023-01-22
      • 1970-01-01
      • 2019-02-13
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多