この記事は何?
Dockerコンテナを動かしていてゾンビプロセスが大量に発生してしまう問題に対応したときのメモです。
現象
- Docker内で動作しているスクリプトを kill して別のスクリプトを動作させるような処理を書いていたが、コンテナを実行し続けると、killしたプロセスがゾンビプロセスとして残り続けてしまいました。(topコマンドで見ると以下のように STAT Z のプロセスが大量に存在する状態に。。。)
Mem: 6740044K used, 1407404K free, 108340K shrd, 243896K buff, 879356K cached
CPU: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
Load average: 0.07 0.19 0.59 2/1306 252
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
249 1 root S 18188 0% 0% /root/.cache/pypoetry/virtualenvs/app-9TtSrW0h-py3.9/bin/python app.py
7 0 root S 5748 0% 0% /bin/bash
1 0 root S 2208 0% 0% busybox crond -f -L /dev/stderr
252 7 root R 2208 0% 0% busybox top
71 1 root Z 0 0% 0% [python]
50 1 root Z 0 0% 0% [python]
127 1 root Z 0 0% 0% [python]
218 1 root Z 0 0% 0% [python]
163 1 root Z 0 0% 0% [python]
123 1 root Z 0 0% 0% [python]
183 1 root Z 0 0% 0% [python]
119 1 root Z 0 0% 0% [python]
132 1 root Z 0 0% 0% [python]
171 1 root Z 0 0% 0% [python]
150 1 root Z 0 0% 0% [python]
144 1 root Z 0 0% 0% [python]
115 1 root Z 0 0% 0% [python]
結論
コンテナ起動時に init オプションを指定する。docker run なら --init オプションをつける。docker-composeなら init:true を指定する。
version: '3.8'
services:
batch:
container_name: batch
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./app:/app
init : true
原因
docker コンテナ内でPID=1のプロセスが init プロセスでなかったため、シグナルを扱えず正常にプロセスを終了できなかったのが原因のようです。
initプロセスについて
chatGPTに聞いたところ、以下の答えが返ってきました。参考までに。
- initプロセスは、システムの起動からシャットダウンまでのライフサイクルを管理する役割を担っている。Linuxシステムにおいて特別な役割を持ち、PID=1のプロセスとなっている。
- Dockerコンテナ内において、PID=1のプロセスは、initプロセスにならないようにすることが推奨されている。これは、Dockerコンテナが軽量かつ独立した環境であるため。Dockerfile 内に CMD や ENTRYPOINT を指定するとPID=1のプロセスがここで指定したコマンドになる。
- Dockerコンテナ内でPID=1がinitプロセスでない場合、シグナルの扱い、デーモンの管理、コンテナの終了処理などに問題が生じる可能性がある。
- これらの問題を回避するために、Dockerでは、軽量なinitシステムであるtiniなどを使用することが推奨されている。tiniは、PID=1を実行し、シグナルの受信やプロセスの管理などの必要な機能を提供することができる。
- Docker Composeの
init
オプションや docker run の--init
オプションは、Dockerコンテナ内でtiniを使用するためのオプション。tiniを使用することで、Dockerコンテナ内でPID=1のプロセスを管理し、シグナルの受信やプロセスの管理などの必要な機能を提供することができる。
参考
以下の記事を参考にさせていただきました。