AWS CLI で ELB 配下のインスタンスをローリングデプロイする方法は去年にまとめた.aws elb deregister-instances-from-load-balancer
と aws elb register-instances-with-load-balancer
を使うだけじゃなく,aws elb describe-instance-health
を使って waiter を実装した点がポイントだった.ちなみに EC2 だと waiter を実装する必要はなく aws ec2 wait
で完了を待つことができる.
ALB の場合 aws elbv2
を使う
1年が経過し,今度は ALB 配下のインスタンスをローリングデプロイしようと考えていて,調べたところ ALB の場合は aws elbv2
を使う必要があった.さらに,ターゲットグループなど ELB とは違う概念があるため,サブコマンドもオプションも異なっていた.
ドキュメント
今回,以下の3コマンドを使った.
aws elbv2 deregister-targets
aws elbv2 register-targets
aws elbv2 describe-target-health
オプションは --target-group-arn
にターゲットグループの ARN を指定し,--targets
にインスタンス ID を指定する.ただし --targets
に指定するときはフォーマットが決まっているため,以下のようにする.なお,ポートは省略することができる.
Id=string,Port=integer …
ALB のステータス
ELB は InService
と OutOfService
のステータスしか存在しなかったが,ALB の場合はもっと多くある.
initial
healthy
unhealthy
unused
draining
ALB から deregister すると healthy → draining → unused
と遷移する.register すると unused → initial → healthy
と遷移する.unhealthy
はヘルスチェックに失敗したときに出るため,通常 deregister / register をするときには出ない.
(正確に言うと他の遷移もあると思う)
ALB ターゲットグループのドレインに注意する
ターゲットグループのデフォルトのドレインは 300 秒に設定されているため,deregister すると,毎回 300 秒 draining
のままになる.アプリケーションの特性次第だけど,基本的には長いと思うので,30 秒などに短くした方が良いと思う.
ドレインに関しては前に検証した記事が参考になると思う.
aws_utils.sh
共通機能は去年と同じで ALB を操作する部分を追加した.
#!/bin/sh # ALB の状態を確認する間隔(秒) SLEEP=3 ####################################### # AWS CLI をチェックする ####################################### check_awscli() { if ! which aws >/dev/null; then echo 'awscli not found' exit 2 fi } ####################################### # ホスト名からインスタンス ID を取得する # Arguments: # $1 HOST NAME # Returns: # INSTANCE ID ####################################### get_instance_id() { instance_id=$(/usr/bin/aws ec2 describe-instances --filter "Name=tag:Name,Values=$1" --query Reservations[].Instances[].InstanceId --output text) if [ -z "$instance_id" ]; then echo 'host not found' exit 2 fi echo ${instance_id} } ####################################### # インスタンスが ALB に反映されるまで待機する # https://docs.aws.amazon.com/cli/latest/reference/elbv2/describe-target-health.html # Arguments: # $1 TARGET GROUP ARN # $2 INSTANCE ID # $3 STATE (healthy or unused) ####################################### alb_waiter() { while : do # 状態(healthy or unused)を取得する state=$(/usr/bin/aws elbv2 describe-target-health --target-group-arn $1 --targets Id=$2 --query TargetHealthDescriptions[].TargetHealth.State --output text) if [ "$3" = "${state}" ]; then echo " TargetGroupARN: $1 InstanceId: $2 State:$3" break else echo " TargetGroupARN: $1 InstanceId: $2 State:$state" fi sleep ${SLEEP} done } ####################################### # ALB からインスタンスを外す # https://docs.aws.amazon.com/cli/latest/reference/elbv2/deregister-targets.html # Arguments: # $1 TARGET GROUP ARN # $2 INSTANCE ID ####################################### alb_deregister() { /usr/bin/aws elbv2 deregister-targets --target-group-arn $1 --targets Id=$2 > /dev/null } ####################################### # ALB にインスタンスを付ける # https://docs.aws.amazon.com/cli/latest/reference/elbv2/register-targets.html # Arguments: # $1 TARGET GROUP ARN # $2 INSTANCE ID ####################################### alb_register() { /usr/bin/aws elbv2 register-targets --target-group-arn $1 --targets Id=$2 > /dev/null }
start.sh
汎用的に書くとこのようになる.
#!/bin/sh # スクリプトをインポートする . ./aws_utils.sh # コマンドチェックと定数の設定 check_awscli ALB_TARGET_GROUP_ARN ='arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222' HOSTS=(web01 web02) for host in ${HOSTS[@]} do # インスタンス ID を取得する INSTANCE_ID=$(get_instance_id ${host}) # unused になるまで待機 echo " deregister : ${INSTANCE_ID}" alb_deregister ${ALB_TARGET_GROUP_ARN} ${INSTANCE_ID} alb_waiter ${ALB_TARGET_GROUP_ARN} ${INSTANCE_ID} 'unused' # # ホストごとにデプロイなどを実行する # # healthy になるまで待機 echo " register : ${INSTANCE_ID}" alb_register ${ALB_TARGET_GROUP_ARN} ${INSTANCE_ID} alb_waiter ${ALB_TARGET_GROUP_ARN} ${INSTANCE_ID} 'healthy' done
実行すると,以下のように waiter をして,期待通りに動く.
deregister : i-xxxxxxxx TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:unused register : i-xxxxxxxx TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:healthy deregister : i-xxxxxxxx TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:draining TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:unused register : i-xxxxxxxx TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:initial TargetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-1:111111111111:targetgroup/xxxxx/2222222222222222 InstanceId: i-xxxxxxxx State:healthy
まとめ
- ELB (
elb
) と ALB (elbv2
) では AWS CLI のサブコマンドが異なる - オプションも異なる
- ALB ターゲットグループのドレインに注意する
aws elbv2 describe-target-health
を使って waiter を実装すると正確に状態を把握しながら deregister / register ができる