立ち上げたDockerが終了するのが遅い
gccのイメージを使ってdockerコンテナをデタッチで立ち上げたが、終了するのが遅いのでそれを解消した。
結論
- コマンドは
bashではなく、catを使うとよさそう。 -
initプログラムをPID1で実行しよう。
課題
次のようなdocker-compose.ymlファイルを作成して、docker compose up -dを実行して、コンテナ(?)を立ち上げた。
services:
gcc:
image: gcc
container_name: hoge
tty: true
command: "bash"
そのあと、docker compose exec -it gcc bashでコンテナにアクセスして、作docker compose downでコンテナを終了しようとしたら、10秒ほどかかる。なぜに!?

10秒もかかっていると、CIや自動化でイライラしそうなので、今のうちに解決したい。
docker コンテナ 終了しないやdocker 終了 遅い コンテナなどで調べると、次のようなことが原因らしい。
原因1 - bash
dockerは、docker compose downやdocker <container名> stopを行ったときに対象のコンテナにSIGTERMを送信する。しかし、bashはSIGTERMが送信されても新しいプロンプトを返すだけで、終了はしない。SITERMがタイムアウトになり、dockerはSIGKILLを送信して強制終了する。そのため、時間がかかっていたようである。
ttyは、疑似端末を割り当てるために必要、、、らしい。勉強不足だが、これを付けるとフォアグラウンドではなくデタッチドでもコンテナが終了しない。
bashがSIGTERMを送信されても、終了しないことはkill -s SIGTERM $$(現在のシェルのプロセスにSIGTERMを送信する)などで確認可能。あとは、公式リファレンスとか探すと書いてあるかも。知らんけど。
原因2 - init & PID1
PID1のプロセスだけは明示的に、SIGTERMを処理しないと終了処理が走らないらしい。killコマンドが制限しているのか、一体何が制限しているのかは不明。
また、Linux系は最初にinitというプログラムが実行される。dockerコンテナだとそれをすっ飛ばして、コマンドを実行する。それによって、本来initプログラムが正常にSIGTERMを処理していたところ、それがなくてタイムアウトまで終了しないようである。
原因まとめ
PID1でinit以外のプログラムやSIGTERMを処理しないプログラムがあると、終了しない。initのサブプロセスとしてbashを実行していたとしても、SIGTERMを無視するため終了しない。
解決策
dockerはdocker-initというプログラムがデフォルトでインストールされているそう。docker runでは--init, docker-compose.ymlではinitを追加すれば、普通のOSのような処理を色々してくれる。ref.docker-run#init: https://docs.docker.jp/engine/reference/run.html#init
bashはSIGTERMを無視してしまうので、catコマンドを使う。
catコマンドの採用理由は、入力を待機してくれること、大抵のLinuxに入っていること、処理負荷が少なそうなこと、メモリ消費量が比較的少ないこと、があげられる。
メモリ消費量に関しては、手元の環境では796kbほどだった。(思ってたより多かった)
sh: 936kb,bash: 3484kb (topコマンドのRES値を参照した)
結果
問題なく終了するdocker-compose.yml
services:
gcc:
image: gcc
container_name: hoge
tty: true
init: true
command: "cat"
終了処理

まとめ
強制終了のため10.3sかかっていた終了処理が、0.3sにまで短くなった。
このやり方が色々問題が発生しないかは疑問が残るが、目的は達成できてよかった。
おまけ - docker run
bash
起動
docker run -itd --rm --init --name hoge gcc bash
終了(計測込み)
$ time docker stop hoge
hoge
real 0m10.694s
user 0m0.000s
sys 0m0.000s
cat
起動
docker run -itd --rm --init --name hoge gcc cat
終了(計測込み)
$ time docker stop hoge
hoge
real 0m0.602s
user 0m0.000s
sys 0m0.046s
Discussion