gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 19:21:12 26 4
gpt4 key购买 nike

直接从 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 代码?

最佳答案

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

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

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

当在容器中运行 shell 并从该 shell 启动 Python 时,shell 将为 PID 1。在这种情况下,运行 os.getppid()从你的 Python 脚本应该返回 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 .

关于python - 为什么在使用 docker-compose 的 Docker 容器中,Python 进程的父 pid 有时为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59585163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com