トラブルシューティング

このページでは、一般的な問題に対するトラブルシューティングの方法と解決策を説明します。

Knative serving のトラブルシューティングで最初に行うことは、コンテナ イメージをローカルで実行できるかどうか確認することです。

アプリケーションがローカルで実行されていない場合は、その原因を突き止め、問題を修正する必要があります。デプロイされたプロジェクトをデバッグするには、Cloud Logging を使用します。

Knative serving のトラブルシューティングを行う際は、以降のセクションで問題の解決方法をご覧ください。

コマンドラインの出力を確認する

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 コンソールの Knative serving のページを使用して、リクエストログとコンテナログを確認できます。詳細については、ログの記録と表示をご覧ください。

Cloud Logging を使用する場合、フィルタするリソースは Kubernetes コンテナです。

サービスのステータスを確認する

次のコマンドを実行して、デプロイされた Knative serving サービスのステータスを取得します。

gcloud run services describe SERVICE

--format yaml(status) または --format json(status) を追加すると、完全なステータスを取得できます。次に例を示します。

gcloud run services describe SERVICE --format 'yaml(status)'

status の条件が、失敗の原因を特定する際に役立ちます。条件には、TrueFalseUnknown などがあります。

  • Ready: True は、サービスが構成され、トラフィックを受信できる状態であることを示します。
  • ConfigurationReady: True は、基盤となる構成の準備が完了していることを示します。False または Unknown の場合は、最新のリビジョンのステータスを表示する必要があります。
  • RoutesReady: True は、基盤となるルートの準備が完了していることを示します。False または Unknown の場合は、ルートのステータスを表示する必要があります。

ステータス条件の詳細については、Knative のエラーシグナルをご覧ください。

ルートのステータスを確認する

Knative serving サービスは、サービスのリビジョンに対する現在のルーティング状態を表すルートを管理します。

ルート全体のステータスを確認するには、サービスのステータスを確認します。

gcloud run services describe SERVICE --format 'yaml(status)'

statusRoutesReady 条件で、ルートのステータスを確認できます。

ルートのステータスをさらに診断するには、次のコマンドを実行します。

kubectl get route SERVICE -o yaml

status の条件は、失敗の理由を表しています。まとめると次のようになります。

  • Ready は、サービスが構成され、利用可能なバックエンドがあるかどうかを示します。true の場合、ルートは正しく構成されています。

  • AllTrafficAssigned は、サービスが適切に構成され、使用可能なバックエンドがあるかどうかを示します。この条件の statusTrue でない場合:

    • サービスのリビジョン間で分割されたトラフィックの合計が 100% になるかどうかを確認します。

      gcloud run services describe SERVICE

      そうでない場合は、gcloud run services update-traffic コマンドを使用してトラフィック分割を調整します。

    • トラフィックを受信しているリビジョンについて、リビジョンのステータスを確認します。

  • IngressReady は Ingress の準備が完了しているかどうかを示します。この条件の statusTrue でない場合は、Ingress のステータスを確認します。

  • CertificateProvisioned は、Knative 証明書がプロビジョニングされたかどうかを示します。この条件の statusTrue ではない場合、マネージド TLS の問題のトラブルシューティングを行います。

ステータス条件の詳細については、Knative のエラー条件とレポートをご覧ください。

Ingress のステータスを確認する

Knative serving は、ロードバランサ サービス(istio-ingressgateway)を使用して、クラスタ外部からの受信トラフィックを処理します。

ロードバランサの外部 IP を取得するには、次のコマンドを実行します。

kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE

ASM-INGRESS-NAMESPACE は、Cloud Service Mesh Ingress が配置されている Namespace に置き換えます。Cloud Service Mesh をデフォルトの構成を使用してインストールした場合は、istio-system を指定します。

出力は次のようになります。

NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
istio-ingressgateway   LoadBalancer   XX.XX.XXX.XX   pending      80:32380/TCP,443:32390/TCP,32400:32400/TCP

ここで、EXTERNAL-IP の値は、ロードバランサの外部 IP アドレスです。

EXTERNAL-IPpending の場合は、後述の EXTERNAL-IP が長時間 pending になっているをご覧ください。

リビジョンのステータスを確認する

Knative serving サービスの最新リビジョンを取得するには、次のコマンドを実行します。

gcloud run services describe SERVICE --format='value(status.latestCreatedRevisionName)'

特定の Knative serving リビジョンのステータスを取得するには、次のコマンドを実行します。

gcloud run revisions describe REVISION

完全なステータスを取得するには、--format yaml(status) または --format json(status) を追加します。

gcloud run revisions describe REVISION --format yaml(status)

status の条件が失敗の理由を表しています。まとめると次のようになります。

  • Ready は、ランタイム リソースが使用可能かどうかを示します。これが true の場合、リビジョンは正しく構成されています。
  • ResourcesAvailable は、基盤となる Kubernetes リソースがプロビジョニングされたかどうかを示します。この条件の statusTrue でない場合は、Pod のステータスを確認してください。
  • ContainerHealthy は、リビジョン準備チェックが完了したかどうかを示します。この条件の statusTrue でない場合は、Pod のステータスを確認してください。
  • Active は、リビジョンがトラフィックを受信しているかどうかを示します。

次のいずれかの条件の statusTrue ではない場合は、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 の詳細情報が表示されます。conditionscontainerStatuses などのフィールドに重要な情報が含まれます。

kubectl get pod POD-NAME -o yaml

EXTERNAL-IP が長時間 <pending> になっている

クラスタの作成後すぐに外部 IP アドレスが取得されず、外部 IP が pending と表示される場合があります。たとえば、次のコマンドを呼び出すと、このような状況になることがあります。

ロードバランサの外部 IP を取得するには、次のコマンドを実行します。

kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE

ASM-INGRESS-NAMESPACE は、Cloud Service Mesh Ingress が配置されている Namespace に置き換えます。Cloud Service Mesh をデフォルトの構成を使用してインストールした場合は、istio-system を指定します。

出力は次のようになります。

NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
istio-ingressgateway   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-ingressgateway -n INGRESS_NAMESPACE
ここで、INGRESS_NAMESPACE は ASM Ingress の Namespace で、デフォルトは istio-system です。 これにより、次のような出力が生成されます。
Name:                     istio-ingressgateway
Namespace:                INGRESS_NAMESPACE
Labels:                   app=istio-ingressgateway
                          istio=ingressgateway
                          istio.io/rev=asm-1102-3
                          operator.istio.io/component=IngressGateways
                          operator.istio.io/managed=Reconcile
                          operator.istio.io/version=1.10.2-asm.3
                          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=istio-ingressgateway,istio=ingressgateway
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 コンソールの [IAM と管理] ページへ移動して、追加の割り当てをリクエストしてください。

外部 IP アドレスが割り当てられるまで、ゲートウェイは再試行を繰り返します。この処理には数分かかることがあります。

カスタム ドメインとマネージド TLS のトラブルシューティング

カスタム ドメインマネージド TLS 証明書機能の一般的な問題を解決するには、以下のトラブルシューティング手順を実施します。

非公開の内部ネットワーク用のカスタム ドメイン

カスタム ドメインを非公開の内部ネットワーク内の Knative serving クラスタまたはサービスにマッピングした場合、マネージド TLS 証明書を無効にする必要があります。そうしないと、ドメイン構成が ready 状態に到達しません。デフォルトでは、内部ロードバランサは認証局と外部で通信できません。

特定のドメイン マッピングのステータスを確認する

特定のドメイン マッピングのステータスを確認するには:

  1. 次のコマンドを実行します。

    gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE

    次のように置き換えます。

    • DOMAIN は、使用しているドメインの名前に置き換えます。
    • NAMESPACE は、ドメイン マッピングに使用する Namespace に置き換えます。
  2. このコマンドからの yaml の結果で、CertificateProvisioned フィールドの条件を確認して、エラーの性質を判断します。

  3. エラーが表示される場合は、次の表のいずれかのエラーと一致するはずです。表の指示に従って問題を解決してください。

ユーザー構成エラー

エラーコード 詳細
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.your-domain.com:
see https://letsencrypt.org/docs/rate-limits/

Let's Encrypt の割り当てを超過しました。該当するホストの Let's Encrypt 証明書の割り当てを増やす必要があります。

InvalidDomainMappingName メッセージ: DomainMapping name %s cannot be the same as Route URL host %s.

DomainMapping の名前は、マップ先の Route のホストと同一にすることはできません。DomainMapping の名前には別のドメインを使用してください。

ChallengeServingErrored メッセージ: System failed to serve HTTP01 request.

このエラーは、istio-ingressgateway サービスが Let's Encrypt からのリクエストに対応してドメインの所有権を確認できない場合に発生します。

  1. Virtual Private Cloud を使用せずに、公共のインターネットから istio-ingressgateway サービスにアクセスできることを確認します。
  2. istio-ingressgateway サービスが URL http://DOMAIN/.well-known/acme-challenge/... からのリクエストを受け付けることを確認します。DOMAIN は、検証されているドメインです。

システムエラー

エラーコード 詳細
OrderErrored

AuthzErrored

ChallengeErrored

この 3 種類のエラーは、Let's Encrypt によるドメイン所有権の確認が失敗した場合に発生します。

通常、これらのエラーは一時的なエラーであり、Knative serving によって再試行されます。

再試行の遅延時間は、最小 8 秒から最大 8 時間まで指数関数的に変動します。

このエラーを手動で再試行する場合は、失敗した Order を手動で削除します。

kubectl delete order DOMAIN -n NAMESPACE

ACMEAPIFailed この種類のエラーは、Knative serving による Let's Encrypt の呼び出しが失敗したときに発生します。通常は一時的なエラーであり、Knative serving によって再試行されます。

このエラーを手動で再試行する場合は、失敗した Order を手動で削除します。

kubectl delete order DOMAIN -n NAMESPACE

UnknownErrored 不明なシステムエラーを示しています。GKE クラスタではめったに発生しません。このエラーが表示された場合は、Cloud サポートに問い合わせて、デバッグの支援を依頼してください。

Order ステータスを確認する

Order ステータスは、Let's Encrypt との対話プロセスを記録するため、Let's Encrypt に関連する問題のデバッグに使用できます。必要に応じて、次のコマンドを実行して Order ステータスを確認します。

kubectl get order DOMAIN -n NAMESPACE -oyaml

次のように置き換えます。

  • DOMAIN は、使用しているドメインの名前に置き換えます。
  • NAMESPACE は、ドメイン マッピングに使用する Namespace に置き換えます。

Order が成功した場合は、結果に発行された証明書とその他の情報が含まれます。

Order のタイムアウト

証明書を取得できない場合、Order オブジェクトは 20 分後にタイムアウトします。

  1. ドメイン マッピングのステータスを確認します。タイムアウトした場合は、ステータス出力で次のようなエラー メッセージを探します。

    order (test.your-domain.com) timed out (20.0 minutes)
  2. タイムアウトの問題の一般的な原因は、使用しているドメインを Ingress サービスの IP アドレスにマッピングするように DNS レコードが適切に構成されていないことです。次のコマンドを実行して DNS レコードを確認します。

    host DOMAIN
  3. Ingress ロードバランサの外部 IP アドレスを確認します。

    ロードバランサの外部 IP を取得するには、次のコマンドを実行します。

    kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
    

    ASM-INGRESS-NAMESPACE は、Cloud Service Mesh Ingress が配置されている Namespace に置き換えます。Cloud Service Mesh をデフォルトの構成を使用してインストールした場合は、istio-system を指定します。

    出力は次のようになります。

    NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
    istio-ingressgateway   LoadBalancer   XX.XX.XXX.XX   pending      80:32380/TCP,443:32390/TCP,32400:32400/TCP
    

    ここで、EXTERNAL-IP の値は、ロードバランサの外部 IP アドレスです。

    ドメインの外部 IP アドレスが上り(内向き)IP アドレスと一致しない場合は、DNS レコードを再構成して正しい IP アドレスにマッピングします。

  4. (更新された)DNS レコードが有効になった後、次のコマンドを実行して Order オブジェクトを削除し、TLS 証明書の要求プロセスを再度トリガーします。

    kubectl delete order DOMAIN -n NAMESPACE

    次のように置き換えます。

    • DOMAIN は、使用しているドメインの名前に置き換えます。
    • NAMESPACE は、使用する Namespace に置き換えます。

承認エラー

承認エラーは、DNS レコードが時間内にグローバルに伝播されない場合に発生することがあります。その結果、Let's Encrypt はドメインの所有権の検証で不合格になります。

  1. Order ステータスを確認します。ステータス acmeAuthorizations フィールドで authz リンクを確認します。URL は次のようになります。

    https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
  2. リンクを開きます。次のようなメッセージが表示される場合があります。

    urn:ietf:params:acme:error:dns

    この問題は、DNS の不完全な伝播が原因です。

  3. DNS の伝播エラーを解決するには、次の操作を行います。

    1. Ingress ロードバランサの外部 IP アドレスを確認します。

      ロードバランサの外部 IP を取得するには、次のコマンドを実行します。

      kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
      

      ASM-INGRESS-NAMESPACE は、Cloud Service Mesh Ingress が配置されている Namespace に置き換えます。Cloud Service Mesh をデフォルトの構成を使用してインストールした場合は、istio-system を指定します。

      出力は次のようになります。

      NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
      istio-ingressgateway   LoadBalancer   XX.XX.XXX.XX   pending      80:32380/TCP,443:32390/TCP,32400:32400/TCP
      

      ここで、EXTERNAL-IP の値は、ロードバランサの外部 IP アドレスです。

    2. 次のコマンドを実行して、ドメインの DNS レコードを確認します。

      host DOMAIN

      DNS レコードの IP アドレスが Ingress ロードバランサの外部 IP と一致しない場合は、ユーザーのドメインを外部 IP にマッピングするように DNS レコードを構成します。

    3. (更新された)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 が表示され、クラスタ内コントロール プレーン Cloud Service Mesh を使用している場合は、istio-system Namespace で istiod Deployment の再起動が必要になることがあります。kubernetes 1.14 で頻繁に見られるこのエラーは、istiodVirtualServices を調整して Envoy 構成を Ingress ゲートウェイに push する準備が整う前にサービスが作成された場合に発生する可能性があります。

この問題を解決するには、次のようなコマンドを使用して Deployment をスケールインし、再度スケールアウトします。

kubectl scale deployment istiod -n istio-system --replicas=0
kubectl scale deployment istiod -n istio-system --replicas=1

リクエスト数とリクエストのレイテンシの指標がない

Workload Identity を有効にしていて、サービスで使用するサービス アカウントに特定の権限が付与されていない場合、サービスはリビジョン リクエスト数とリクエストのレイテンシの指標をレポートしないことがあります。

この問題を修正するには、Workload Identity を使用したクラスタでの指標の有効化の説明に従います。