EC2 Auto Scaling グループの「ヘルスチェックの猶予期間」を正しく理解する

2019.05.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西澤です。今回、ELB配下のEC2 Auto Scaling グループにおいて、"ヘルスチェックタイプ=ELB"とした際の「ヘルスチェックの猶予期間(Grace Priod)」の挙動について、正しく理解できてていなかったので、まとめておきたいと思います。

「ヘルスチェックの猶予期間」について調査した経緯

ELB配下のEC2 Auto Scaling グループにて、高負荷時のみインスタンス数を自動スケールさせて負荷分散している環境で、スケールアウト(台数増)のタイミングで毎度CloudWatchからUnHealthyHostCountのアラートが発生していることが判明し、調査を行いました。

まず、2台ずつスケールアウトするスケーリングポリシーが設定されていたので、直近のスケールアウトによるLaunch時刻を確認しました。

$ aws autoscaling describe-scaling-activities \
--query "Activities[?AutoScalingGroupName==\`${ASGNAME}\`].[StartTime,EndTime,Description]" \
--output text
:::
2019-05-28T03:38:36.247Z 2019-05-28T03:39:09Z Launching a new EC2 instance: i-039f1519XXXXXXXXX
2019-05-28T03:38:36.247Z 2019-05-28T03:39:09Z Launching a new EC2 instance: i-0b958d7eXXXXXXXXX
2019-05-28T03:43:10.535Z 2019-05-28T03:43:43Z Launching a new EC2 instance: i-004c2a14XXXXXXXXX
2019-05-28T03:43:10.535Z 2019-05-28T03:43:43Z Launching a new EC2 instance: i-083589e5XXXXXXXXX

Launchされた直後にALB TargetGroupのメトリクスにて、UnHealthyHostCountがカウントされていることを確認しました。

$ aws cloudwatch get-metric-statistics \
--namespace "AWS/ApplicationELB" \
--dimensions Name=LoadBalancer,Value=app/${ALBNAME}/${ALBID} Name=TargetGroup,Value=targetgroup/${TGTNAME}/${TGTID} \
--metric-name UnHealthyHostCount \
--statistics "Average" \
--start-time "2019-05-28T03:30:00Z" \
--end-time "2019-05-28T03:50:00Z" \
--period 60 \
--query "sort_by(Datapoints,&Timestamp)[?Average>\`0\`].[Timestamp,Average]" \
--output text
:::
2019-05-28T03:39:00Z 2.0
2019-05-28T03:44:00Z 2.0

本環境について、もう少しだけ補足しておきます。

  • 新規インスタンスがLaunchすると、ユーザデータから初期設定を行っているが、その処理に1分程度かかっている
  • Auto Scalingグループ設定は、ヘルスチェックのタイプ=ELBかつヘルスチェックの猶予期間=120

想定では、ヘルスチェックの猶予期間を十分に大きくすれば、ユーザデータから実行される初期設定のスクリプトの処理時間がそれを超えない限り、UnHealthyHostCountは発生しないだろうと考えていました。そこで、猶予期間をさらに長く設定することも試したのですが、結果としてはUnHealthyHostCountが無くなることはありませんでした。

「ヘルスチェックの猶予期間」の仕様とは?

公開ドキュメントだけでは、わからなかった為、AWSサポートにも確認を取ったところ、ヘルスチェックのタイプ=ELBヘルスチェックの猶予期間は、あくまでAuto Scalingのヘルスチェック猶予であり、ELBヘルスチェックの猶予では無いということがわかりました。

今回のケースについて、実際にどんな流れになっていたかと言うと、以下であることがわかりました。

  1. Auto Scalingから新しいEC2がLaunchされ、ステータスOKに
  2. Auto Scalingヘルスチェックは猶予期間に入る(※今回の設定では120s)
  3. ELB配下に移動(※今回のケースではALBに紐づくTargetGroup)、ELBヘルスチェック開始→NGなのでUnHealthyと判定される ※ここでアラートが発生していた
  4. ユーザデータから実行された初期設定が完了、ELBヘルスチェックOKに遷移し、Healthyと判定され、ELB経由でのサービス提供開始
  5. 猶予期間終了(120s経過)し、Auto Scalingヘルスチェック開始(※異常があればAuto Scalingからのterminate対象となる)

まとめ

正確な理解をしていなかった為、調査に手間取ってしまいましたが、ようやく正確に理解することができました。ということで、ELB配下でAuto Scalingを構成する場合には、ELB側のUnHealthyHostCountを利用するのではなく、Auto Scaling Groupが持っているGroupTerminatingInstancesメトリクスを利用した監視がオススメとのことです。

どこかの誰かのお役に立てば嬉しいです。