🍣
スポットインスタンスの中断通知を受けてスクリプトを実行する (インスタンスメタデータ編)
はじめに
スポットインスタンスは中断する可能性があります。
そのため中断通知を受け取ったら何かしらのアクション(バックアップ等)を実行して、中断の影響を少なくする必要があります。
今回はその避難訓練として、インスタンスメタデータから中断通知を受け取り、その通知から簡単なスクリプトを実行させる検証を行いました。
※EventBridge+Lambda編はいずれできたらいいな
検証内容
- 5秒おきにインスタンスメタデータ
instance-action
を確認するシェルスクリプトを動かす - 返却されるステータスコードが404であれば、中断通知が来ていないためそのまま続行
- 返却されるステータスコードが200の際に、
instance-action
の内容を一時ファイルに書き込み、s3にコピーする
中断時のバックアップを想定した軽い検証となります。
環境
FISでスポットインスタンスを停止出来る環境を使用します。Terraformで再現可能です。
事前準備
s3の準備
ファイル格納用のs3を用意します。
特に言及することはありません。
instance-action
の理解
メタデータ中断通知のありなしで応答する内容が異なります。
中断通知なし
エラーメッセージ、ステータスコード404が返却されます。
$ TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/spot/instance-action
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
中断通知あり
中断予定時間、ステータスコード200が返却されます。
この場合2023年6月9日10時27分17秒にスポットインスタンスが中断されます。
$ TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/spot/instance-action
{"action":"terminate","time":"2023-06-09T01:27:17Z"}
シェルスクリプトの準備
今回はcronを作成せずに、シェルスクリプトを実行・常駐するスタイルにしました。
(cronで5秒おき実行はできるのかな?)
#!/bin/bash
export s3bucket="testbucket-20230609"
while true; do
TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
response=$(curl -s -w "%{http_code}" -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/spot/instance-action)
http_code=${response:(-3)}
if [ "$http_code" == "200" ]; then
instance_action=${response:0:${#response}-3}
echo $instance_action > /tmp/instance-action.txt
aws s3 cp /tmp/instance-action.txt s3://${s3bucket}/
break
fi
sleep 5
done
instance-action
の応答するステータスコードが200であれば、その内容をs3にコピーします。
ステータスコードが404
であれば、中断通知が来ていないということで特に何もしません。
準備が出来たらスポットインスタンスでスクリプトを実行します。
$ vi spot-notice.sh
$ chmod 700 spot-notice.sh
$ ./spot-notice.sh
動作確認
FISでスポットインスタンスへ中断通知を送ります。
s3に中断予定時間の書かれたファイルが転送されればOKです
参考
Discussion