Spotインスタンスの中断通知を完全理解する〜コスト70%OFFの代償と、安全に終わらせる作法〜

AWS

「Spotインスタンスを使うとEC2やFargateの料金が最大70〜90%安くなる」という話を聞いたことはありませんか?ただし、その代わりに「AWSの都合でいきなり終了させられる」という制約があります。とはいえ、ただ突然終了するわけではなく、AWSは2分前(120秒前)に「中断通知」を送ってくれるので、その時間内にきちんと後片付けをすれば安全に使えます。この記事では、その仕組みと、特にFargate Spotでの実装ポイントを詳しく解説します。

この記事を読むと以下のことが得られます。

  • Spotインスタンスの中断通知が「いつ・どのように」送られるかが分かる
  • SIGTERMとSIGKILLの違いと、120秒の猶予時間の意味が理解できる
  • Fargate Spotで「StopTimeoutを75秒に設定する理由」が腹落ちする
  • AWS認定試験(SAP-C02)で問われやすい「グレースフルシャットダウン」の設計ポイントが押さえられる

Spotインスタンスとは何か

Spotインスタンスは、AWSのデータセンターで「今は使われていない余剰のコンピューティング容量」を、最大70〜90%の割引価格で借りられる仕組みです。EC2 SpotとFargate Spotの2種類があります。

項目通常の料金Spot
料金定価最大90%OFF(EC2)/70%OFF(Fargate)
中断リスクなしAWS都合で突然中断される
用途本番Webサーバー等バッチ処理、検証、再実行可能タスク

「途中で止められても問題ない処理」に向いており、例えるならば「席が空いていれば乗れる新幹線の自由席」のようなイメージです。安く乗れる代わりに、満席になったら降ろされる可能性があります。

中断通知(Spot Interruption Notice)の仕組み

AWSがSpotインスタンスを取り戻す必要が生じた場合、いきなり電源を切るのではなく2分前(120秒前)に中断通知を送ります。これをSpot Instance Interruption Noticeと呼びます。通知の届き方は主に以下の2通りです。

通知方法EC2 SpotFargate Spot
① インスタンスメタデータあり(http://169.254.169.254/latest/meta-data/spot/…)なし
② Amazon EventBridgeイベントあり(EC2 Spot Instance Interruption Warning)あり(タスク状態変更イベント)
③ コンテナ/プロセスへのシグナル(ユーザー実装)SIGTERMが送られる

EventBridge(イベントブリッジ)とは、AWSサービス間でイベントを橋渡しするサービスです。「Spotが中断される」というイベントをLambda関数やSNS通知に連携できます。

EC2 Spotの場合、インスタンス内からメタデータURLにアクセスすると中断時刻が返されます。レスポンスの例は以下の通りです。

{
  "action": "terminate",
  "time": "2026-05-10T08:22:00Z"
}

アプリ側でこのエンドポイントを「5秒ごとにポーリング(定期確認)」して、中断が検知されたら処理を切り上げるのがAWS公式の推奨実装です。

120秒のタイムライン:SIGTERMとSIGKILLの違い

中断通知が来てから強制終了されるまでの120秒間に何が起きるのかを整理します。

SIGTERMとSIGKILLの違い

シグナル性質アプリ側の対応
SIGTERM(T=0)「終わってください」というお願い無視可能。アプリが自発的にシャットダウンするチャンス
SIGKILL(T=120)強制終了の命令無視不可。即座にプロセス終了=データ損失

シグナルとは、Linux/UNIX系OSがプロセスに送る通知のことで、コマンドで言うとkill -15(SIGTERM)、kill -9(SIGKILL)に相当します。SIGTERMは「終了して」というお願いなので、アプリ側で無視することも、後処理を入れて自発的に終わらせることもできます。

よくある誤解:「中断通知から120秒後にSIGTERMが送られて強制終了される」は誤りです。正しくは「中断通知=SIGTERM(T=0秒)」「120秒後=SIGKILL」。中断通知それ自体がSIGTERMであり、アプリが120秒以内に自発的に終わらなければSIGKILLで強制終了される、という仕組みです。

Fargate Spotの設定:なぜ「StopTimeout=75秒」が推奨か

Fargate Spotでは、ECSタスク定義のstopTimeoutパラメータで、SIGTERMを受信してからSIGKILLが送られるまでの待機時間を設定します。

設定値結果判定
30秒(デフォルト)アプリの後処理が間に合わず、リクエストが途切れる❌ 短すぎる
75秒(推奨)アプリに十分な猶予+ECS側に45秒の後処理時間✅ ちょうど良い
120秒(MAX)ECSの後処理時間がなく、結局SIGKILL⚠️ 危険

CloudFormationでの設定例は以下の通りです。

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    ContainerDefinitions:
      - Name: app
        Image: !Sub ${ECRRepo}:latest
        StopTimeout: 75   # Fargate Spot対応の推奨値

StopTimeoutを120秒MAXにすると、もしアプリが終わらなかった場合、ECS側がタスクを片付ける時間(ENI解放、タスク登録解除など)が確保できません。結果として最終的にSIGKILLされてしまうため、アプリ用に75秒、AWS側に45秒という配分が安全です。

アプリ側での実装:グレースフルシャットダウン

StopTimeoutを延長しただけでは不十分です。アプリケーション側でSIGTERMを受け取って適切に後処理する実装が必須です。これをグレースフルシャットダウン(Graceful Shutdown)と呼びます。「グレースフル(Graceful)」は「優雅な、丁寧な」という意味で、要するに「店じまいの時に入口を閉じて、店内のお客さん(処理中のリクエスト)を最後までもてなしてから店を閉める」動作です。

グレースフルシャットダウンは以下の4ステップで行います。

  1. 新規リクエストの受付を停止(ロードバランサーから自分を切り離す)
  2. 処理中のリクエストを完了させる(レスポンスを返し終える)
  3. リソース解放(DB接続クローズ、ログのフラッシュ、未処理メッセージの戻し)
  4. プロセス終了(自発的に exit 0)

言語・フレームワークごとのSIGTERMハンドラ実装方法は以下の通りです。

言語/フレームワークSIGTERMハンドラ
Node.js(Express)process.on('SIGTERM', () => server.close())
Java(Spring Boot)server.shutdown=graceful をプロパティに設定
Gosignal.Notify(c, syscall.SIGTERM)
Python(Gunicorn)デフォルトでgraceful対応(–graceful-timeout)

インフラ設定(StopTimeout)とアプリ実装(SIGTERMハンドラ)は必ずセットで考えます。どちらか一方だけでは効果がありません。

あわせて知っておきたい:ALBの登録解除遅延

Fargate SpotタスクをALB(Application Load Balancer)の背後に置いている場合、もう1つ重要な設定があります。それがderegistration_delay(登録解除遅延)です。これは「ALBがターゲット(コンテナ)を切り離してから、既存接続を維持する時間」のことで、デフォルトは300秒です。

中断通知の猶予は120秒なのに、登録解除遅延が300秒だと、タスクが消えた後もALBがリクエストを送り続けて5xxエラーが発生します。Spot使用時は30〜60秒程度に短縮するのがセオリーです。

例え話で理解する:Spot中断通知は何に似ているか

飛行機でのオーバーブッキングを想像してください。航空会社が「すみません、満席になったので別の便に乗ってもらえませんか?」と2分前にアナウンスするようなものです。

このアナウンス(SIGTERM)を聞いた乗客(アプリ)は、「荷物をまとめて降りる準備をする(処理中タスクの完了)」を120秒以内に済ませる必要があります。間に合わなければ強制的に降ろされて(SIGKILL)、荷物が機内に置き去りになる(データ損失)というイメージです。そして「StopTimeout=75秒」というのは、「降りる準備に75秒以内、残りの45秒は航空会社が次のお客さんを案内する時間」という時間配分のルールに該当します。

SAP-C02試験で問われるポイント

AWS認定ソリューションアーキテクト – プロフェッショナル(SAP-C02)では、Spotとグレースフルシャットダウンの組み合わせがよく出題されます。「Spotで処理が途中で切れる問題の対処」として、以下の3つすべてを組み合わせるのが正解パターンです。

  • StopTimeoutを延長(30秒→75〜90秒)
  • アプリにSIGTERMハンドラを実装
  • ALBのderegistration_delayを短縮(300秒→30秒程度)

また、Spot系サービスの中断猶予はすべて同じです。試験対策として覚えておきましょう。

サービス中断通知の猶予
EC2 Spot Instance2分前に通知
Fargate Spot2分前に通知
EKS Spot Pod2分前に通知

EC2 Spot・Fargate Spot・EKS Spot Podのいずれも、中断猶予は「2分(120秒)」で統一して覚えれば大丈夫です。

まとめ

  • Spotインスタンスは「最大70〜90%OFFの代わりに、AWS都合で中断される」
  • 中断時は「2分前にSIGTERMが送られる」(=これが中断通知の正体)
  • 120秒以内にアプリが自発的に終わらないと、SIGKILLで強制終了される
  • Fargate Spotでは「StopTimeoutを75秒」に設定するのが推奨(MAX 120秒の手前で安全マージン確保)
  • アプリ側にも「SIGTERMハンドラを実装」して、グレースフルシャットダウンを行う
  • ALB配下のSpotタスクは「deregistration_delayの短縮」もセットで設定する

「コスト削減と可用性確保のバランス」は、SAP-C02試験でも実務でも繰り返し問われるテーマです。Spot系を採用する際は、インフラ設定+アプリ実装のセットで対応することを忘れないでください。

参考リソース

コメント

タイトルとURLをコピーしました