ELB配下のEC2を一定確率で安全にシャットダウンする
やること
ELB配下のEC2インスタンスを
- 一定確率以上で
- 安全に(ELBからのトラフィックをこぼすことなく)
シャットダウンします
用途
- 長時間起動しているとメモリリークするアプリケーションのワークアラウンド
- 何らかの理由でEC2のIPを変更したい
- 何らかの理由でEC2を1から立て直したい(ElasticBeanstalk環境のみの話ですが)
他にもなにかあれば教えてください!
環境
- ALB
- EC2(Amazon Linux)
- bash
- aws-cli
- ElasticBeanstalk
- jq
結論
このシェルをEC2インスタンスのcronに仕込めばn%の確率でシャットダウンします。
random_shutdown.sh
# !/bin/sh -vx
# Configuration
PERCENTAGE=5
SHUTDOWN_WAIT_TIME=300
# Execute with a probability of n% or more.
if [ $(($RANDOM % 100)) -lt $PERCENTAGE ]; then
# Get instance-id(myself) and loadblancer-name
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
LB_NAME=`aws elb describe-load-balancers --region ap-northeast-1 |jq -r '.LoadBalancerDescriptions[] | select( .Instances[].InstanceId == "'${INSTANCE_ID}'") |.LoadBalancerName'`
echo My instance-id is ${INSTANCE_ID}
echo My loadbalancer-name is ${LB_NAME}
# Deregister ec2instance(myself)
aws elb deregister-instances-from-load-balancer --region ap-northeast-1 --load-balancer-name ${LB_NAME} --instances ${INSTANCE_ID}
# Terminate myself
sleep $SHUTDOWN_WAIT_TIME
shutdown -h now;
fi
説明
1. Randomに処理をするかどうか決める部分
if [ $(($RANDOM % 100)) -lt $PERCENTAGE ]; then
# 行いたい処理
fi
シェルスクリプトでは、$RANDOMを参照すると 0~32767の乱数を取得できる。
100で割った余りを求めることで(0 ~ 99)の数を取得することができる。
乱数が事前に指定した値($PERCENTAGE)より低い範囲だった場合とする事で、指定確率で処理を実行できます。
2. meta-dataから自身のinstance-idを取得する
# Get instance-id(myself) and loadblancer-name
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
- meta-dataからELBの名前を取得する
LB_NAME=`aws elb describe-load-balancers --region ap-northeast-1 |jq -r '.LoadBalancerDescriptions[] | select( .Instances[].InstanceId == "'${INSTANCE_ID}'") |.LoadBalancerName'`
jqについてはこちらが参考になります。
3. EC2(自分自身)をELBから切り離す
aws elb deregister-instances-from-load-balancer --region ap-northeast-1 --load-balancer-name ${LB_NAME} --instances ${INSTANCE_ID}
EC2のロールには適切なポリシー(elasticloadbalancing:DeregisterTargets)を付与しておく必要があります。
4.shutdownコマンドでEC2インスタンスを落とす
# Terminate myself
sleep $SHUTDOWN_WAIT_TIME
shutdown -h now;
EC2インタンス上での処理が終わるまで、一定時間待ってから落とします。
終わりに
小ネタですが、Qiita初投稿してみました。
これからもちょこちょこあげていこうと思います。