HTTP(S) 負荷分散のトラブルシューティング

このガイドでは、Google Cloud 外部 HTTP(S) ロードバランサの構成に関する問題のトラブルシューティングについて説明します。

概要

このガイドで説明する問題の種類は次のとおりです。

  • 一般的な接続に関する問題
  • バックエンドに接続する HTTP/2 に関する問題のトラブルシューティング
  • カスタムの送信元とインターネット NEG に関する問題
  • サーバーレス NEG に関する問題(ベータ版)

始める前に

問題を調べる前に、次のページをよくお読みください。

一般的な接続について:

カスタムの送信元とインターネット NEG の場合:

サーバーレス NEG の場合:

接続に関する一般的な問題のトラブルシューティング

原因不明の 502 エラー

ロードバランサの構成を完了してから 502 エラーが数分以上続く場合は、次のいずれかである可能性があります。

ヘルスチェック トラフィックがバックエンド VM に到達したことを確認するには、ヘルスチェック ロギングを有効にし、成功したログエントリを検索します。

負荷分散されたトラフィックに元のクライアントのソースアドレスが含まれていない

ロードバランサからインスタンスへのトラフィックは、130.211.0.0/2235.191.0.0/16 の範囲の IP アドレスを持っています。負荷分散インスタンスのログを見ても、元のクライアントの送信元アドレスは記録されていません。この範囲の送信元アドレスが記録されます。

自分の Cloud Storage バケットでオブジェクトを表示すると権限エラーが発生する

負荷分散を通じてオブジェクトを提供するには、Cloud Storage オブジェクトが一般公開されている必要があります。一般読み取り可能になるように、提供するオブジェクトの権限を更新してください。

URL から予期した Cloud Storage オブジェクトが提供されない

提供される Cloud Storage オブジェクトは、URL マップとリクエストした URL に基づいて決まります。URL マップでリクエストパスがバックエンド バケットにマッピングしている場合、URL マップで指定されている Cloud Storage バケットにリクエストのフルパスが追加され、Cloud Storage オブジェクトが決まります。

たとえば、/static/*gs://[EXAMPLE_BUCKET] にマッピングしている場合、https://<GCLB IP or Host>/static/path/to/content.jpg へのリクエストにより gs://[EXAMPLE_BUCKET]/static/path/to/content.jpg の処理が試みられます。そのオブジェクトが存在しない場合は、オブジェクトの代わりに次のエラー メッセージが返されます。


NoSuchKey
The specified key does not exist.

圧縮が機能しない

HTTP(S) 負荷分散ではレスポンスそのものは圧縮や解凍はされませんが、gzipDEFLATE などのツールを使用して圧縮されたバックエンド サービスで生成されたレスポンスを処理させることはできます。

HTTP(S) 負荷分散で配信されるレスポンスが圧縮されるべきであるものの、圧縮されていない場合は、レスポンスの圧縮がインスタンス上のウェブサーバー ソフトウェアで実行されていることを確認します。デフォルトでは、一部のウェブサーバー ソフトウェアは、ヘッダー Via を含むリクエストの圧縮を自動的に無効にします。このヘッダーはリクエストがプロキシによって転送されたことを示します。HTTP(S) 負荷分散はプロキシであるため、HTTP の仕様の要求に従って Via ヘッダーがリクエストごとに追加されます。圧縮を有効にするには、ウェブサーバーのデフォルトの構成を変更し、リクエストに Via ヘッダーがある場合でもレスポンスを圧縮するように設定します。

nginx ウェブサーバー ソフトウェアを使用している場合は、nginx.conf 構成ファイルを変更して圧縮を有効にします。このファイルの場所は、nginx をインストールした場所によって異なります。多くの Linux ディストリビューションでは、このファイルは /etc/nginx/nginx.conf に保存されています。nginx 圧縮が HTTP(S) 負荷分散で機能するようにするには、nginx.conf の http セクションに次の 2 行を追加します。

gzip_proxied any;
gzip_vary on;

最初の行を追加すると、HTTP(S) 負荷分散などのプロキシから転送されたリクエストでも圧縮が有効になります。2 番目の行により、レスポンスに Vary: Accept-Encoding ヘッダーが追加されます。Vary: Accept-Encoding は、圧縮可能なリソースの圧縮バリアントと非圧縮バリアントに別々のキャッシュ エントリを維持するように、Cloud CDN などのキャッシュ プロキシに通知します。

nginx.conf を変更した後で新しい設定を使用するには、nginx を再起動する必要があります。多くの Linux ディストリビューションでは、sudo service nginx restart または /etc/init.d/nginx restart を実行して nginx を再起動します。

HTTP 408 エラーを解決する

HTTP トラフィックの場合、クライアントがリクエストの送信を完了できる最大時間は、バックエンド サービス タイムアウトと同じです。HTTP 408 レスポンスが jsonPayload.statusDetail client_timed_out で表示されている場合は、クライアントからのリクエストがプロキシされている間、またはバックエンドからのレスポンスがプロキシされた間に、進捗がなかったことを意味します。問題の原因がクライアントのパフォーマンスの問題である場合は、バックエンド サービス タイムアウトを増やすことでこの問題を解決できます。

バックエンドに接続する HTTP/2 に関する問題のトラブルシューティング

フィールド resource.loadBalancingScheme の値が無効: 'EXTERNAL'

バックエンド サービスベースのネットワーク負荷分散は、まだサポートされていません。

この問題は、グローバル オプションを選択せずにバックエンド サービスを作成した場合に発生します。次のように gcloud コマンドを発行した場合、リージョンを指定するか、ロードバランサをグローバルとして指定するように求めるメッセージが表示されます。

gcloud beta compute backend-services create service-test \
    --health-checks=hc-test \
    --project=test1 \
    --protocol=http2

次のバックエンド サービスの場合:

- [service-test] choose a region or global:
[1] global
[2] region: [REGION_A_NAME]
[3] region: [REGION_B_NAME]
....
Please enter your numeric choice:

HTTP(S) ロードバランサの場合、バックエンド サービスはグローバルである必要があります。オプション 1 を選択するか、gcloud コマンドを --global オプションで発行してください。

gcloud beta compute backend-services create service-test \
    --health-checks=hc-test \
    --project=test \
    --protocol=http2 \
    --global

原因不明の 502 エラー

バックエンド インスタンスが正常で、HTTP/2 プロトコルをサポートしていることを確認します。 これを確認するには、HTTP/2 を使用してバックエンド インスタンスへの接続をテストします。VM が HTTP/2 仕様準拠の暗号スイートを使用していることを確認します。たとえば、特定の TLS 1.2 暗号スイートは HTTP/2 では使用できません。TLS 1.2 暗号スイートのブラックリストをご覧ください。

VM が HTTP/2 プロトコルを使用していることを確認したら、ファイアウォールの設定でヘルスチェッカーとロードバランサが通過できることを確認します。

ファイアウォールの設定に問題がない場合は、VM の正しいポートに接続するようにロードバランサを設定します。

カスタムの送信元とインターネット NEG に関する問題のトラブルシューティング

トラフィックがエンドポイントに到達しない

サービスを構成すると、次の場合に、外部 HTTP(S) ロードバランサを介して新しいエンドポイントに到達できます。

  • エンドポイントは、インターネット NEG に接続されている。
  • 関連付けられた FQDN は、DNS で正常に解決できる(FQDN エンドポイント タイプを使用している場合)。
  • エンドポイントには、インターネット経由でアクセスできる。

トラフィックがエンドポイントに到達できず、HTTP(S) で 502 エラーコードが生成される場合は、次の点を確認してください。

  • dig や nslookup などのツールを使用して、_cloud-eoips.googleusercontent.com の DNS TXT レコードのクエリを実行します。CIDR を書き留め(ip4: の後)、ファイアウォールまたはクラウドのアクセス制御リスト(ACL)でこれらの範囲が許可されていることを確認します。

カスタムの送信元を構成した後、カスタムの送信元へのリクエストが 5xx エラーで失敗した

  • Logging を確認します。
  • カスタムの送信元の正しい IP:ポートまたは FQDN:ポートでネットワーク エンドポイント グループが構成されていることを確認します。
  • FQDN を使用している場合は、Google Public DNS で解決できることを確認してください。FQDN がこれらの手順またはウェブ インターフェースを直接使用して Google Public DNS を介して解決できることを確認できます。
  • 外部 IP でのみ HTTP(S) ロードバランサにアクセスし、送信元ウェブサーバーがホスト名を想定している場合は、ユーザー定義のリクエスト ヘッダーを構成することにより、有効な HTTP ホストヘッダーをバックエンドに送信していることを確認します。
  • HTTPS または HTTP2 を介するバックエンドへの通信(バックエンド サービスの protocol フィールドで設定)が INTERNET_FQDN_PORT カスタムの送信元エンドポイントとして構成されている場合は、送信元が有効な TLS(SSL)証明書を示し、構成された FQDN が証明書の SAN(サブジェクト代替名)リスト内の SAN と一致していることを確認します。有効な証明書とは、パブリック認証局によって署名され、有効期限が切れていないものと定義されています。
  • INTERNET_FQDN_PORT カスタムの送信元エンドポイントを使用している場合は、自己署名証明書は、HTTPS ロードバランサで受け入れられず、拒否されます。
  • INTERNET_IP_PORT タイプのエンドポイントで HTTPS や HTTP/2 を使用している場合は、SSL 証明書の検証と SAN チェックは行われません。つまり、自己署名証明書を使用できます。SSL を使用している場合は、INTERNET_FQDN_PORT エンドポイントを使用して、サーバー証明書と SAN を検証できるようにすることをおすすめします。

カスタムの送信元からのレスポンスが Cloud CDN によってキャッシュされない

その際は、以下の点を確認してください。

  • enableCDN を true に設定して、カスタムの送信元を指す NEG を含むバックエンド サービスで Cloud CDN をすでに有効にしている。
  • カスタムの送信元から配信されたレスポンスが、Cloud CDN のキャッシュ保存の要件を満たしている。たとえば、送信元からの Cache-Control: public, max-age=3600 レスポンス ヘッダーを返している。

サーバーレス NEG に関する問題のトラブルシューティング

リクエストが 404 エラーで失敗する

基盤となるサーバーレス リソース(App Engine、Cloud Functions、フルマネージドの Cloud Run サービスなど)がまだ実行されていることを確認します。サーバーレス リソースが削除されても、サーバーレス NEG がまだ存在する場合、外部 HTTP(S) ロードバランサは引き続き存在しないサービスへのリクエストの転送を試みます。これにより、404 レスポンスが返されます。

一般に、外部 HTTP(S) ロードバランサは、基盤となるサーバーレス リソースが想定どおりに動作しているかどうかを検出できません。つまり、あるリージョンのサービスがエラーを返しても、そのリージョンの Cloud Run(フルマネージド)、Cloud Functions、または App Engine インフラストラクチャ全体が正常に動作している場合、外部 HTTP(S) ロードバランサが他のリージョンにトラフィックを自動的に転送することはありません。ユーザー トラフィックをルーティングする前に、サービスの新しいバージョンを入念にテストしてください。

URL マスクの不一致への対処

ユーザー リクエスト URL に構成済み URL マスクを適用してもサービス名が生成されない場合や、存在しないサービス名が生成される場合、ロードバランサは使用中のサーバーレス コンピューティング プラットフォームに応じて、これらの不一致を異なる方法で対処します。

Cloud Run(フルマネージド): URL マスクが一致しない場合、ロードバランサは HTTP エラー 404(Not Found)を返します。

Cloud Functions: URL マスクが一致しない場合、ロードバランサは HTTP エラー 404(Not Found)を返します。

App Engine: URL マスクが一致しない場合、App Engine は dispatch.yaml と App Engine のデフォルトのルーティング ロジックを使用して、リクエストの送信先のサービスを決定します。