对 Cloud Run for Anthos on Google Cloud 进行问题排查

本页面介绍问题排查策略以及一些常见错误的解决方案。

对 Cloud Run for Anthos on Google Cloud 进行问题排查时,请先确认您可以在本地运行容器映像

如果您的应用未在本地运行,您将需要对其进行诊断和修复。 您应该使用 Cloud Logging 来帮助调试已部署的项目。

对 Cloud Run for Anthos on Google Cloud 进行问题排查时,请参阅以下部分,了解可能的问题解决方案。

检查命令行输出

如果您使用 gcloud 命令行,则需要检查命令输出来确定该命令是否运行成功。例如,如果您的部署未成功终止,则您应该会看到一条错误消息,其中描述了失败的原因。

导致部署失败的最可能原因是清单配置错误或命令不正确。例如,以下输出表明路由流量百分比的总和必须配置为 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 或 Cloud Console 中的 Cloud Run 页面来检查请求日志和容器日志。如需查看完整的详细信息,请阅读记录和查看日志

如果您使用 Cloud Logging,则需要过滤的资源是 Kubernetes 容器

检查 Route 状态

您可以运行以下命令来获取用于部署应用的 Route 对象的状态:

kubectl get route ROUTE

status 中的 conditions 提供失败的原因。

检查 Istio 路由

您可以将通过检查 Route 状态而获得的 Istio Route 对象配置与 Istio RouteRule 对象的配置进行比较。

请输入以下命令,并将 ROUTERULE-NAME 替换为适当的值:

kubectl get routerule ROUTERULE-NAME -o yaml

如果您不知道路由规则的名称,请使用 kubectl get routerule 查找。

该命令会返回路由规则的配置。您可以将路由与路由规则之间的网域进行比较;它们应当一致。

检查 Revision 状态

如果您使用 Configuration 来配置路由,请运行以下命令以获取为您的部署创建的 Revision 的名称,并在 Route 的 .yaml 文件中查找配置名称:

kubectl get configuration CONFIGURATION-NAME -o jsonpath="{.status.latestCreatedRevisionName}"

如果您直接使用 Revision 配置 Route,请在 Route yaml 文件中查找 Revision 名称。

然后运行以下命令:

kubectl get revision REVISION-NAME -o yaml

对于处于就绪状态的 Revision,status 应包含以下条件:

conditions:
  - reason: ServiceReady
    status: "True"
    type: Ready

如果您看到此条件,请进行如下检查以继续调试:

  • 检查 Pod 状态
  • 检查应用日志
  • 检查 Istio 路由

如果您看到其他条件,可以按照如下所述进一步调试:

检查 Pod 状态

要获取所有部署的 Pod,请使用以下命令:

kubectl get pods

此命令应列出所有 Pod 的简要状态。例如:

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

请选择一个 Pod,然后使用以下命令查看其详细状态信息。conditions 和 containerStatuses 字段会为您提供实用信息:

kubectl get pod POD-NAME -o yaml

EXTERNAL-IP 长时间处于 <pending> 状态

有时,您可能无法在创建集群后立即获得外部 IP 地址,从而将外部 IP 地址视为 pending 状态。例如,您可以通过调用以下命令来确认这一点:

要获取 Istio 入站网关的外部 IP 地址,请执行以下操作:

kubectl get svc ISTIO-GATEWAY -n NAMESPACE 
按如下所示替换 ISTIO-GATEWAYNAMESPACE
集群版本 ISTIO-GATEWAY NAMESPACE
1.15.3-gke.19 及更高版本
1.14.3-gke.12 及更高版本
1.13.10-gke.8 及更高版本
istio-ingress gke-system
所有其他版本 istio-ingressgateway istio-system

生成的输出类似如下所示:

NAME            TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
ISTIO-GATEWAY    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-GATEWAY -n NAMESPACE

注意将 ISTIO-GATEWAYNAMESPACE 替换为上表中的值。这将产生如下所示的输出:

stem
Name:                     ISTIO-GATEWAY
Namespace:                NAMESPACE
Labels:                   addonmanager.kubernetes.io/mode=Reconcile
                          app=ISTIO-GATEWAY
                          chart=gateways-1.0.3
                          heritage=Tiller
                          istio=ingressgateway
                          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=ISTIO-GATEWAY,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 Console 中的“IAM 和管理”页面来申请增加配额。

网关将继续重试,直到分配外部 IP 地址。 这可能需要几分钟的时间。

排查代管式传输层安全协议 (TLS) 问题

使用下列问题排查步骤解决有关代管式 TLS 证书功能的常见问题。

检查特定网域映射的状态

如需检查特定网域映射的状态,请执行以下操作:

  1. 运行以下命令:

    kubectl get domainMapping DOMAIN -n NAMESPACE -oyaml

    替换

    • DOMAIN 替换为您使用的域名。
    • 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.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 名称不能与其映射到的路由的主机名完全相同。请使用其他域名来作为 DomainMapping 名称。
ChallengeServingErrored 系统无法处理 HTTP01 请求。 如果 istio-ingress 服务无法处理来自 Let's Encrypt 的请求来验证网域所有权,则可能会发生此错误。
  1. 确保可以在不使用 Virtual Private Cloud 的情况下通过公共互联网访问 istio-ingress 服务。
  2. 确定您的 istio-ingress 服务接受来自网址 http://DOMAIN/.well-known/acme-challenge/... 的请求,其中 DOMAIN 是待验证的网域。

系统错误

错误代码 详细消息 问题排查说明
OrderErrored

AuthzErrored

ChallengeErrored

如果 Let's Encrypt 对网域所有权的验证失败,则会出现这三种类型的错误。

这些错误通常是暂时性错误,Cloud Run 将重新尝试解决错误。

重新尝试的延迟时间以指数增加,最短为 8 秒,最长为 8 小时。

如果您要手动重新尝试解决错误,可以手动删除失败的订单。

kubectl delete order DOMAIN -n NAMESPACE

ACMEAPIFailed 如果 Cloud Run 无法调用 Let's Encrypt,则会出现这种类型的错误。此错误通常是暂时性错误,Cloud Run 将重新尝试解决错误。

如果您要手动重新尝试解决错误,请手动删除失败的订单。

kubectl delete order DOMAIN -n NAMESPACE

UnknownErrored 此错误表示 GKE 集群中极少出现的未知系统错误。如果您看到此错误,请与 Cloud 支持团队联系以获得调试帮助。

检查订单状态

订单状态记录了与 Let's Encrypt 交互的过程,因此可用于调试与 Let's Encrypt 相关的问题。如果需要,请通过运行以下命令检查订单的状态:

kubectl get order DOMAIN -n NAMESPACE -oyaml

替换

  • DOMAIN 替换为您使用的域名。
  • NAMESPACE 替换为您用于网域映射的命名空间。

如果订单成功,则结果将包含已发放的证书以及其他信息。

超出 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 文档

订单超时

如果订单对象仍然无法获取证书,则会在 20 分钟后超时。

  1. 检查网域映射状态。对于超时,请在状态输出中查找如下错误消息:

    order (test.example.com) timed out (20.0 minutes)
  2. 超时问题的一个常见原因是您的 DNS 记录未正确配置,无法将您使用的网域映射到 gke-system 下的 istio-ingress 服务的 IP 地址。请运行以下命令来检查 DNS 记录:

    host DOMAIN
  3. 运行以下命令以检查 gke-systemistio-ingress 服务的外部 IP 地址:

    kubectl get svc istio-ingress -n gke-system

    如果网域的外部 IP 地址与入站 IP 地址不匹配,请重新配置您的 DNS 记录以映射到正确的 IP 地址。

  4. (更新的)DNS 记录生效后,运行以下命令删除订单对象,以重新触发请求 TLS 证书的过程:

    kubectl delete order DOMAIN -n NAMESPACE

    替换

    • DOMAIN 替换为您使用的域名。
    • NAMESPACE 替换为您使用的命名空间。

授权失败

如果 DNS 记录未及时传播到全球范围,则可能会出现授权失败的问题。在这种情况下,Let's Encrypt 无法验证网域的所有权。

  1. 检查订单状态。请在状态的 acmeAuthorizations 字段下找到 authz 链接。网址应如下所示:

    https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
  2. 打开链接。如果您看到类似如下消息:

    urn:ietf:params:acme:error:dns

    则问题就在于 DNS 传播不完整。

  3. 如需解决 DNS 传播错误,请执行以下操作:

    1. 通过运行以下命令获取 gke-systemistio-ingress 服务的外部 IP 地址:
      kubectl get svc istio-ingress -n gke-system
    2. 通过运行以下命令检查网域的 DNS 记录:

      host DOMAIN

      如果 DNS 记录的 IP 地址与 gke-systemistio-ingress 服务的外部 IP 地址不匹配,请配置 DNS 记录以将用户的网域映射到外部 IP 地址。

    3. (更新的)DNS 记录生效后,运行以下命令删除订单对象,以重新触发请求 TLS 证书的过程:

      kubectl delete order DOMAIN -n NAMESPACE

    替换

    • DOMAIN 替换为您使用的域名。
    • NAMESPACE 替换为您用于网域映射的命名空间。

专用集群部署失败:“调用 webhook 失败”错误

如果您对专用集群的部署失败并显示以下消息,则您的防火墙可能未正确设置:

ERROR: (gcloud.run.deploy) 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 命名空间中重启 istio-pilot 部署。此错误在 kubernetes 1.14 上更加常见;如果服务是在 istio_pilot 准备开始协调 VirtualServices 并将 Envoy 配置推送到入站网关之前创建的,则可能会出现此错误。

如需解决此问题,请缩减部署规模,然后使用类似如下的命令再次扩大部署规模:

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-cluser-local-gateway
  namespace: gke-system
spec:
  workloadSelector:
    labels:
      app: cluster-local-gateway
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      listener:
        portNumber: 80
        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