Application Load Balancer (ALB) は、ヘルスチェックを使用してバックエンドサーバーの可用性を判断します。サーバーがヘルスチェックに失敗すると、ALB は自動的に新しいリクエストを他の正常なサーバーにルーティングします。これにより、個別のサーバーの問題によるサービスの中断を防ぎ、高可用性を確保します。
問題の説明
ALB インスタンスのリスナーの ヘルスチェックステータス が 異常 になります。
原因
初期設定後にヘルスチェックが失敗する場合、 原因は設定エラーである可能性が高いです:
-
ヘルスチェックパラメーターの誤り
-
ヘルスチェックポートの問題
以前は成功していたヘルスチェックが失敗し始めた場合、 問題はバックエンドサーバーにある可能性が高いです:
-
セキュリティソフトウェアの干渉
-
不正なルート設定
-
バックエンドサーバーの高負荷 (システムリソースの過負荷や接続リークによるリソース枯渇を含む)
ソリューション
初期設定時のヘルスチェックの失敗
原因1:ヘルスチェックパラメーターの誤り
- ALBコンソールにログインします。
-
トップメニューバーで、ALB インスタンスが配置されているリージョンを選択します。
-
左側メニューで、ALB > サーバーグループ を選択します。
-
サーバーグループ ページで、対象の ALB インスタンスにアタッチされているサーバーグループを見つけ、サーバーグループ ID をクリックします。
-
サーバーグループの詳細ページで、ヘルスチェック タブをクリックし、ヘルスチェックの変更 セクションで [ヘルスチェックの変更] をクリックします。
-
ヘルスチェックの変更 ダイアログボックスで、ヘルスチェックパラメーターを確認します。デフォルト値を使用することを推奨します。
原因2:ヘルスチェックポートの問題
- ALBコンソールにログインします。
-
トップメニューバーで、ALB インスタンスが配置されているリージョンを選択します。
-
左側メニューで、ALB > サーバーグループ を選択します。
-
サーバーグループ ページで、対象の ALB インスタンスにアタッチされているサーバーグループを見つけ、サーバーグループ ID をクリックします。
-
サーバーグループの詳細ページで、バックエンドサーバー タブをクリックして、バックエンドサーバーのポートを表示および記録します。
-
サーバーグループの詳細ページで、詳細 タブをクリックし、ヘルスチェック セクションで ヘルスチェックの変更 をクリックします。ヘルスチェックの変更 ダイアログボックスで、ヘルスチェックパラメーターを表示および記録します。
-
バックエンドサーバーにログインし、
ncまたはcurlコマンドを使用してサーバーをプローブします。# nc コマンド: echo -e "[$Method] [$PATH] [$VERSION]\r\nHost: [$Domain]\r\n\r\n" | nc -t [$IP] [$Port] # フォーマット echo -e "HEAD /index.html HTTP/1.0\r\nHost: www.example.org\r\n\r\n" | nc -t 127.0.0.1 80 # 例 # curl コマンド: curl -X [$Method] -H "Host: [$Domain]" -I http://[$IP]:[$Port][$PATH] # フォーマット curl -X HEAD --http1.0 -H "Host: www.example.org" -I http://127.0.0.1:80/index.html # 例説明-
[$Method]は、サーバーグループに設定されたヘルスチェックメソッドです。 -
[$PATH]は、サーバーグループに設定されたヘルスチェックパスです。 -
[$VERSION]は、ヘルスチェックに使用される HTTP バージョンです (例: HTTP/1.0)。 -
[$Domain]は、ヘルスチェックに設定されたドメイン名です。この値が-----の場合、デフォルトで各バックエンド ECS インスタンスのプライベート IP アドレスが使用されます。この場合、代わりに[$IP]を使用できます。 -
[$IP]は、バックエンド ECS インスタンスのプライベート IP アドレスです。 -
[$Port]は、サーバーグループに設定されたヘルスチェックポートです。ヘルスチェックポートが手動で設定されていない場合、デフォルトでバックエンド ECS インスタンスのポートが使用されます。ヘルスチェックポートが設定されている場合は、設定されたヘルスチェックポートが使用されます。
-
-
返されたステータスコードが、サービスにとって正常なレスポンスを示しているかどうかを確認します。
-
ステータスコードは正常ですが、設定された正常なステータスコードに含まれていない場合は、ヘルスチェック設定に追加します。
-
ステータスコードがエラーを示している場合は、次の表を使用してトラブルシューティングを行います。
ステータスコード
説明
トラブルシューティング
400
不正なリクエストです。通常、不正な形式の HTTP リクエスト、ヘルスチェックプロトコルとバックエンドサービスの不一致、または常に 400 ステータスコードを返すビジネスロジックが原因です。
以下の項目を1つずつ確認します:
-
不正な形式の HTTP ヘッダー (例:空の Content-Length ヘッダー)。HTTP リクエストの形式を確認します。
-
ヘルスチェックプロトコルがバックエンドサービスと一致していません (例:HTTPS ポートに対して HTTP ヘルスチェックプロトコルが使用されている)。正しいヘルスチェックプロトコルを使用します。
-
ビジネスロジック自体が常に 400 などの 4xx ステータスコードを返す場合、ヘルスチェック設定の [ヘルスチェックステータスコード] で [http_4xx] を選択し、4xx ステータスコードを正常なレスポンスとして扱います。これにより、特定のビジネスリターンコードが原因でバックエンドノードがヘルスチェックによって削除されるのを防ぎます。
警告正常なコードとして 4xx または 5xx ステータスコードを追加すると、異常なインスタンスが時間内に削除されなくなる可能性があります。まず、バックエンドサービスが正しい 2xx または 3xx ステータスコードを返すことを確認してください。
403
アクセスが禁止されています。通常、バックエンドの Web サービス設定が原因です。
バックエンドサービス (例: Nginx や Tomcat) に、特定の送信元 IP アドレスまたはリクエストパターンからのリクエストをブロックするアクセス制御ルールがあるかどうかを確認します。バックエンドがヘルスチェックリクエストの送信元をブロックしている場合、ヘルスチェックは継続的に 403 を返します。バックエンドサービスのアクセス制御設定を調整して、ヘルスチェックリクエストを許可します。
404
ターゲットリソースが見つかりません。通常、ヘルスチェックパスとバックエンドサーバーで実際に利用可能なパスの不一致が原因です。
次のようにトラブルシューティングを行います:
-
バックエンドゲートウェイ (例: Nginx) によって公開されているパスプレフィックス (例:
/api/v1) を確認し、設定した [ヘルスチェックパス] がバックエンドで実際にアクセス可能なパスと一致していることを確認します。 -
バックエンドサーバーの IP への直接アクセスでは正常なレスポンスが返されるが、ドメイン名経由のアクセスでは 404 が返される場合、通常、バックエンドサービスはドメイン名 (Host ヘッダー) に基づいて仮想ホストのマッチングを行っています。ヘルスチェックに設定された [ヘルスチェックドメイン] が、バックエンドサービスのドメイン設定と一致していることを確認します。
405
ヘルスチェックリクエストのメソッドがサポートされていません。
バックエンドサービスが、設定されたヘルスチェックメソッドをサポートしているかどうかを確認します。
500
内部サーバーエラーが発生し、リクエストを完了できません。
バックエンドサービスのビジネスロジックを確認します。
503
サーバーは一時的に利用できません。
バックエンドサービスのビジネスロジックを確認するか、サーバーの負荷が高すぎるかどうかを判断します。
-
-
既存の設定でのヘルスチェックの失敗
原因1:セキュリティソフトウェアの干渉
-
デフォルトでは、アップグレードされた ALB インスタンスは、vSwitch のネットワークセグメントのプライベート IP アドレス (ローカル IP) を使用して、バックエンドの ECS インスタンスと通信します。バックエンドの ECS インスタンスが、iptables やその他のセキュリティソフトウェアなどによって ALB インスタンスのローカル IP をブロックしていないことを確認してください。ローカル IP は、ALB コンソールのインスタンス詳細ページで確認できます。
-
アップグレード前、ALB インスタンスは 100.64.0.0/10 を使用してバックエンド ECS インスタンスと通信します。 バックエンド ECS インスタンスでは、iptables または他のセキュリティソフトウェアによってこの CIDR ブロックがブロックされないようにしてください。
ALB は、予約済み CIDR ブロックの IP アドレスを使用してバックエンド ECS インスタンスと通信します。 この ALB インスタンスの CIDR ブロックがブロックされると、ヘルスチェックが失敗し、ALB は正常に動作できなくなります。 次の例では、iptables を使用して 100.64.0.0/10 のブロックを確認します。
-
影響を受けるバックエンドの ECS インスタンスにログインし、次のコマンドを実行してフィルターテーブルのルールを一覧表示します。
iptables -nL以下のような出力は、バックエンド ECS インスタンスが ALB CIDR ブロックからのリクエストをブロックしていることを示しています。
[root@xxx Z ~]# iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- 100.64.0.0/10 0.0.0.0/0 Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain L (0 references) target prot opt source destination -
次のコマンドを実行して、このルールを削除します:
iptables -t filter -D INPUT -s 100.64.0.0/10 -j DROP -
ALB CIDR ブロックがブロックされていないことを確認してください:
iptables -nL
iptables のルールに加えて、以下のセキュリティ設定を確認し、ALB のヘルスチェックトラフィックがバックエンドサービスに到達できるようにします:
-
バックエンドサーバーのポートリッスン状態の確認:バックエンドサーバーがサーバーグループで設定されたバックエンドポート (例:ポート 80) でリッスンしていることを確認します。次のコマンドを実行して、ポートのリッスン状態を確認します:
netstat -tlnp | grep <port> # または ss コマンドを使用します: ss -tlnp | grep <port>ポートが LISTEN 状態でない場合は、バックエンドサービスが正常に開始されているかどうかを確認します。
説明Docker や他のコンテナーにデプロイされたバックエンドサービスの場合、到達可能なホストポートは、コンテナー内のサービスがヘルスチェックポートで正しくリッスンしていることを保証するものではありません。ホストポートに到達できてもヘルスチェックが失敗する場合は、コンテナーに入り、サービスがヘルスチェックポート (例:ポート 80) でリッスンしており、リッスンアドレスが
0.0.0.0(だけでなく127.0.0.1) であることを確認します。また、コンテナー内のセキュリティポリシーが ALB のヘルスチェック IP アドレスを制限していないかどうかも確認します。 -
バックエンド ECS セキュリティグループのインバウンドルールの確認:セキュリティグループのインバウンドルールが以下の送信元からのアクセスを許可していることを確認します。許可されていない場合、ALB のヘルスチェックプローブがセキュリティグループによってブロックされる可能性があります:
-
[承認オブジェクト (送信元アドレス)]:アップグレードされた ALB インスタンスの場合は、そのローカル IP が存在する vSwitch の CIDR ブロック。アップグレードされていない ALB インスタンスの場合は、
100.64.0.0/10CIDR ブロック。 -
[プロトコル]:TCP
-
[ポート範囲]:サーバーグループで設定されたバックエンドサービスポートと、使用中のヘルスチェックポート。
-
バックエンドサーバーまたは他のセキュリティソフトウェアで、高頻度のリクエストブロックまたは HTTP フラッド (CC) 防御ポリシーが有効になっているかどうかを確認します。ALB は分散クラスターからヘルスチェックプローブを送信するため、プローブの頻度が高くなる可能性があり、これらのポリシーがプローブを攻撃と誤認して ALB のヘルスチェック IP アドレスをブロックし、ヘルスチェックの失敗につながることがあります。一部のプローブのみがブロックされた場合、ヘルスステータスが正常と異常の間で変動することもあります。
原因2:不正なルート設定
この原因は、アップグレードされていない ALB インスタンスにのみ適用されます。アップグレードされたインスタンスは、vSwitch CIDR ブロックからのプライベート IP (ローカル IP) を使用し、100.64.0.0/10 を経由してルーティングしません。
バックエンド ECS インスタンス上の 100.64.0.0/10 CIDR ブロックのルートが正しくないと、ヘルスチェック応答が ALB インスタンスに到達できなくなる可能性があります。 次の例では、Linux の route コマンドを使用して設定を確認します。
-
バックエンドの ECS インスタンスにログインし、次のコマンドを実行してルート設定を確認します:
route -nDestination が 100.64.0.0 で Genmask が 255.192.0.0 のエントリの Gateway が、NIC のデフォルトゲートウェイ (Destination が 0.0.0.0 の Gateway 値) 以外の場合、ルートは不正です。
[root@test-server2 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 <Default gateway of eth0> 0.0.0.0 UG 100 0 0 eth0 xxx xxx xxx xxx xxx xxx xxx xxx 100.64.0.0 0.0.0.0 255.192.0.0 U 0 0 0 eth0 -
次のコマンドを実行して、100.64.0.0/10 CIDR ブロックの不正なルートを削除します:
route del -net 100.64.0.0/10
原因3:バックエンドサーバーの高負荷
バックエンドの ECS インスタンスのリソースが少なくなると、設定されたタイムアウト内にヘルスチェックプローブに応答できなくなり、ヘルスチェックが失敗することがあります。リソース不足は、システム全体の過負荷、または接続リークなどの特定の問題が徐々にシステムリソースを枯渇させることによって発生する可能性があります。以下の2つのサブシナリオについてトラブルシューティングを行います。
サブシナリオ1:システムリソースの過負荷
CPU、メモリ、またはディスク I/O が飽和状態になると、サーバーはヘルスチェックプローブに時間内に応答できなくなります。サーバーが過負荷状態にあるかどうかを確認するには、「Linux インスタンスの高負荷のトラブルシューティングと対応」をご参照ください。
サブシナリオ2:接続リークによるリソース枯渇 (CLOSE_WAIT の蓄積)
バックエンド ECS インスタンスで TCP CLOSE_WAIT 接続が大量に蓄積される場合、その原因は通常、バックエンドアプリケーション (たとえば、jsvc.exec によって管理される Java サービスなど) がリクエストを処理した後に close() をアクティブに呼び出して接続を解放しないためです。これにより、接続が CLOSE_WAIT 状態のままになり、時間とともに蓄積されます。過剰な CLOSE_WAIT 接続はシステムリソースを消費し、ヘルスチェックの応答に影響を与える可能性があります。
トラブルシューティング手順:
-
バックエンドの ECS インスタンスにログインし、次のコマンドを実行して現在の CLOSE_WAIT 接続数を確認します:
netstat -an | grep CLOSE_WAIT | wc -l -
CLOSE_WAIT 接続の数が増え続けるか、異常に高い場合は、バックエンドアプリケーションのコードまたはサービス設定を確認し、アプリケーションがリクエストの処理後に (たとえば、
close()またはshutdown()を呼び出して) 接続を正しく閉じることを確認してください。接続プールを使用するフレームワークの場合は、プールのアイドルタイムアウトと回収設定を確認してください。
よくある質問
バックエンドサーバーがヘルスチェックリクエストを高頻度で受信するのはなぜですか?
ALB はマルチゾーンの分散クラスターアーキテクチャを使用しています。クラスター内のすべての転送ノードは、独立してバックエンドサーバーにヘルスチェックプローブを送信します。その結果、バックエンドサーバーが受信する実際のヘルスチェックリクエストの頻度は、ノードごとのチェック頻度 × ノード数 に等しくなります。たとえば、ヘルスチェック間隔が 5 秒に設定され、クラスターに 10 個の転送ノードが含まれている場合、バックエンドサーバーは 5 秒ごとに約 10 回のヘルスチェックリクエストを受信し、これは 1 秒あたりほぼ 2 回のリクエストに相当します。これは設計による想定内の動作であり、問題ではありません。
ヘルスチェックプローブの頻度またはバックエンドサーバーへの影響を軽減するには、次の方法を使用します:
-
[ヘルスチェック間隔] を適度に長くして、単位時間あたりのプローブ数を減らします。ただし、間隔を長くすると、異常なノードを検出して削除するために必要な時間が増加し、障害検出の適時性に影響を与える可能性があります。これをビジネスの可用性要件とバランスさせてください。
-
ヘルスチェックプロトコルを TCP (レイヤー 4) ヘルスチェックに変更します:ALB は HTTP リクエストを送信せずに TCP ハンドシェイクのみを実行するため、バックエンドアプリケーションでの各プローブのリソース消費が削減されます。