Auto ScalingライフサイクルフックによるAWSプロセス監視設計|put-lifecycle-hookと終了処理構成

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > AWS(Amazon Linux) > Auto ScalingライフサイクルフックによるAWSプロセス監視設計|put-lifecycle-hookと終了処理構成
「スケールインのタイミングで、まだ処理中のリクエストが切れてしまう」
Auto ScalingでEC2インスタンスを削除するとき、デフォルト設定では即座に終了処理が始まります。

HTTPリクエストを受け付けているインスタンスが突然消えると、クライアントにエラーが返ります。コネクションを安全にドレインさせる猶予を挟む仕組みが「ライフサイクルフック」です。

この記事では、aws autoscaling put-lifecycle-hookコマンドでスケールイン時のプロセス監視を設計する方法を解説します。接続ドレインの確認スクリプトと、complete-lifecycle-actionによる完了通知の手順まで取り上げます。
Amazon Linux 2023とAWS CLI v2を想定環境として説明します。

この記事のポイント

・ aws autoscaling put-lifecycle-hookでTerminatingフックを作成できる
・ heartbeat-timeoutでドレインの猶予時間を秒単位で指定する
・ ss -tnで確立済み接続数を確認してからcomplete-lifecycle-actionを呼ぶ
・ IAMロールにCompleteLifecycleAction権限がないとエラーになる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜライフサイクルフックが必要なのか

Auto Scalingは、CPUや接続数のメトリクスに応じてEC2インスタンスの台数を自動で増減させます。
スケールアウトはインスタンスを追加するため問題は少ないですが、スケールインでは稼働中のインスタンスを削除します。

デフォルト動作では、削除対象になったインスタンスはすぐに「Terminating」状態に遷移し、プロセスが終了します。
HTTPSの通信中にインスタンスが消えると、クライアントはエラーを受け取ります。

ライフサイクルフックを使うと、「Terminating:Wait」という待機状態を挟めます。この猶予時間の間に、プロセスの終了確認やコネクションのドレインを実行できます。

ライフサイクルフックには2種類あります。
・ INSTANCE_LAUNCHING: インスタンスがサービスイン前の準備に使う
・ INSTANCE_TERMINATING: インスタンス削除前の終了処理に使う

プロセス監視の文脈では「INSTANCE_TERMINATING」を使います。

ライフサイクルフックを設定する(put-lifecycle-hook)

1. Terminatingフックを作成する

Auto ScalingグループにTerminatingフックを設定するコマンドを確認してください。

# Terminatingライフサイクルフックを作成する aws autoscaling put-lifecycle-hook \ --lifecycle-hook-name drain-hook \ --auto-scaling-group-name my-asg \ --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \ --heartbeat-timeout 300 \ --default-result CONTINUE

各パラメータの意味を整理します。
・ --lifecycle-hook-name: フック名(同じASG内で一意にする)
・ --lifecycle-transition: トリガーのタイミング(LAUNCHING or TERMINATING)
・ --heartbeat-timeout: 待機の最大秒数(デフォルト3600秒。300秒が一般的)
・ --default-result: タイムアウト時の動作(CONTINUEで終了処理を続行。ABANDONは中断)

2. 設定内容を確認する

作成したフックは次のコマンドで確認できます。

# ライフサイクルフックの一覧を取得する aws autoscaling describe-lifecycle-hooks \ --auto-scaling-group-name my-asg

出力例(環境により異なります):

{ "LifecycleHooks": [ { "LifecycleHookName": "drain-hook", "AutoScalingGroupName": "my-asg", "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING", "HeartbeatTimeout": 300, "GlobalTimeout": 7200, "DefaultResult": "CONTINUE" } ] }

GlobalTimeoutはheartbeat-timeoutを繰り返して延長できる上限です。300秒で最大24回延長でき、合計7200秒(2時間)まで待機できます。

プロセス監視スクリプトの設計

ライフサイクルフックが発火すると、設定済みのSNSトピックかSQSキューに通知が届きます。
その通知を受けて、インスタンス上でドレインスクリプトを実行し、完了後にcomplete-lifecycle-actionを呼び出します。

1. SQSキューへ通知先を設定する

フックとSQSを連携させるには、put-lifecycle-hookに通知先のARNを追加します。

# SQSキューを通知先に指定する aws autoscaling put-lifecycle-hook \ --lifecycle-hook-name drain-hook \ --auto-scaling-group-name my-asg \ --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \ --heartbeat-timeout 300 \ --default-result CONTINUE \ --notification-target-arn arn:aws:sqs:ap-northeast-1:123456789012:lifecycle-queue \ --role-arn arn:aws:iam::123456789012:role/AutoScalingNotificationRole

IAMロール(AutoScalingNotificationRole)にはSQSの送信権限(sqs:SendMessage)が必要です。

2. 接続ドレインを確認するスクリプト

インスタンス上で動作するドレインスクリプトの例を示します。ssコマンドで確立済みの接続数を確認し、ゼロになったら完了通知を送ります。

ssコマンドを使ったポート確認の基本についてはLinux ポート確認の全コマンドで詳しく解説しています。

#!/bin/bash # ライフサイクルフック用ドレインスクリプト # 保存先例: /usr/local/bin/lifecycle-drain.sh HOOK_NAME="drain-hook" ASG_NAME="my-asg" INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) MAX_WAIT=240 ELAPSED=0 # 確立済みのTCP接続数を確認する(最大MAX_WAIT秒待機する) while [ "$ELAPSED" -lt "$MAX_WAIT" ]; do CONN=$(ss -tn state established | grep -E ':80|:443' | wc -l) if [ "$CONN" -eq 0 ]; then break fi sleep 5 ELAPSED=$((ELAPSED + 5)) done # ライフサイクルアクションを完了する aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "$HOOK_NAME" \ --auto-scaling-group-name "$ASG_NAME" \ --lifecycle-action-result CONTINUE \ --instance-id "$INSTANCE_ID"

スクリプトのポイントをまとめます。
・ ss -tn state established: 確立済みのTCPコネクションを取得する
・ MAX_WAIT: heartbeat-timeout(300秒)より短くして完了通知が遅れないようにする
・ complete-lifecycle-action --lifecycle-action-result CONTINUE: 終了処理を続行する

3. complete-lifecycle-actionで完了を通知する

ドレインが完了したら、必ずcomplete-lifecycle-actionを呼ぶ必要があります。
呼ばない場合はheartbeat-timeoutが経過し、default-resultの設定に従います。

# CONTINUE: インスタンス終了を続行する aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name drain-hook \ --auto-scaling-group-name my-asg \ --lifecycle-action-result CONTINUE \ --instance-id i-0abc12345678defgh # ABANDON: ライフサイクルアクションを中断する(緊急停止やデバッグ時に使う) aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name drain-hook \ --auto-scaling-group-name my-asg \ --lifecycle-action-result ABANDON \ --instance-id i-0abc12345678defgh

ABANDONはデバッグや緊急停止に使います。本番のドレインが正常に終わった場合はCONTINUEを指定してください。

AWSセミナーでの実践的な構成パターンについて

大規模な構成では、SNSとEventBridgeを組み合わせる設計が使われます。
SNSトピックを経由してLambdaがSSM Run Commandを呼び出し、インスタンス上でドレインスクリプトを実行するパターンが代表的です。

SQSポーリング方式(先に紹介した方法)と比較すると、次の違いがあります。

・ SQSポーリング方式: インスタンス自身がキューを監視する。シンプルな構成に向く
・ SNS + Lambda方式: 中央管理のLambdaがドレイン処理を制御する。複数ASGを一元管理できる

AWSの実践的な構成設計についてはAWSセミナー(Amazon Linux対応)でも取り上げています。

よくある問題と対処法

1. heartbeat-timeoutが切れてインスタンスが強制終了する

ドレインスクリプトの実行時間がheartbeat-timeoutを超えると、default-resultに従って処理が進みます。
CONTINUEに設定している場合はインスタンスが終了します。長時間のドレインが予想される場合は、ハートビートを延長してください。

# ハートビートを延長する(GlobalTimeoutまで繰り返し延長できる) aws autoscaling record-lifecycle-action-heartbeat \ --lifecycle-hook-name drain-hook \ --auto-scaling-group-name my-asg \ --instance-id i-0abc12345678defgh

2. complete-lifecycle-actionでIAM権限エラーになる

EC2インスタンスのIAMロールに次の権限が必要です。

・ autoscaling:CompleteLifecycleAction
・ autoscaling:RecordLifecycleActionHeartbeat

インスタンスプロファイルに上記のアクションを追加してください。

本記事のまとめ

やりたいこと コマンド
Terminatingフックを作成する aws autoscaling put-lifecycle-hook --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING
フック設定を確認する aws autoscaling describe-lifecycle-hooks --auto-scaling-group-name 名前
フック完了を通知する aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE
ハートビートを延長する aws autoscaling record-lifecycle-action-heartbeat --lifecycle-hook-name フック名
確立済みTCP接続数を確認する ss -tn state established | grep -E ':80|:443' | wc -l
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、まずはAWSセミナーの詳細をご確認ください。
>>AWSセミナー(Amazon Linux対応)の詳細と申し込み

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。