ALB からの HTTP エラーを迅速にトラブルシューティングするために、ALB アクセスログを有効にすることをお勧めします。まず、アクセスログで ALB の状態コード (status フィールド内) とバックエンドの状態コード (upstream_status フィールド内) を比較します。値が同じ場合、ALB はバックエンドサーバーからの状態コードをパススルーしたと考えられます。この場合、バックエンドサービスのトラブルシューティングを優先する必要があります。
5 つのクイックチェック
状態コード別にトラブルシューティングを行う前に、まず以下の 5 つのチェックを実行してください。これらは ALB の障害で最も一般的な根本原因に対応しています。
-
ALB インスタンス診断ツールを実行します。インスタンス ページで、ターゲットインスタンスを見つけます。インスタンスの診断 列で 診断 をクリックして、インスタンスの構成、リスナー、およびバックエンドサービスに関する一般的な問題をワンクリックでチェックします。
-
リスナーの ヘルスチェックステータス が 正常 であることを確認します。 リスナーの詳細 ページで、バックエンドサーバーグループの ヘルスチェックステータス を確認します。ステータスが 異常 の場合は、「ALB ヘルスチェック失敗のトラブルシューティング」をご参照ください。
-
バックエンド ECS インスタンスが、ALB インスタンスが配置されている VSwitch の CIDR ブロックをブロックしていないことを確認してください。 ALB は、その VSwitch によって割り当てられた Local IP を使用してバックエンドサーバーと通信します。 バックエンド ECS インスタンス上の iptables ルールまたはサードパーティのセキュリティソフトウェアが VSwitch の CIDR ブロックをブロックする場合、ALB はバックエンドに到達できず、502 や 504 などのエラーを引き起こす可能性があります。
-
サーバーグループ内のバックエンドサーバーに設定されているポートが、バックエンドサービスが実際にリッスンしているポートと一致することを確認します。ALB サーバーグループ内の各バックエンドサーバーに設定されているポートは、アプリケーションプロセスがリッスンしているポートと一致する必要があります。たとえば、サーバーグループでポートが
8080として設定されているにもかかわらず、バックエンドサービスがポート80でリッスンしている場合、接続は失敗します。バックエンド ECS でss -tlnp | grep ':<port> 'またはnetstat -tlnp | grep ':<port> 'を実行して確認できます。 -
HTTPS リスナーの場合、証明書が期限切れになっていないこと、およびそのドメインがアクセスドメインと一致することを確認します。 リスナーの詳細 ページで、バインドされた証明書とその有効期限を確認します。 期限切れの証明書またはドメインの不一致は、SSL ハンドシェイクの失敗の原因となったり、エラーステータスコードを返したりすることがあります。
502 Bad Gateway
このエラーは、HTTP または HTTPS リスナーがクライアントリクエストを受信したものの、ALB がリクエストをバックエンドサーバーに転送できなかったり、バックエンドサーバーから応答を受信できなかったりした場合に発生します。
トラブルシューティング方法: まず、アクセスログの upstream_status フィールドの値を確認して、次のステップを判断します。
-
upstream_status= 502 の場合、ALB はバックエンドサーバーからの 502 状態コードを中継します。問題はバックエンドサービス自体にあります。バックエンドサービスを調査してください。たとえば、バックエンドの Nginx またはゲートウェイレイヤーが、到達不能なアップストリームへのリバースプロキシを試みていないか確認してください。 -
upstream_statusが別の値である場合 (たとえば504、444、または500など): ALB がクライアントに返すstatusはupstream_statusとは異なります。これは、ALB が状態コードを変更したことを意味します。バックエンド Nginx、ゲートウェイ、またはアプリケーションログを確認し、バックエンドサービスがその特定の状態コードを返している理由を調査してください。 -
upstream_statusが-または空の場合: ALB はバックエンドから応答を受信していません。これは、リクエストがバックエンドに到達しなかったか、応答が送信される前にバックエンド接続が異常に終了したことを意味します。以下の原因を順番に確認してください。-
ALB とバックエンドサーバー間の TCP 通信が失敗している。バックエンドサービスが実行中であること、サービスポートが正しくリッスンしていること、およびバックエンドの ECS 上の iptables ルールやサードパーティのセキュリティソフトウェアが、ALB インスタンスが配置されている VSwitch の CIDR ブロックをブロックしていないことを確認してください。ALB は、VSwitch によって割り当てられたLocal IP を使用してバックエンドサーバーと通信します。パケットをキャプチャして、TCP ハンドシェイクが成功したかどうかを確認できます。
-
バックエンドサーバーのバックログがいっぱいになっています。これにより、サーバーは新しい接続リクエストをドロップします。バックエンドサーバーで
netstat -s | grep -i listenを実行し、dropカウンターを確認します。 -
バックエンドサーバーが時間内にリクエストを処理できなかった。バックエンドサーバーのログを確認し、CPU とメモリ使用量を見直してパフォーマンスボトルネックを特定します。
-
クライアントリクエストのパケットサイズがバックエンドサーバーの MTU を超えている。これにより、ヘルスチェックなどの短いパケットは成功し、長いパケットは失敗する可能性があります。バックエンドサーバーでパケットキャプチャを実行し、パケット長が必要な制限内にあるか分析します。
-
バックエンドサーバーの応答のフォーマットが無効であるか、無効な HTTP ヘッダーを含んでいる。バックエンドサーバーでパケットキャプチャを実行し、応答フォーマットが標準に準拠しているか分析します。
-
400 Bad Request
リクエストのフォーマットが無効です。
-
バックエンドが直接 400 を返す:アクセスログを確認してください。
upstream_statusが400の場合、ALB がバックエンドからの状態コードを渡した可能性が高いです。バックエンドサービスを調査してください。 -
HTTP リクエストが HTTPS リスナーに送信される: ALB の HTTPS リスナーは、HTTPS ではないリクエストを拒否し、状態コード
400を返します。クライアントが誤って HTTP リクエストを HTTPS ポートに送信していないかどうかを確認してください。 -
リクエストヘッダーのサイズが制限を超えています: ALB では、各 HTTP リクエストヘッダーのサイズは 32 KB 以下である必要があります。この制限を超えた場合、ALB は
400状態コードを返します。リクエストヘッダーのサイズを削減してください。 -
クライアントが完全なリクエストを送信しなかった:クライアントは、完全な HTTP リクエストを送信する前に接続を閉じました。クライアントでパケットキャプチャを実行し、原因を特定します。
-
リクエストヘッダーのフォーマットが無効です:たとえば、
Content-Lengthの値がリクエストボディの実際の長さと一致しません。クライアントでパケットをキャプチャし、HTTP リクエストのフォーマットを分析し、有効なリクエストと比較してください。
405 Method Not Allowed
リクエストメソッドがサポートされていません。
-
ALB による制限: ALB は
TRACEリクエストメソッドをサポートしていません。別のメソッドを使用してください。 -
バックエンドサービスの制限:
TRACEを除き、他のリクエストメソッドがサポートされているかどうかは、バックエンドサーバーに依存します。確認するには、curl -X METHOD http://<backend_service_IP>:<service_port>を実行します。ここで、METHODはクライアントが使用するリクエストメソッドです。
408 Request Timeout
リクエストがタイムアウトし、ALB が接続を閉じます。
-
クライアントのデータ送信が遅い: これは、クライアントから ALB へのリクエストタイムアウト期間 (デフォルト: 60 秒) 内に、クライアントが
HTTP Headerのみ送信してHTTP Bodyは送信しないなど、部分的なデータしか送信しなかった場合に発生します。クライアントでパケットをキャプチャして、パフォーマンスボトルネックやその他の問題がないか確認してください。 -
クライアントと ALB 間のネットワーク品質の低下: TCP ラウンドトリップタイム (RTT) が高い、またはパケット損失などの他のネットワーク問題が発生しています。アクセスログの
request_timeフィールドとtcpinfo_rttフィールドを確認するか、クライアントでネットワーク診断を実行することをお勧めします。 -
ALB インスタンスの帯域幅調整: ALB インスタンスへのトラフィックの急増により、帯域幅調整とパケット損失が発生しました。Cloud Monitor で
アウトバウンド帯域幅およびドロップされた接続数メトリックを確認してください。
414 URI Too Long
リクエスト URI の長さが制限を超え、ALB またはバックエンドサーバーがリクエストを拒否しました。
-
ALB の制限: ALB では、リクエスト URI を 32 KB 以下にする必要があります。 そうでない場合、
414状態コードが返されます。 URI を短縮してください。 大量のデータを送信するには、POSTメソッドを使用し、データをリクエストボディに配置することができます。 ALB は、最大 50 GB のPOSTリクエストボディをサポートします。 -
バックエンドサービスの制限: URI の長さが ALB の制限を超えていないものの、バックエンドサービスにより厳しい制限がある場合、ALB は、バックエンドから返された
414状態コードをパススルーします。バックエンドサービスを調査してください。
463
463 状態コードは、リスナーが IP タイプのサーバーグループに関連付けられている場合にのみ返されます。
リクエストパスにループが存在します。リクエストが ALB を通過すると、システムは HTTP Header に ALICLOUD-ALB-TRACE フィールドを追加します。このフィールド値は、ルール ID から生成された 16 文字のハッシュです。重複したルール ID が検出された場合、または ALICLOUD-ALB-TRACE フィールドの数が 16 を超えた場合、ALB はループがあると判断します。その後、ALB はネットワークストームを防ぐためにリクエストの転送を停止し、状態コード 463 を返します。
-
バックエンドサービスの設定ミス:バックエンドサービスが誤って設定されており、リクエストをループで ALB に送り返しています。ご利用の ALB のバックエンドサービス設定を確認してください。
-
ネットワークアーキテクチャの欠陥:例えば、単一のリクエストの転送パスに複数の SLB インスタンスが存在する場合などです。ネットワークアーキテクチャを最適化することを推奨します。
499 Client Closed Request
クライアントが能動的に接続を閉じました。
-
クライアントと ALB 間のネットワーク品質が悪い:TCP RTT が高い、またはパケット損失などの他のネットワーク問題が存在します。アクセスログで
request_timeおよびtcpinfo_rttフィールドを確認するか、クライアントでネットワーク診断を実行することをお勧めします。 -
ALB インスタンスの帯域幅調整:ALB インスタンスへのトラフィックの急増により、帯域幅調整とパケット損失が発生しました。Cloud Monitor で
アウトバウンド帯域幅とドロップされた接続数のメトリックを確認してください。 -
長いバックエンド処理時間: バックエンド処理時間がクライアントのタイムアウト期間を超過しました。バックエンドの処理時間を示す、アクセスログの
upstream_response_timeフィールドを確認してください。この値が一貫して高い場合は、バックエンドサービスにパフォーマンスボトルネックがないか調査してください。 -
クライアントリクエストのタイムアウトが短すぎる: クライアントがリクエストの送信を完了する前にタイムアウトが発生し、接続が切断されます。 合計リクエスト時間を示すアクセスログの
request_timeフィールドを確認してください。 この値を参考に、より適切なクライアント側のリクエストタイムアウトを設定してください。 -
クライアントで不明な問題が発生した:クライアントは、リクエストが完了する前に接続を閉じました。早期の接続切断を引き起こす可能性のある動作について、クライアントを調査してください。
500 Internal Server Error
バックエンドサーバーで内部エラーが発生し、リクエストを処理できませんでした。
-
バックエンドが 500 を直接返す:アクセスログを確認してください。
upstream_statusが500の場合、ALB がバックエンドからの状態コードをパススルーした可能性が高いです。バックエンドサービスを調査してください。 -
バックエンドサーバーが予期せず接続を閉じた:バックエンドサーバーは、完全な応答を送信する前に接続を閉じました。バックエンドサーバーでパケットキャプチャを実行し、予期せぬ接続切断の原因を特定します。
503 Service Temporarily Unavailable
サーバーは一時的に利用できません。通常、トラフィックが制限を超えたか、バックエンドサービスが利用できないことが原因です。
-
バックエンドが 503 を直接返す: アクセスログを確認してください。
upstream_statusが503の場合、ALB がバックエンドからの状態コードをパススルーした可能性が高いです。バックエンドサービスを調査してください。 -
クライアントリクエストが ALB のスロットリングをトリガーする:
-
Cloud Monitor では、
Requests per secondメトリックを確認します。 -
Cloud Monitor は分単位のデータを表示し、秒単位のスパイクを反映しない場合があります。 アクセスログを確認してください。
upstream_statusフィールドが-の場合、リクエストはバックエンドサーバーに到達していません。 -
応答パケットヘッダーを確認します。
ALB-QPS-Limited:Limitedフィールドが含まれている場合、リクエストが ALB の速度制限をトリガーしたことを示します。
-
-
直接 IP アクセスまたは異常な DNS 解決:これにより、トラフィックが少数の IP アドレスに集中し、スロットリングがトリガーされる可能性があります。ドメイン名を使用して ALB にアクセスし (詳細については、「ALB インスタンスの CNAME ドメイン名の設定」をご参照ください)、DNS 解決が期待どおりに機能することを確認します。
-
リスナーにバックエンドサーバーが設定されていないか、または設定されているバックエンドサーバーの重みが
0である。 -
ALB Ingress のデフォルト転送ルールが 503 を引き起こす:Container Service for Kubernetes (ACK) に ALB Ingress コントローラーをインストールすると、コントローラーは ALB インスタンス上にデフォルト転送ルールと関連するデフォルトサーバーグループを自動的に作成します。デフォルトサーバーグループは最初は空です。着信トラフィックが設定された Ingress 転送ルールのいずれにも一致しない場合、ALB はリクエストをデフォルト転送ルールにルーティングします。デフォルトサーバーグループが空であるため、ALB は 503 エラーを返します。これは期待される動作です。デフォルト転送ルールを手動で削除する必要はありません。この問題を解決するには、正しいドメインベースの転送ルールを設定して、トラフィックを対応するバックエンドサーバーグループにルーティングします。
説明503 エラーは、リクエストを処理できるバックエンドサーバーがない (サーバーグループが空である) ことを示し、バックエンドサーバーは存在するが利用できない 502 エラーとは異なります。
ワイルドカードパスの不適切な設定による 503 エラー
ALB 転送ルールのパスマッチタイプが [完全一致およびワイルドカード] の場合、ワイルドカード文字 * は任意の長さの文字列に一致します。パス /zhpt/* は /zhpt/ で始まるパス (例: /zhpt/test) に一致しますが、ベースパス /zhpt 自体は含まれません。したがって、ルールが /zhpt/* のみで設定されている場合、/zhpt へのリクエストはルールに一致せず、デフォルトの転送アクションにフォールスルーします。デフォルトサーバーグループが空の場合、ALB は 503 Service Temporarily Unavailable エラーを返します。パスマッチングルールの詳細については、「転送ルールの設定例とドメイン名およびパスマッチングルール」をご参照ください。
ソリューション:一致させる必要があるパスの範囲に応じて、以下のいずれかを選択してください:
-
ベースパス
/zhptのみをマッチさせる必要がある場合、ルールパスを/zhpt/*から/zhptに変更します。 -
ベースパス
/zhptとそのサブパス/zhpt/*の両方にマッチさせる必要がある場合は、2 つの個別の転送ルール (/zhptと/zhpt/*) を設定し、ルールの順序に注意してください。 -
より柔軟なパスマッチングが必要な場合は、マッチタイプを [正規表現一致] に変更し、パスを正規表現として記述します (たとえば、
^/zhpt(/.*)?$を使用して/zhptとそのサブパスの両方に一致させます)。 正規表現を^と$で固定し、/zhptxxxのような意図しない一致を回避します。
504 Gateway Timeout
ALB がバックエンドサーバーからの応答を待機中にタイムアウトしました。
-
バックエンドが 504 を直接返す: アクセスログを確認してください。
upstream_statusが504の場合、ALB がバックエンドからの状態コードをパススルーしたと考えられます。バックエンドサービスを調査してください。 -
ALB からバックエンドサーバーへの接続試行がタイムアウトする: このタイムアウトのデフォルト値は 5 秒で、変更はできません。バックエンドサーバーが時間内に応答しない理由を特定するには、パケットをキャプチャします。
-
バックエンド応答タイムアウト: 接続リクエストタイムアウトはデフォルトでは 60 秒です。Cloud Monitor の
UpstreamResponseTimeメトリックとアクセスログのupstream_response_timeフィールドを確認して、バックエンドサーバーの応答がタイムアウトしたかどうかを判断できます。
HTTPS リスナーの TLS ハンドシェイク失敗のトラブルシューティング
クライアントが ALB HTTPS リスナーとの TLS 接続を確立する際に Handshake Failure (40) エラーを受信した場合、以下の原因を確認してください。
SNI の一致確認
クライアントの TLS Client Hello パケットの SNI ServerName フィールドが、ALB リスナーの証明書にバインドされたドメインと一致しない場合、TLS ハンドシェイクは失敗します。
Wireshark を使用してクライアントの TLS Client Hello パケットをキャプチャし、SNI ServerName の値を確認します。 ALB コンソールで、HTTPS リスナーの 証明書 ページで、紐付けられた証明書とその関連ドメイン名を表示し、SNI ServerName の値が証明書のドメイン名と一致することを確認します。
暗号スイートの互換性確認
クライアントがサポートするリストと、ALB の TLS セキュリティポリシーで設定された暗号スイートとの間に共通の暗号スイートがない場合、TLS ハンドシェイクは失敗します。
次のコマンドを実行して、クライアントが Client Hello メッセージで提供する暗号スイートを取得します:
openssl s_client -connect <ALB_domain>:<port>
ALB コンソールの リスナーの詳細 ページで、TLS セキュリティポリシー名をクリックすると、暗号スイートの完全なリストが表示されます。 たとえば、デフォルトポリシー tls_cipher_policy_1_0 には 19 個の暗号スイートが含まれています。 2 つのリストで共通の暗号スイートが少なくとも 1 つあるかどうかを確認します。
証明書タイプと暗号スイートの互換性確認
TLS セキュリティポリシーが ECDSA 署名アルゴリズムを要求しているにもかかわらず、リスナーに RSA 証明書しか設定されていない場合、ECDSA 暗号スイートはネゴシエートできず、TLS ハンドシェイクは失敗します。
ALB コンソールの リスナーの詳細 ページの [SSL 証明書] セクションには、証明書名、ID、ドメイン名が表示されますが、署名アルゴリズムの種類は直接表示されません。証明書リンクをクリックして SSL Certificates Service コンソールに移動し、証明書が RSA または ECDSA を使用しているかどうかを確認します。TLS セキュリティポリシーに ECDSA 暗号スイートが含まれているが、リスナーに ECDSA 証明書がバインドされていない場合は、リスナーに ECC 証明書を追加します。