ALBのヘルスチェックに失敗したターゲットを特定する方法

2022.03.11

困っていた内容

ALB のヘルスチェックに失敗したターゲットと失敗した理由を知りたいのですが、確認する方法はありますか?

どう対応すればいいの?

AWSのブログにこの方法が書いてありました

このブログによると、ターゲットがELBヘルスチェックの失敗で CloudWatch アラームがトリガーされ、
そのアラームアクションがSNS 通知を送信して Lambda 関数を実行する。

ということらしいです。

実際に試してみるのが良さそうなので、本記事ではこちらの内容を基に実際に試してみたいと思います。

因みに、上記 AWS ブログ内には CloudFormation テンプレートも用意されておりましたので、そちらを活用することも有用です。

1. IAM ポリシーの作成

先ずは Lambda 関数に必要なアクセス許可を与える IAM ポリシーを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LambdaLogging",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SNS",
            "Action": [
                "sns:Publish"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "EC2",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:Describe*",
                "ec2:AttachNetworkInterface",
                "ec2:DeleteNetworkInterface"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "ELB",
            "Action": [
                "elasticloadbalancing:Describe*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "CW",
            "Action": [
                "cloudwatch:putMetricData"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

2. IAM ロールの作成

続いて IAM ロールを作成していきます。

ユースケースで Lambda を選択します。

先ほど作成した IAM ポリシーをアタッチします。

3. 1つ目の SNS トピックの作成

CloudWatchアラームのアクションをトリガーとして送信される SNS トピックを作成します。
この SNS をトリガーとして Lambda 関数を実行します。

4. 2つ目の SNS トピックの作成

次に、unhealthy を検知したことを通知するための SNS トピックを作成します。
こちらは、通知先に通知をしたいメールアドレスを設定しておきます。

5. CloudWatch アラームの作成

2つ目の SNS トピックに通知を送信するための CloudWatch アラームアクションを設定します。

すべて > ApplicationELB > AppELB 別、TG 別メトリクス で
取得したいロードバランサーの [UnHealthyHostCount]を選択します。

条件を設定していきます。
UnHealthyHostCountが1分で1以上をカウントするとアラームがトリガーされるように設定しています。
この条件は要件に併せて変更してください。

通知先に、Lambda トリガー用として作成した、1つ目の SNS トピックを指定します。

6. Lambda 関数の作成

Python で Lambda を作成していきます。
この時、1.で作成した IAM ロールを指定します。

7. Lambda 関数の設定

ランタイム設定でハンドラを「identifying_unhealthy_targets.lambda_handler」に設定します。

次に「アップロード元」をクリックし、下記参考 AWS ブログからダウンロードした zip ファイルをアップロードします。

Identifying unhealthy targets of Elastic Load Balancer | Networking & Content Delivery

The Lambda function zip package is available here. Let’s dive in!

トリガーを追加で3.で作成した SNS トピックを指定します

設定 > 環境変数 で以下の環境変数を追加します

ONDEMAND_HEALTHCHECK – Lambda関数が異常なターゲットを検出したときに、ヘルスチェックリクエストを送信する必要があるかどうか
SNS_TOPIC –4.で作成した SNS トピックの ARN
TARGETGROUP_ARN –ターゲットグループのARN
TARGETGROUP_TYPE –ターゲットグループのタイプ
NAMESPACE – ELBの名前空間(AWS/ELB , AWS/ApplicationELB , AWS/NetworkELBなど)

8. 検証

さて、それではこれで設定が完了したので動作するか検証してみたいと思います。

現在、テスト環境として用意した ALB 配下のターゲットグループにはインスタンスが1台登録されています。

ヘルスチェックのパスに指定しているファイルを削除して unhealthy の状態にした後しばらく待ちます。

メールが来ました。

ヘルスチェックに失敗したインスタンス名と失敗の理由が確認出来ますね。

最後に

ヘルスチェック失敗したインスタンスと理由が特定できれば、異常が発生した際の原因調査の助けになります。

是非ご活用ください。

参考資料

Identifying unhealthy targets of Elastic Load Balancer | Networking & Content Delivery