この記事は 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 では要件を満たさない場合もありますのでご注意ください。