2022年10月9日日曜日

Dockerコンテナをgraceful shutdownするときの注意点

 前回はNode.jsプロセスのgraceful shutdownについて触れました。今回はそれの続きというか、Dockerコンテナで動かしているプロセスをgraceful shutdownするときの注意点です。

前提として、動かすプロセス自体はgraceful shutdownに対応しているものとします。つまりSIGTERMやSIGINTなどの終了シグナルを受け取ったらgraceful shutdownするように作られているものとします。やり方は前回の記事をご覧ください。

単にプロセスを実行するだけなら問題ない

対象のプロセスを実行するだけなら注意点も何もありません。Node.jsの公式Dockerイメージから好きなものを選んで、こんな感じのDockerfileを書けばOKです。

FROM node:current
...
CMD ["node", "server.js"]

スタートアップスクリプトを自前で用意する場合

問題が発生するのは、スタートアップスクリプト経由でプロセスを実行するとき。

単に対象のプロセスを実行するだけでなく、例えば事前にセットアップが必要とか、プロセスが使用するポート(DBとか)が使えるようになるのを待機するなどの処理が必要な場合です。

こんなコードを書くと、コンテナ終了時にプロセスが終了シグナルを受け取れず、コンテナのタイムアウト後に強制終了させられてしまいます。

#!/bin/bash
...
node server.js

おそらくシェルがシグナルを横取りしているのが原因。

正解はこう。

#!/bin/bash
...
exec node server.js

execでシェルを該当プロセスに置き換えてやれば、ちゃんとプロセスがシグナルを受け取ってgraceful shutdownできるようになります。

原因がわかれば単純な話なんですが、原因を突き止めるのに半日仕事でした。

0 件のコメント:

コメントを投稿