トラブルシューティングの概要
このページでは、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
から発生したのか、バックエンドから発生したのかをレスポンス自体から判断できないことがあります。
これを判断するには:
[ログ エクスプローラ] ページに移動して、プロジェクトを選択します。
次のログクエリを使用して、関連するゲートウェイ リソースにフィルタします。
resource.type="apigateway.googleapis.com/Gateway" resource.labels.gateway_id="GATEWAY_ID" resource.labels.location="GCP_REGION"
ここで
- GATEWAY_ID はゲートウェイの名前を指定します。
- GCP_REGION は、デプロイされたゲートウェイの Google Cloud リージョンです。
調査する HTTP エラー レスポンスに一致するログエントリを見つけます。 たとえば、
httpRequest.statusでフィルタします。jsonPayload.responseDetailsフィールドの内容を確認します。
jsonPayload.responseDetails フィールドの値が
"via_upstream" の場合、エラー レスポンスはバックエンドから発生しているため、バックエンドを直接トラブルシューティングする必要があります。それ以外の値の場合、エラー レスポンスは Gateway から発生しています。トラブルシューティングのヒントについては、このドキュメントの以下のセクションをご覧ください。
API リクエストが HTTP 403 エラーを返す
デプロイされた API に対するリクエストで API クライアントに HTTP 403 エラーが返された場合は、リクエストされた URL
が有効であっても、なんらかの理由でアクセスが禁止されています。
デプロイされた API には、API 構成の作成時に使用した
サービス アカウントに付与されたロールに関連付けられた権限があります。通常、HTTP 403 エラーが発生する理由は、サービス アカウントにバックエンド サービスへのアクセスに必要な権限が付与されていないことです。
API とバックエンド サービスを同じ Google Cloud プロジェクトで定義した場合は、サービス アカウントに Editor
ロールまたはバックエンド サービスへのアクセスに必要なロールが割り当てられていることを確認します。たとえば、バックエンド サービスが Cloud Run functions を使用して実装されている場合は、サービス アカウントに Cloud Function Invoker ロールが割り当てられていることを確認します。
API リクエストが HTTP 401 または 500 エラーを返す
デプロイされた API に対するリクエストで API クライアントに HTTP 401 または 500 エラーが返された場合は、バックエンド サービスを呼び出す API 構成を作成したときに使用されたサービス アカウントの使用に問題がある可能性があります。
デプロイされた API には、API 構成の作成時に使用した サービス アカウント に付与されたロールに関連付けられた権限があります。両方が存在し、API のデプロイ時に API ゲートウェイで使用できることを確認するために、サービス アカウントがチェックされます。
ゲートウェイのデプロイ後にサービス アカウントが削除または無効にされると、次の一連のイベントが発生する可能性があります。
サービス アカウントが削除または無効に設定されると直ちに、ゲートウェイ ログに 401 HTTP レスポンスが表示される場合があります。ログエントリの
jsonPayloadでjsonPayload.responseDetailsフィールドが"via_upstream"に設定されている場合は、サービス アカウントを削除または無効にしたことがエラーの原因であることを示しています。API Gateway のログに対応するログエントリがないと、HTTP
500エラーが表示されることもあります。サービス アカウントが削除または無効になった直後にゲートウェイへのリクエストがない場合、HTTP 401 レスポンスは表示されませんが、対応する API Gateway ログがない HTTP500エラーは、ゲートウェイのサービス アカウントがアクティブではなくなった可能性を示しています。
失敗したリクエストのバックエンドが別の 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 として返されます。
ゲートウェイ ログで原因を確認する
[ログ エクスプローラ] ページに移動して、プロジェクトを選択します。
次のログクエリを実行します。
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の場合と同じ値が生成されます。一致するエントリの
jsonPayload.apiConfigフィールドとjsonPayload.apiMethodフィールドを確認します。これらは、割り当て構成が無効な API 構成とメソッドを識別します。
API 構成で割り当て構成が無効になる理由
割り当て指標と上限は API 構成で定義しますが、API Gateway はそれらを API 全体に適用します。API 構成を作成するたびに、宣言された指標と上限は、API の以前の API 構成で宣言された指標と上限を置き換えます。 最後に作成された API 構成の値のみが適用されます。
一方、各メソッドで使用される指標は、ゲートウェイが提供する API 構成で定義されます。ゲートウェイが古い API 構成を実行すると、Service Control は独自の構成に存在するが API に存在しない可能性のある指標に対して割り当てを割り当てるように要求します。指標が存在しない場合、割り当て呼び出しは失敗し、ゲートウェイはリクエストを拒否します。
たとえば、次のシーケンスでは、最初のゲートウェイが破損します。
- 指標
quota-metric-v1を宣言する API 構成config-v1を作成し、gateway-1にデプロイします。 - 同じ API の API 構成
config-v2を作成します。この構成では、指標quota-metric-v2を宣言し、gateway-2にデプロイします。
gateway-2 は機能しますが、gateway-1 の割り当て適用メソッドへのリクエストは失敗します。これは、quota-metric-v1
が API で定義されなくなったためです。
次の変更を行うと、以前の API 構成でデプロイされているゲートウェイでエラーが発生する可能性があります。
- 指標の名前変更または削除。
- 割り当て上限が適用される指標の変更。
- メソッドごとの割り当て費用(OpenAPI ドキュメントの場合は
x-google-quota、gRPC サービス構成の場合はquota.metric_rules)で指定された指標の変更。
上限の 値のみを変更してもエラーは発生しません。ただし、上限は API レベルでも適用されるため、新しい値は、以前の API 構成でデプロイされたゲートウェイを含む、その API のすべてのゲートウェイに適用されます。
デプロイされた割り当て構成を比較する
ゲートウェイと、各ゲートウェイが提供する API 構成を一覧表示します。
gcloud api-gateway gateways list \ --format="table(name.basename(),apiConfig)"
影響を受ける 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 構成を予測可能な順序で返しません。API 構成の作成元となった API 定義を表示します。
gcloud api-gateway api-configs describe CONFIG_ID --api=API_ID \ --view=FULL --format="value(openapiDocuments[0].document.contents)" \ | tr '_-' '/+' | base64 --decode
contentsフィールドは base64url エンコードされているため、base64 --decodeで直接読み取ることができません。そのため、trコマンドが必要です。gRPC API の場合、割り当て構成は OpenAPI ドキュメントではなくサービス構成にあるため、
openapiDocuments[0].document.contentsをmanagedServiceConfigs[0].contentsに置き換えます。ステップ 2 のリストの先頭にある API 構成と、ステップ 1 でゲートウェイにデプロイされていると示されている他の API 構成ごとに、ステップ 3 のコマンドを実行します。
結果を比較します。古い 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 コンソール
Google Cloud コンソールで、[API とサービス] >[API ライブラリ] ページに移動します。
- [API ライブラリ] ページの検索バーに、必要な API 名を入力します。
- 検索結果で、API ページを選択します。
- API ページで [有効にする] をクリックします。
- 上記の表に記載されているサービスごとに、これらの手順を繰り返します。
Google Cloud CLI
次のコマンドを使用して、サービスを有効にします。
gcloud services enable apigateway.googleapis.comgcloud services enable servicemanagement.googleapis.comgcloud services enable servicecontrol.googleapis.com
gcloud サービスの詳細については、
gcloud サービスをご覧ください。