0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS EC2 で Spot Instance interruption notices を取得する方法

0
Posted at

EC2 の Spot Instance はコストを抑えられる一方で、AWS 側の都合により中断されることがあります。

そのため、Spot Instance を本番やバッチ処理で使う場合は、中断前の通知を受け取って安全に終了処理を行う仕組み を入れておくのが重要です。

この記事では、EC2 の Spot Instance interruption notices を取得する方法を、できるだけわかりやすく整理します。


Spot Instance interruption notice とは

Spot Instance が停止・終了される前に、AWS から送られる通知です。

通常は 中断の約2分前 に通知されます。
この通知を使うことで、たとえば次のような処理ができます。

  • 処理中データの保存
  • graceful shutdown
  • ECS / Kubernetes / 独自アプリの drain 処理
  • ログやメトリクスの出力
  • 別インスタンスへの切り替え

ただし、この通知は ベストエフォート です。
必ず毎回届く前提ではなく、通知が来なくても問題が起きない設計 にしておくことが大切です。


取得方法は2つある

Spot Instance interruption notice を取得する方法は、主に次の2つです。

1. インスタンス内で取得する

EC2 インスタンス自身が、インスタンスメタデータを確認して通知を受け取る方法です。

2. EventBridge で取得する

AWS のイベントとして受け取り、Lambda や SNS などに連携する方法です。

まずは全体像をざっくり整理すると、次のような使い分けになります。

方法 用途
インスタンスメタデータ(IMDS) そのインスタンス自身が終了前処理をしたい
EventBridge 複数台をまとめて監視・通知・自動化したい

1. インスタンス内で取得する方法(IMDS)

もっともシンプルなのは、EC2 インスタンスの中から Instance Metadata Service(IMDS) を確認する方法です。

Spot Instance では、以下のメタデータを参照できます。

/latest/meta-data/spot/instance-action

このエンドポイントにアクセスすると、Spot Instance に中断通知が来ている場合に内容が返ります。
まだ通知が来ていない場合は 404 になります。

AWS では、この確認を 5秒ごと に行うことが推奨されています。


返ってくる内容

通知が来ていると、たとえば次のような JSON が返ります。

{
  "action": "terminate",
  "time": "2017-09-18T08:22:00Z"
}

action には次のような値が入ります。

  • terminate
  • stop
  • hibernate

IMDSv2 で取得する例

現在は IMDSv2 を使う構成が一般的なので、まずトークンを取得してからメタデータを参照します。

TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/spot/instance-action

監視スクリプトの例

以下は、5秒ごとに interruption notice を確認し、通知が来たら処理を始める例です。

#!/usr/bin/env bash
set -euo pipefail

TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

while true; do
  if RESPONSE=$(curl -s -f \
    -H "X-aws-ec2-metadata-token: $TOKEN" \
    http://169.254.169.254/latest/meta-data/spot/instance-action); then
    echo "Spot interruption notice detected: $RESPONSE"

    # ここで終了前処理を実行
    # 例:
    # - ワーカー停止
    # - キュー処理の終了
    # - データ保存
    # - ログ出力

    break
  fi

  sleep 5
done

この方法が向いているケース

この方法は、そのインスタンス自身が終了前処理をしたい場合 に向いています。

たとえば次のようなケースです。

  • バッチ処理中に checkpoint を保存したい
  • systemd サービスを安全停止したい
  • コンテナやアプリケーションを graceful shutdown したい
  • queue worker を停止して処理中ジョブを保護したい

つまり、即座にその場で反応したい処理 に向いています。


2. EventBridge で取得する方法

次に、AWS 全体のイベントとして Spot Instance interruption notice を受け取る方法です。

Spot Instance の中断通知は、Amazon EventBridge にイベントとして流れてきます。
イベント種別は次の通りです。

EC2 Spot Instance Interruption Warning

これを使うと、次のような連携ができます。

  • Lambda を起動する
  • SNS で通知する
  • SQS に送る
  • Step Functions で処理を分岐する
  • 監視基盤に送る

EventBridge のイベントパターン

EventBridge ルールでは、次のようなイベントパターンを設定します。

{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Spot Instance Interruption Warning"]
}

イベントの例

実際には、次のようなイベントが届きます。

{
  "version": "0",
  "id": "12345678-1234-1234-1234-123456789012",
  "detail-type": "EC2 Spot Instance Interruption Warning",
  "source": "aws.ec2",
  "account": "123456789012",
  "time": "yyyy-mm-ddThh:mm:ssZ",
  "region": "us-east-2",
  "resources": [
    "arn:aws:ec2:us-east-2a:instance/i-1234567890abcdef0"
  ],
  "detail": {
    "instance-id": "i-1234567890abcdef0",
    "instance-action": "terminate"
  }
}

このイベントの detail.instance-id を使えば、どのインスタンスに通知が来たのかを特定できます。


EventBridge ルールを CLI で作る例

aws events put-rule \
  --name spot-interruption-rule \
  --event-pattern '{
    "source": ["aws.ec2"],
    "detail-type": ["EC2 Spot Instance Interruption Warning"]
  }'

このあと、ターゲットとして Lambda や SNS を設定すれば、通知を受けて自動処理できます。


この方法が向いているケース

EventBridge は、複数台の Spot Instance をまとめて監視したい場合 に向いています。

たとえば次のような用途です。

  • Spot 中断を Slack やメールに通知したい
  • Lambda で自動復旧処理をしたい
  • 終了されたインスタンスの情報を記録したい
  • Auto Scaling や独自運用ツールと連携したい

つまり、運用監視や自動化のハブ として使いやすい方法です。


どちらを使うべきか

結論としては、次のように考えるとわかりやすいです。

インスタンス自身が終了前処理をするなら IMDS

アプリケーション停止、checkpoint 保存、ワーカー停止など、そのマシンの中で完結する処理 に向いています。

運用側で集約したいなら EventBridge

複数台の監視、通知、Lambda 連携など、AWS 全体で処理したい場合 に向いています。


実運用では併用がおすすめ

実際には、どちらか一方だけでなく 併用 がわりと定番です。

たとえば次のように分けると扱いやすいです。

  • IMDS
    インスタンス内で graceful shutdown やデータ保存を行う

  • EventBridge
    運用チームへの通知や記録、別システム連携を行う

この形にしておくと、アプリ側と運用側の両方で中断に備えられます。


注意点

1. 通知はベストエフォート

通知が来ないケースもあり得るので、Spot Instance を使うなら 途中終了されても壊れにくい設計 が前提です。

2. 通常は約2分前通知

多くのケースでは約2分前に通知されますが、その短い時間で終えられる処理にしておく必要があります。

3. hibernate は注意

hibernate の場合は通知が出ても、通常の「2分猶予」があるとは限りません。
復帰前提の設計かどうかを含めて考えておく必要があります。

4. termination-time より instance-action を使う

古い情報では spot/termination-time を使っている例もありますが、基本的には spot/instance-action を使うのが推奨 です。


まとめ

EC2 Spot Instance の interruption notice は、次の2つの方法で取得できます。

  • IMDS
    インスタンス自身が通知を取得する方法

  • EventBridge
    AWS イベントとして受け取り、通知や自動化に使う方法

シンプルに覚えるなら、次の認識で十分です。

  • そのインスタンスで終了前処理をしたい → IMDS
  • 運用監視や自動化に使いたい → EventBridge
  • 本番では両方使うのがおすすめ

Spot Instance はコスト最適化にとても便利ですが、終了前提で設計しないと運用が不安定になります。
interruption notice をうまく使って、安全に止まれる仕組みを入れておくのがポイントです。


参考

  • AWS EC2 Spot Instance interruption notices
  • AWS EventBridge と EC2 Spot interruption warning
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?