5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon ECS FargateでSTOPSIGNALが使えるようになりました

Last updated at Posted at 2025-12-14

Fargateで「STOP SIGNAL」が使えるようになりました

Dockerfileで定義されている STOPSIGNAL 命令を、 Fargate がコンテナに送るようになりました。

何が嬉しいのか?今までの課題

今まで ECS Fargateでは、graceful shutdown を実現する際に SIGTERM を受けてから安全に停止する処理を作成する必要がありました。
https://aws.amazon.com/jp/blogs/news/graceful-shutdowns-with-ecs/

しかし、ミドルウェアは停止命令による挙動が決まっています。
例えば、nginx はSIGTERMを受けるとすぐに停止します。そのため、SIGTERMを受けてSIGQUITを投げ直す trap 処理を書くなどの工夫が必要でした。
https://linuxjm.sourceforge.io/html/nginx/man8/nginx.8.html

改善された点

OCI標準に準拠するように、Dockerfile に STOPSIGNAL 任意のシグナル を指定するだけでFargate、Kubernetes、ローカルDockerのどこでも graceful shutdown が保証されるため可搬性が高まります。

なぜ今までできなかったのか?(考察)

Fargateは、AWSが管理する独自のホストOS(マイクロVM/Firecracker)上で動作していると思われるため、柔軟にアクセスできなかったのではないでしょうか。誰か詳しい人教えてください。

試してみた

検証用のソースはこちらにあります
https://github.com/nidcode/ecs-stop-signal-sample

以下のようなシンプルなプログラムを作成してテストしてみました。

server.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 8080;
const SHUTDOWN_DELAY_MS = parseInt(process.env.SHUTDOWN_DELAY_MS, 10) || 10000;

app.get('/', (req, res) => {
    res.send('Running and waiting for stop signal...');
});

const server = app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

// --- シグナルハンドラ定義 ---
// SIGTERM (デフォルトの停止シグナル) 用のハンドラ
process.on('SIGTERM', () => {
    handleShutdown('SIGTERM');
});

// SIGINT (カスタム検証用シグナル) 用のハンドラ
process.on('SIGINT', () => {
    handleShutdown('SIGINT');
});

// SIGKILL (強制終了) は捕捉できません!

function handleShutdown(signal) {
    console.log(`[${signal} RECEIVED] Graceful shutdown initiated.`);

    // 1. サーバーの新しい接続受付を停止
    server.close(() => {
        console.log('HTTP server closed.');
    });

    // 2. ログの書き出しやDBクローズなどのクリーンアップ処理をシミュレート
    console.log(`Starting cleanup. Waiting for ${SHUTDOWN_DELAY_MS / 1000} seconds...`);
    
    // 猶予時間内に処理を終えることを想定
    setTimeout(() => {
        console.log(`[${signal} SUCCESS] Cleanup complete. Exiting cleanly.`);
        process.exit(0);
    }, SHUTDOWN_DELAY_MS);
}

テスト用アプリケーションの動作

  • SIGINT を受け取ると10秒間クリーンアップ
  • CloudWatch Logsには [SIGINT RECEIVED] のログが記録される

検証するにあたって、ECSタスク定義 stopTimeout を 15秒 に設定しました

STOPSIGNALなしの動作

server.js に適当にコメントなどを追加して差分を作成し、 cdk deploy を実施して強制的にタスクを再作成してみます

想定通り SIGTERM を受け取っていることがわかります
スクリーンショット 2025-12-14 17.03.27.png

STOPSIGNALを設定

DockerfileにSTOPSIGNALを書くだけでOKです
server.jsと合わせて SIGINT を設定してみましょう

FROM node:22-slim
...
STOPSIGNAL SIGINT

CMD ["node", "server.js"]

無事にデプロイされたら、先ほどと同様に再度 cdk deploy をして強制的にタスクを作り直してみましょう。

SIGINTをキャッチしてくれました!
スクリーンショット 2025-12-14 17.30.46.png

まとめ

今回のカスタム停止シグナルサポートは、単なるパラメータの追加ではなく、AWS Fargateがコンテナランタイムの国際標準(OCI)に完全に準拠したことを示します。
これにより、コンテナ運用者は、他の環境で使っていた標準イメージをそのままFargateに持ち込めるようになり、デプロイや運用時の品質(Graceful Shutdown)が大幅に向上しました。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?