Docker ComposeでGraceful Shutdownのための時間をかせぐ方法

こんにちは。 エキサイト株式会社の三浦です。

前回、ECS FargateとGraceful Shutdownに関する記事を書きました。

tech.excite.co.jp

今回はこの調査をしている時に直面した、Docker Composeで実行したコンテナの終了時、Graceful Shutdownが完了する前に強制停止されてしまう場合がある件について説明していきます。

Docker ComposeとGraceful Shutdown

上記の記事で書いたとおり、コンテナで動いているアプリケーションを安全に終了させるためにはGraceful Shutdownをすることが必要です。

すなわち、例えばWebサーバであれば、「コンテナ停止時に即時終了するのではなく、さばいているアクセスがすべて完了してから停止する」というような感じです。

Docker Composeでも、適切な終了シグナルを送信するようにすればちゃんとGraceful Shutdownを開始してくれるのですが、実は場合によっては途中でGraceful Shutdownが打ち切られ、強制終了されてしまう場合があります。

Docker Composeと stop_grace_period

Docker Composeには stop_grace_period という設定項目があります。

docs.docker.com

stop_grace_period specifies how long the Compose implementation MUST wait when attempting to stop a container if it doesn’t handle SIGTERM (or whichever stop signal has been specified with stop_signal), before sending SIGKILL. Specified as a duration.

Default value is 10 seconds for the container to exit before sending SIGKILL.

この項目は、「終了コードを送った後にこの項目に設定した時間が経過したら、Graceful Shutdownが完了していなくても強制終了する」というもので、デフォルトは10秒になっています。

すなわち、この項目に何も設定していない場合、Graceful Shutdownに10秒以上掛かってしまうアプリケーションでは、10秒の時点で強制終了されてしまうということです。

もし10秒以上時間がかかる可能性があるのであれば、適切な値をここに設定しましょう。

ECS Fargateと stopTimeout

実はこれに似たような設定が、ECS Fargateのタスク定義にも存在します。

docs.aws.amazon.com

stopTimeout

コンテナが正常に終了しなかった場合にコンテナが強制終了されるまでの待機時間 (秒)。

上記の通り、 stopTimeout という設定項目がそれに該当します。

ECS Fargateの場合はデフォルトが30秒となっていますが、こちらも必要に応じて適切な値に変更するのが良いでしょう。

{
    "family": "***",
    ...
    "containerDefinitions": [
        {
            "name": "***",
            "stopTimeout": 60,
            ...
        }
    ]
}

最後に

今回は、Graceful Shutdownを気にし始めると躓くかもしれないタイムアウトの設定値について説明しました。

Graceful Shutdownは、適切に設定しないとユーザが不利益を被る結果になることもあるので注意していきましょう。