web-dev-qa-db-ja.com

Dockerコンテナー内で実行されているプロセスのホストのPIDは何ですか?

Dockerコンテナーで実行されているいくつかのプロセスがあり、それらのPIDはコンテナーの名前空間で分離されていますが、Dockerホスト上のPIDを把握する方法はありますか?

たとえば、Dockerコンテナー内で実行されているApache Webサーバー( Docker Hub のApache + PHPイメージを使用)があり、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プロセスの子をリストできます。

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

これから、コンテナ内のPID 1がホスト上のPID 17985にマップする方法と同じ方法で、それもマップすると仮定します。

  • コンテナー内のPID 8をホスト上のPID 18010に、および
  • PID 9からPID 18011;
  • PID 10からPID 18012など...

(これにより、straceのように、ホストでのみ使用でき、コンテナでは使用できないツールを使用して、Dockerコンテナからプロセスをデバッグできます)

問題は、pstreeがコンテナーとホストの両方で同じ順序でプロセスをリストすると想定するのがどれほど安全かわからないことです。

Dockerコンテナ内で実行されている特定のプロセスのホスト上のPIDを検出するより信頼性の高い方法を誰かが提案できたら、すばらしいでしょう。

15
Lukas Normantas

/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 root       0:00 sleep 900
    9 root       0:00 sleep 900
   10 root       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 sleep 900

そして、それらのいずれについても、statusファイルを見て名前空間pidを確認できます。

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