簡體   English   中英

為什么在使用 docker-compose 的 Docker 容器中,Python 進程的父 pid 有時為 0?

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

直接從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。這是預期的行為,如果是,是否有 Python 代碼的解決方法以這種依賴父PID的方式運行?

這既不奇怪也不錯誤——父 PID 為 0,因為 Docker 容器中沒有父進程

當運行諸如docker-compose run thing python類的docker-compose run thing python ,在該容器(或更准確地說,在該PID 命名空間中)中啟動的第一個進程將是python進程本身。 因此,它將獲得 PID 1 並且它不會有父進程。

注意:完全相同的事情也發生在常規(非容器化)Linux 系統上; PID 為 1 的進程也是第一個進程(在這種情況下由內核在引導后啟動)並且通常是一個類似systemd的初始化系統。 init 系統然后處理啟動 Linux 系統的用戶空間部分(比如設置網絡、掛載文件系統和啟動系統服務)——在 Docker 容器中,通常不需要任何這些,這也消除了需要任何初始化系統。 但是,有一些 init 系統,例如dub-init ,它們是專門為在容器中運行而設計的。

在容器中運行 shell 並從該 shell 啟動 Python 時,shell 將為 PID 1。在這種情況下,從 Python 腳本運行os.getppid()應返回1

這是預期的行為,如果是,是否有解決方法以依賴父 PID 的方式運行 Python 代碼?

如前所述,您可以從 shell(或任何其他進程,就此而言)啟動 Python 環境,然后將獲得 PID 1 而不是 python。 您還可以使用為容器設計的 init 系統,例如dumb-init

這是預期的行為。 容器內的主進程是 PID 1,沒有父進程。 這是容器隔離的一部分——進程似乎是整個系統中唯一的進程。

當我從 bash shell 中運行 python shell 時,我看到了一個更合理的值......

在這種情況下,根進程是 bash,它有一個 python 子進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM