この記事は Nginx の公式 Docker Image がコンテナシャットダウン時にデフォルトで graceful shutdown になったことが嬉しかったという内容です。(1.19.5 以降)
前提条件
以下のような方々に少しでも嬉しさが伝わると幸いです。
- docker stop、docker-compose、kubernetes でコンテナを操作・運用している方々
- コンテナシャットダウン時に 502 エラーが許されないサービスを開発している方々
graceful shutdown とは
wiki によると「プログラムが重大なエラーを検出し、何らかの制御により正常に終了させること」と書いてあります。web サービスをコンテナで提供する場合に限定すると、以下のような要件になると思います。
- コンテナがシャットダウンされる時、既に存在するコネクションやリクエストの処理を完了させること
- コンテナがシャットダウンされる時、新規に接続を受け付けないようにすること
今までの Nginx コンテナの挙動
今まで(v1.19.4 以下) の Nginx コンテナを終了するとSIGTERM シグナル
が送信されていました。(Nginx のエラーログレベルを notice 以下にすると見れます。以下のログは v1.19.3 の場合)
これは、docker や Kubernetes のデフォルト動作でコンテナ終了時に SIGTERM シグナル
を送信するためです。
参照:docker stop、docker-compose、Kubernetes
問題は Nginx が SIGTERM シグナル
を受信すると、即刻シャットダウン動作に移行すること です。(Nginx 公式 より)
そのため、デフォルト設定のまま運用すると場合によっては 502エラーが出てしまうこともありました。
今までの回避方法
この現象を避けるためには Nginx コンテナにSIGQUIT シグナル
を送信すれば良い です。(Nginx 公式 より)
代表的な方法は以下です。
ちょっとしたことですが、どちらも「そんなの知らなかった!」とか「加工のひと手間が面倒・・・」ということを感じていました。
これからの回避方法
何もしなくて良いです。
Nginx 1.19.5 以上のイメージは上記のSTIOPSIGNAL
の定義が上書きされ、デフォルトで SIGQUIT シグナル
が送信されます。(以下は v1.19.5 の場合)
これにより、graceful shutdown のために Dockerfile をいじったり、preStop を定義したりする必要は無さそうです!
ちょっと嬉しい。
まとめ
graceful shutdown が要件のサービスで Nginx コンテナを使っている場合、v1.19.5 以上を使うと少し楽かもしれません。
ただし、構成やツールによって Nginx 単体の graceful shutdown では要件を満たさない場合もありますのでご注意ください。