このページでは、一般的な問題に対するトラブルシューティングの方法と解決策を説明します。
Cloud Run for Anthos のトラブルシューティングで最初に行うことは、コンテナ イメージをローカルで実行できるか確認することです。
アプリケーションがローカルで実行されていない場合は、その原因を突き止め、問題を修正する必要があります。デプロイされたプロジェクトをデバッグするには、Cloud Logging を使用します。
Cloud Run for Anthos のトラブルシューティングを行う際は、以降のセクションで問題の解決方法をご覧ください。
Cloud Run for Anthos の既知の問題と、解決方法の詳細について、既知の問題のページもご覧ください。
コマンドラインの出力を確認する
Google Cloud CLI を使用する場合は、コマンドの出力で結果を確認します。たとえば、デプロイが失敗した場合、失敗の理由を説明するエラー メッセージが表示されます。
デプロイが失敗する原因の多くは、マニフェストの構成ミスかコマンドの誤りです。次の出力の場合、ルート トラフィックの割合が合計で 100 になるように構成する必要があります。
Error from server (InternalError): error when applying patch:</p><pre>{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"serving.knative.dev/v11\",\"kind\":\"Route\",\"metadata\":{\"annotations\":{},\"name\":\"route-example\",\"namespace\":\"default\"},\"spec\":{\"traffic\":[{\"configurationName\":\"configuration-example\",\"percent\":50}]}}\n"}},"spec":{"traffic":[{"configurationName":"configuration-example","percent":50}]}}
to:
&{0xc421d98240 0xc421e77490 default route-example STDIN 0xc421db0488 264682 false}
for: "STDIN": Internal error occurred: admission webhook "webhook.knative.dev" denied the request: mutation failed: The route must have traffic percent sum equal to 100.
ERROR: Non-zero return code '1' from command: Process exited with status 1
サービスのログを確認する
Cloud Logging または Google Cloud コンソールの Cloud Run for Anthos ページを使用して、リクエストログとコンテナログを確認できます。詳細については、ログの記録と表示をご覧ください。
Cloud Logging を使用する場合、フィルタするリソースは Kubernetes コンテナです。
サービスのステータスを確認する
次のコマンドを実行して、デプロイされた Cloud Run for Anthos サービスのステータスを取得します。
gcloud run services describe SERVICE
--format yaml(status)
または --format json(status)
を追加すると、完全なステータスを取得できます。次に例を示します。
gcloud run services describe SERVICE --format 'yaml(status)'
status
の条件が、失敗の原因を特定する際に役立ちます。条件には、True
、False
、Unknown
などがあります。
- Ready:
True
は、サービスが構成され、トラフィックを受信できる状態であることを示します。 - ConfigurationReady:
True
は、基盤となる構成の準備が完了していることを示します。False
または「Unknown」の場合、最新のリビジョンのステータスを表示します。 - RoutesReady:
True
は、基盤となるルートの準備が完了していることを示します。False
または「Unknown」の場合は、ルートのステータスを表示します。
ステータス条件の詳細については、Knative のエラーシグナルをご覧ください。
ルートのステータスを確認する
Cloud Run for Anthos サービスは、サービスのリビジョンに対する現在のルーティング状態を表すルートを管理します。
ルート全体のステータスを確認するには、サービスのステータスを確認します。
gcloud run services describe SERVICE --format 'yaml(status)'
status
の RoutesReady 条件で、ルートのステータスを確認できます。
ルートのステータスをさらに診断するには、次のコマンドを実行します。
kubectl get route SERVICE -o yaml
status
の条件は、失敗の理由を表しています。まとめると次のようになります。
Ready は、サービスが構成され、利用可能なバックエンドがあるかどうかを示します。
true
の場合、ルートは正しく構成されています。AllTrafficAssigned は、サービスが適切に構成され、使用可能なバックエンドがあるかどうかを示します。この条件の
status
がTrue
でない場合:サービスのリビジョン間で分割されたトラフィックの合計が 100% になるかどうかを確認します。
gcloud run services describe SERVICE
そうでない場合は、
gcloud run services update-traffic
コマンドを使用してトラフィック分割を調整します。トラフィックを受信しているリビジョンについて、リビジョンのステータスを確認します。
IngressReady は Ingress の準備が完了しているかどうかを示します。この条件の
status
がTrue
でない場合は、Ingress のステータスを確認します。CertificateProvisioned は、Knative 証明書がプロビジョニングされたかどうかを示します。この条件の
status
がTrue
ではない場合、マネージド TLS の問題のトラブルシューティングを行います。
ステータス条件の詳細については、Knative のエラー条件とレポートをご覧ください。
Ingress のステータスを確認する
Cloud Run for Anthos は、ロードバランサの Kubernetes Service(istio-ingress
)を使用して、クラスタ外部からのトラフィックを処理します。
Ingress の外部 IP アドレスを取得するには、次のコマンドを使用します。
kubectl get svc istio-ingress -n gke-system
EXTERNAL-IP
が pending
の場合は、後述の EXTERNAL-IP が長時間 pending
になっているをご覧ください。
リビジョンのステータスを確認する
Cloud Run for Anthos サービスの最新リビジョンを取得するには、次のコマンドを実行します。
gcloud run services describe SERVICE --format='value(status.latestCreatedRevisionName)'
特定の Cloud Run for Anthos リビジョンのステータスを取得するには、次のコマンドを実行します。
gcloud run revisions describe REVISION
完全なステータスを取得するには、--format yaml(status)
または --format json(status)
を追加します。
gcloud run revisions describe REVISION --format yaml(status)
status
の条件が失敗の理由を表しています。まとめると次のようになります。
- Ready は、ランタイム リソースが使用可能かどうかを示します。これが
true
の場合、リビジョンは正しく構成されています。 - ResourcesAvailable は、基盤となる Kubernetes リソースがプロビジョニングされたかどうかを示します。この条件の
status
がTrue
でない場合は、Pod のステータスを確認してください。 - ContainerHealthy は、リビジョン準備チェックが完了したかどうかを示します。この条件の
status
がTrue
でない場合は、Pod のステータスを確認してください。 - Active は、リビジョンがトラフィックを受信しているかどうかを示します。
次のいずれかの条件の status
が True
ではない場合は、Pod のステータスを確認してください。
Pod のステータスを確認する
すべてのデプロイのポッドを取得するには:
kubectl get pods
ポッドの一覧とステータスの概要が表示されます。例:
NAME READY STATUS RESTARTS AGE
configuration-example-00001-deployment-659747ff99-9bvr4 2/2 Running 0 3h
configuration-example-00002-deployment-5f475b7849-gxcht 1/2 CrashLoopBackOff 2 36s
いずれかを選択して次のコマンドを使用すると、status
の詳細情報が表示されます。conditions
と containerStatuses
などのフィールドに重要な情報が含まれます。
kubectl get pod POD-NAME -o yaml
EXTERNAL-IP が長時間 <pending>
になっている
クラスタの作成後すぐに外部 IP アドレスが取得されず、外部 IP が pending
と表示される場合があります。たとえば、次のコマンドを呼び出すと、このような状況になることがあります。
Istio Ingress Gateway の外部 IP を取得するには:
kubectl get svc istio-ingress -n gke-system
次のような出力が生成されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingress LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
ロードバランサの EXTERNAL-IP は、使用する必要がある IP アドレスです。
この場合、Google Cloud の外部 IP アドレスの割り当てが上限に達している可能性があります。次の呼び出しを行うと、考えられる原因を確認できます。
kubectl describe svc istio-ingress -n gke-system
これにより、次のような出力が生成されます。
Name: istio-ingress Namespace: gke-system Labels: addonmanager.kubernetes.io/mode=Reconcile app=istio-ingress chart=gateways-1.0.3 heritage=Tiller istio=ingress-gke-system k8s-app=istio kubernetes.io/cluster-service=true release=istio Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconcile","app":"istio-ingressgateway","... Selector: app=ingressgateway,istio=ingress-gke-system,release=istio Type: LoadBalancer IP: 10.XX.XXX.XXX LoadBalancer Ingress: 35.XXX.XXX.188 Port: http2 80/TCP TargetPort: 80/TCP NodePort: http2 31380/TCP Endpoints: XX.XX.1.6:80 Port: https 443/TCP TargetPort: 443/TCP NodePort: https 3XXX0/TCP Endpoints: XX.XX.1.6:XXX Port: tcp 31400/TCP TargetPort: 3XX00/TCP NodePort: tcp 3XX00/TCP Endpoints: XX.XX.1.6:XXXXX Port: tcp-pilot-grpc-tls 15011/TCP TargetPort: 15011/TCP NodePort: tcp-pilot-grpc-tls 32201/TCP Endpoints: XX.XX.1.6:XXXXX Port: tcp-citadel-grpc-tls 8060/TCP TargetPort: 8060/TCP NodePort: tcp-citadel-grpc-tls 31187/TCP Endpoints: XX.XX.1.6:XXXX Port: tcp-dns-tls 853/TCP TargetPort: XXX/TCP NodePort: tcp-dns-tls 31219/TCP Endpoints: 10.52.1.6:853 Port: http2-prometheus 15030/TCP TargetPort: XXXXX/TCP NodePort: http2-prometheus 30944/TCP Endpoints: 10.52.1.6:15030 Port: http2-grafana 15031/TCP TargetPort: XXXXX/TCP NodePort: http2-grafana 31497/TCP Endpoints: XX.XX.1.6:XXXXX Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 7s (x4318 over 15d) service-controller Ensuring load balancer
IN_USE_ADDRESSES
割り当てを超過したことを示す項目が出力に含まれている場合は、Google Cloud Console の [IAM と管理] ページへ移動して、追加の割り当てをリクエストしてください。
外部 IP アドレスが割り当てられるまで、ゲートウェイは再試行を繰り返します。これには数分かかることがあります。
マネージド TLS の問題のトラブルシューティング
マネージド TLS 証明書機能の一般的な問題を解決するには、以下のトラブルシューティング手順を確認してください。
特定のドメイン マッピングのステータスを確認する
特定のドメイン マッピングのステータスを確認するには:
次のコマンドを実行します。
gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE
次のように置き換えます。
- DOMAIN は、使用しているドメインの名前に置き換えます。
- NAMESPACE は、ドメイン マッピングに使用する Namespace に置き換えます。
このコマンドからの
yaml
の結果で、CertificateProvisioned
フィールドの条件を確認して、エラーの性質を判断します。エラーが表示される場合は、次の表のいずれかのエラーと一致するはずです。表の指示に従って問題を解決してください。
ユーザー構成エラー
エラーコード | 詳細なメッセージ | トラブルシューティングの手順 | |
DNSErrored | DNS record is not configured correctly. Need to map domain [XXX] to IP XX.XX.XX.XX | 指定された手順に従って、DNS レコードを正しく構成してください。 | |
RateLimitExceeded | acme: urn:ietf:params:acme:error:rateLimited: Error creating new order
:: too many certificates already issued for exact set of domains: test.example.com: see https://letsencrypt.org/docs/rate-limits/ |
Let's Encrypt に連絡して、そのホストの証明書の割り当てを増やしてください。 | |
InvalidDomainMappingName | DomainMapping name %s cannot be the same as Route URL host %s. | DomainMapping の名前は、マップ先の Route のホストと同一にすることはできません。DomainMapping の名前には別のドメインを使用してください。 | |
ChallengeServingErrored | システムが HTTP01 リクエストを処理できませんでした。 | このエラーは、istio-ingress サービスが Let's Encrypt からのリクエストに対応してドメインの所有権を確認できない場合に発生します。 |
|
システムエラー
エラーコード | 詳細なメッセージ | トラブルシューティングの手順 |
OrderErrored
AuthzErrored ChallengeErrored |
この 3 種類のエラーは、Let's Encrypt によるドメイン所有権の確認が失敗した場合に発生します。 通常、これらのエラーは一時的なエラーであり、Cloud Run for Anthos によって再試行されます。 再試行の遅延時間は、最小 8 秒から最大 8 時間まで指数関数的に変動します。 このエラーを手動で再試行する場合は、失敗した Order を手動で削除します。
|
|
ACMEAPIFailed | この種類のエラーは、Cloud Run for Anthos による Let's Encrypt の呼び出しが失敗したときに発生します。通常は一時的なエラーであり、Cloud Run for Anthos によって再試行されます。 このエラーを手動で再試行する場合は、失敗した Order を手動で削除します。
|
|
UnknownErrored | 不明なシステムエラーを示しています。GKE クラスタではめったに発生しません。このエラーが表示された場合は、Cloud サポートに問い合わせて、デバッグの支援を依頼してください。 |
Order ステータスを確認する
Order ステータスは、Let's Encrypt との対話プロセスを記録するため、Let's Encrypt に関連する問題のデバッグに使用できます。必要に応じて、次のコマンドを実行して Order ステータスを確認します。
kubectl get order DOMAIN -n NAMESPACE -oyaml
次のように置き換えます。
- DOMAIN は、使用しているドメインの名前に置き換えます。
- NAMESPACE は、ドメイン マッピングに使用する Namespace に置き換えます。
Order が成功した場合は、結果に発行された証明書とその他の情報が含まれます。
Let's Encrypt の割り当ての超過
DomainMapping のステータスを確認します。次のように、Let's Encrypt の割り当てを超過すると、DomainMapping にエラー メッセージが表示されます。
acme: urn:ietf:params:acme:error:rateLimited: Error creating new order :: too many certificates already issued for exact set of domains: test.example.com: see https://letsencrypt.org/docs/rate-limits/'
証明書の割り当てを増やすには、Let's Encrypt のレート制限に関するドキュメントをご覧ください。
Order のタイムアウト
証明書を取得できない場合、Order オブジェクトは 20 分後にタイムアウトします。
ドメイン マッピングのステータスを確認します。タイムアウトした場合は、ステータス出力で次のようなエラー メッセージを探します。
order (test.example.com) timed out (20.0 minutes)
タイムアウトの問題の一般的な原因は、使用しているドメインを
gke-system
の下にあるistio-ingress
サービスの IP アドレスにマッピングするように DNS レコードが適切に構成されていないことです。次のコマンドを実行して DNS レコードを確認します。host DOMAIN
次のコマンドを実行して、
gke-system
の下にあるistio-ingress
サービスの外部 IP アドレスを確認します。kubectl get svc istio-ingress -n gke-system
ドメインの外部 IP アドレスが上り(内向き)IP アドレスと一致しない場合は、DNS レコードを再構成して正しい IP アドレスにマッピングします。
(更新された)DNS レコードが有効になった後、次のコマンドを実行して Order オブジェクトを削除し、TLS 証明書の要求プロセスを再度トリガーします。
kubectl delete order DOMAIN -n NAMESPACE
次のように置き換えます。
- DOMAIN は、使用しているドメインの名前に置き換えます。
- NAMESPACE は、使用する Namespace に置き換えます。
承認エラー
承認エラーは、DNS レコードが時間内にグローバルに伝播されない場合に発生することがあります。その結果、Let's Encrypt はドメインの所有権の検証で不合格になります。
Order ステータスを確認します。ステータス
acmeAuthorizations
フィールドで authz リンクを確認します。URL は次のようになります。https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
リンクを開きます。次のようなメッセージが表示される場合があります。
urn:ietf:params:acme:error:dns
この問題は、DNS の不完全な伝播が原因です。
DNS の伝播エラーを解決するには、次の手順を行います。
- 次のコマンドを実行して、
gke-system
の下のistio-ingress
サービスの外部 IP を取得します。kubectl get svc istio-ingress -n gke-system
次のコマンドを実行して、ドメインの DNS レコードを確認します。
host DOMAIN
DNS レコードの IP アドレスが
gke-system
の下のistio-ingress
サービスの外部 IP と一致しない場合は、ユーザーのドメインを外部 IP にマッピングするように DNS レコードを構成します。(更新された)DNS レコードが有効になった後、次のコマンドを実行して Order オブジェクトを削除し、TLS 証明書の要求プロセスを再度トリガーします。
kubectl delete order DOMAIN -n NAMESPACE
次のように置き換えます。
- DOMAIN は、使用しているドメインの名前に置き換えます。
- NAMESPACE は、ドメイン マッピングに使用する Namespace に置き換えます。
- 次のコマンドを実行して、
限定公開クラスタのデプロイ失敗: Webhook エラーの呼び出しに失敗。
限定公開クラスタへのデプロイが次のメッセージで失敗した場合、ファイアウォールが正しく設定されていない可能性があります。
Error: failed calling webhook "webhook.serving.knative.dev": Post
https://webhook.knative-serving.svc:443/?timeout=30s: context deadline exceeded (Client.Timeout
exceeded while awaiting headers)
限定公開クラスタへのデプロイをサポートするために必要なファイアウォールの変更については、限定公開クラスタでのデプロイの有効化をご覧ください。
サービス レポートのステータスが IngressNotConfigured になる
サービス ステータスに IngressNotConfigured
が表示される場合は、gke-system
Namespace で istio-pilot
Deployment を再起動する必要があります。kubernetes 1.14
で頻繁に見られるこのエラーは、istio_pilot
が VirtualServices
を調整して Envoy 構成を Ingress ゲートウェイに push する準備が整う前にサービスが作成された場合に発生する可能性があります。
この問題を解決するには、次のようなコマンドを使用して Deployment をスケールインし、再度スケールアウトします。
kubectl scale deployment istio-pilot -n gke-system --replicas=0
kubectl scale deployment istio-pilot -n gke-system --replicas=1
リクエスト数とリクエストのレイテンシの指標がない
Workload Identity を有効にしていて、サービスで使用するサービス アカウントに特定の権限が付与されていない場合、サービスはリビジョン リクエスト数とリクエストのレイテンシの指標をレポートしないことがあります。
この問題を修正するには、Workload Identity を使用したクラスタでの指標の有効化セクションの手順を行います。
カスタム ドメインで WebSocket を使用する
デフォルトでは、カスタム ドメイン マッピングに対する WebSocket は無効になっています。
カスタム ドメインで Websocket を有効にするには、次のコマンドを実行して allow_connect: true
で Istio EnvoyFilter オブジェクトを作成します。
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: allowconnect-cluster-local-gateway-tb
namespace: gke-system
spec:
workloadSelector:
labels:
istio: ingress-gke-system
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
portNumber: 8081
filterChain:
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
http2_protocol_options:
allow_connect: true
EOF