トラブルシューティングの概要

このページでは、API Gateway の一般的なトラブルシューティング情報について説明します。

「gcloud api-gateway」コマンドを実行できない

gcloud api-gateway ... コマンドを実行するには、Google Cloud CLI を更新し、必要な Google サービスを有効にしている必要があります。詳細については、開発環境の構成をご覧ください。

コマンド「gcloud api-gateway api-configs create」を実行すると、「サービス アカウントが存在しません」と表示される

gcloud api-gateway api-configs create ... コマンドを実行して、次の形式のエラーが表示された場合:

ERROR: (gcloud.api-gateway.api-configs.create) FAILED_PRECONDITION:
Service Account "projects/-/serviceAccounts/service_account_email" does not exist

コマンドを再実行します。今回は、--backend-auth-service-account オプションを使用して、使用するサービス アカウントのメールアドレスを明示的に指定します。

gcloud api-gateway api-configs create CONFIG_ID \
  --api=API_ID --openapi-spec=API_DEFINITION \
  --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL

開発環境の構成の説明に従って、サービス アカウントに必要な権限がすでに割り当てられていることを確認します。

API エラー レスポンスのソースを特定する

デプロイされた API へのリクエストでエラー(HTTP ステータス コード 400~599)が発生した場合、エラーが Gateway から発生したのか、バックエンドから発生したのかがレスポンス自体からは明確でない場合があります。これを確認する方法は次のとおりです。

  1. [ログ エクスプローラ] ページに移動して、プロジェクトを選択します。

    [ログ エクスプローラ] に移動

  2. 次のログクエリを使用して、関連するゲートウェイ リソースをフィルタします。

    resource.type="apigateway.googleapis.com/Gateway"
    resource.labels.gateway_id="GATEWAY_ID"
    resource.labels.location="GCP_REGION"

    ここで

    • GATEWAY_ID はゲートウェイの名前を指定します。
    • GCP_REGION は、デプロイされたゲートウェイの Google Cloud リージョンです。
  3. 調査する HTTP エラー レスポンスに一致するログエントリを見つけます。たとえば、httpRequest.status でフィルタします。

  4. jsonPayload.responseDetails フィールドの内容を調べます。

jsonPayload.responseDetails フィールドの値が "via_upstream" の場合、エラー レスポンスはバックエンドから発生しているため、バックエンドを直接トラブルシューティングする必要があります。それ以外の値の場合、エラー レスポンスは Gateway から送信されています。トラブルシューティングのヒントについては、このドキュメントの次のセクションをご覧ください。

API リクエストが HTTP 403 エラーを返す

デプロイされた API に対するリクエストで API クライアントに HTTP 403 エラーが返された場合は、リクエストされた URL が有効であっても、なんらかの理由でアクセスが禁止されています。

デプロイされた API には、API 構成の作成時に使用したサービス アカウントに付与されたロールに関連付けられた権限があります。通常、HTTP 403 エラーが発生する理由は、サービス アカウントにバックエンド サービスへのアクセスに必要な権限が付与されていないことです。

同じ Google Cloud プロジェクトで API とバックエンド サービスを定義した場合は、サービス アカウントに Editor ロールまたはバックエンド サービスへのアクセスに必要なロールが割り当てられていることを確認します。たとえば、バックエンド サービスが Cloud Run functions を使用して実装されている場合は、サービス アカウントに Cloud Function Invoker ロールが割り当てられていることを確認します。

API リクエストが HTTP 401 または 500 エラーを返す

デプロイされた API に対するリクエストで API クライアントに HTTP 401 または 500 エラーが返された場合は、バックエンド サービスを呼び出す API 構成を作成したときに使用されたサービス アカウントの使用に問題がある可能性があります。

デプロイされた API には、API 構成の作成時に使用したサービス アカウントに付与されたロールに関連付けられた権限があります。サービス アカウントは、両方が存在し、API のデプロイ時に API Gateway で使用できることを確認するためにチェックされます。

ゲートウェイのデプロイ後にサービス アカウントが削除または無効にされると、次の一連のイベントが発生する可能性があります。

  1. サービス アカウントが削除または無効に設定されると直ちに、ゲートウェイ ログに 401 HTTP レスポンスが表示される場合があります。ログエントリの jsonPayload で jsonPayload.responseDetails フィールドが "via_upstream" に設定されている場合は、サービス アカウントを削除または無効にしたことがエラーの原因であることを示しています。

  2. API Gateway のログに対応するログエントリがないと、HTTP 500 エラーが表示されることもあります。サービス アカウントが削除または無効になった直後にゲートウェイへのリクエストがない場合、HTTP 401 レスポンスは表示されませんが、対応する API Gateway ログがない HTTP 500 エラーは、ゲートウェイのサービス アカウントがアクティブではなくなった可能性を示しています。

失敗したリクエストのバックエンドが別の Google Cloud API(bigquery.googleapis.com など)の場合、ゲートウェイ ログに 401 HTTP レスポンスが表示され、jsonPayload.responseDetails フィールドが "via_upstream" に設定されます。これは、API Gateway が ID トークンを使用してバックエンドを認証するのに対し、他の Google Cloud API ではアクセス トークンが必要になるためです。

割り当てが適用されたメソッドに対して API リクエストが HTTP 500 エラーを返す

次のエラーが表示された場合、ゲートウェイはリクエストに数量に基づく割り当てを割り当てることができませんでした。

HTTP/2 500
{"code":500,"message":"Failed to call Service Control Quota."}

このエラーは通常、割り当てが構成されているメソッドを呼び出したときに、API の割り当て指標が存在しない場合に発生します。gRPC ゲートウェイでは、同じエラーが gRPC ステータス コード Internal として返されます。

ゲートウェイ ログで原因を確認する

  1. [ログ エクスプローラ] ページに移動して、プロジェクトを選択します。

    [ログ エクスプローラ] に移動

  2. 次のログクエリを実行します。

    resource.type="apigateway.googleapis.com/Gateway"
    resource.labels.gateway_id="GATEWAY_ID"
    jsonPayload.responseDetails="service_control_quota_error"
    httpRequest.status=500

    ここで、GATEWAY_ID はゲートウェイの名前を指定します。

    API Gateway は、割り当ての拒否ごとに同じ responseDetails 値を使用するため、クエリはステータス コードと jsonPayload.responseDetails でフィルタします。割り当てを正当に超過したリクエストは、httpRequest.status が 429 の同じ値を生成します。

  3. 一致するエントリの jsonPayload.apiConfig フィールドと jsonPayload.apiMethod フィールドを調べます。これらは、API 構成と、割り当て構成が無効なメソッドを識別します。

API 構成に無効な割り当て構成が含まれる理由

割り当て指標と上限は API 構成で定義しますが、API Gateway はそれらを API 全体に適用します。API 構成を作成するたびに、宣言された指標と上限が、API の以前の API 構成で宣言された指標と上限に置き換えられます。最新の API 構成の値のみが適用されます。

一方、各メソッドで使用される指標は、ゲートウェイが提供する API 構成で定義されます。ゲートウェイが古い API 構成を実行している場合、Service Control に、独自の構成に存在するが API には存在しない指標に対して数量に基づく割り当てを割り当てるようにリクエストします。指標が存在しない場合、割り当て呼び出しは失敗し、ゲートウェイはリクエストを拒否します。

たとえば、次のシーケンスでは、最初のゲートウェイが破損したままになります。

  1. 指標 quota-metric-v1 を宣言する API 構成 config-v1 を作成し、gateway-1 にデプロイします。
  2. 同じ API の API 構成 config-v2 を作成します。この構成では、指標 quota-metric-v2 を宣言し、gateway-2 にデプロイします。

gateway-2 は機能しますが、gateway-1 の割り当てが適用されるメソッドへのリクエストは失敗します。これは、API に quota-metric-v1 が定義されていないためです。

次の変更を行うと、以前の API 構成でデプロイされたゲートウェイでエラーが発生する可能性があります。

  • 指標の名前変更または削除。
  • 割り当て上限が適用される指標を変更する。
  • メソッドごとの割り当てコストで指定された指標を変更する(OpenAPI ドキュメントの場合は x-google-quota、gRPC サービス構成の場合は quota.metric_rules)。

上限の値のみを変更しても、エラーは発生しません。ただし、上限は API レベルでも適用されるため、新しい値は、以前の API 構成でデプロイされたゲートウェイを含む、その API のすべてのゲートウェイに適用されます。

デプロイされた割り当て構成を比較する

  1. ゲートウェイと、各ゲートウェイが提供する API 構成を一覧表示します。

    gcloud api-gateway gateways list \
     --format="table(name.basename(),apiConfig)"
  2. 影響を受ける API の API 構成を一覧表示します。最新のものが最初に表示されます。

    gcloud api-gateway api-configs list --api=API_ID \
     --format="table(name.basename(),createTime:sort=1:reverse)"

    最初のエントリは、API 全体に割り当て指標と上限が適用される API 構成です。次のように --format フラグを使用して並べ替えます。このコマンドは --sort-by フラグをサポートしておらず、API 構成を予測可能な順序で返しません。

  3. API 構成の作成元となった API 定義を表示します。

    gcloud api-gateway api-configs describe CONFIG_ID --api=API_ID \
     --view=FULL --format="value(openapiDocuments[0].document.contents)" \
     | tr '_-' '/+' | base64 --decode

    tr コマンドは、contents フィールドが base64url でエンコードされているために必要です。base64 --decode は直接読み取ることができません。

    gRPC API の場合、割り当て構成は OpenAPI ドキュメントではなくサービス構成にあるため、openapiDocuments[0].document.contents を managedServiceConfigs[0].contents に置き換えます。

  4. ステップ 2 のリストの一番上にある API 構成に対してステップ 3 のコマンドを実行し、ステップ 1 でゲートウェイにデプロイされていることが示された他の各 API 構成に対して実行します。

  5. 結果を比較します。古い API 構成でメソッドに対して課金されるすべての指標は、最近作成された API 構成でも定義する必要があります。その構成に指標がない場合、古い API 構成を処理するゲートウェイは失敗します。

有効な割り当て構成を復元する

割り当て指標と上限を監査して、すべてのアクティブな構成で一貫していることを確認します。これを行うには、次のいずれかの操作を行います。

  • ゲートウェイを更新するの説明に従って、API のすべてのゲートウェイを更新し、最後に作成された API 構成を使用します。
  • まだデプロイされている API 構成で使用されているすべての指標を宣言する新しい API 構成を作成し、既存のゲートウェイを現在の API 構成に維持します。

割り当てエラーを回避するには、API の API 構成全体で指標名を一貫して使用します。割り当てを変更する場合は、指標の名前ではなく、上限の値を変更します。

レイテンシの高い API リクエスト

Cloud Run や Cloud Run functions と同様に、API Gateway には「コールド スタート」レイテンシが発生します。ゲートウェイが 15~20 分間トラフィックを受信していない場合は、コールド スタートの最初の 10~15 秒以内にゲートウェイに対して行われたリクエストでは 3~5 秒のレイテンシが発生します。

最初の「ウォームアップ」期間が経過しても問題が解決しない場合は、API 構成で構成したバックエンド サービスのリクエストログを確認します。たとえば、バックエンド サービスが Cloud Run functions を使用して実装されている場合は、関連する Cloud Functions リクエストログの Cloud Logging ログエントリを確認します。

ログ情報を表示できない

API が正しく応答していても、ログにデータが含まれていない場合は、通常、API Gateway に必要なすべての Google サービスが有効になっていないことを意味します。

API Gateway では、次の Google Cloud サービスを有効にする必要があります。

名前 サービス名
API Gateway API apigateway.googleapis.com
Service Management API servicemanagement.googleapis.com
Service Control API servicecontrol.googleapis.com

必要なサービスを有効にするには:

Google Cloud コンソール

  1. Google Cloud コンソールで、[API とサービス] > [API ライブラリ] ページに移動します。

    [API ライブラリ] に移動

  2. [API ライブラリ] ページで、検索バーに必要な API 名を入力します。
  3. 検索結果で、API ページを選択します。
  4. API ページで [有効にする] をクリックします。
  5. 前の表に記載されているサービスごとに、上記の手順を繰り返します。

Google Cloud CLI

次のコマンドを使用してサービスを有効にします。

gcloud services enable apigateway.googleapis.com
gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

gcloud サービスの詳細については、gcloud サービスをご覧ください。