本页面介绍问题排查策略以及一些常见错误的解决方案。
对 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-GATEWAY 和 NAMESPACE:
集群版本 | 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-GATEWAY 和 NAMESPACE 替换为上表中的值。这将产生如下所示的输出:
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 证书功能的常见问题。
检查特定网域映射的状态
如需检查特定网域映射的状态,请执行以下操作:
运行以下命令:
kubectl get domainMapping DOMAIN -n NAMESPACE -oyaml
替换
- 将 DOMAIN 替换为您使用的域名。
- 将 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 名称不能与其映射到的路由的主机名完全相同。请使用其他域名来作为 DomainMapping 名称。 | |
ChallengeServingErrored | 系统无法处理 HTTP01 请求。 | 如果 istio-ingress 服务无法处理来自 Let's Encrypt 的请求来验证网域所有权,则可能会发生此错误。 |
|
系统错误
错误代码 | 详细消息 | 问题排查说明 |
OrderErrored AuthzErrored ChallengeErrored |
如果 Let's Encrypt 对网域所有权的验证失败,则会出现这三种类型的错误。 这些错误通常是暂时性错误,Cloud Run 将重新尝试解决错误。 重新尝试的延迟时间以指数增加,最短为 8 秒,最长为 8 小时。 如果您要手动重新尝试解决错误,可以手动删除失败的订单。
|
|
ACMEAPIFailed | 如果 Cloud Run 无法调用 Let's Encrypt,则会出现这种类型的错误。此错误通常是暂时性错误,Cloud Run 将重新尝试解决错误。 如果您要手动重新尝试解决错误,请手动删除失败的订单。
|
|
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 分钟后超时。
检查网域映射状态。对于超时,请在状态输出中查找如下错误消息:
order (test.example.com) timed out (20.0 minutes)
超时问题的一个常见原因是您的 DNS 记录未正确配置,无法将您使用的网域映射到
gke-system
下的istio-ingress
服务的 IP 地址。请运行以下命令来检查 DNS 记录:host DOMAIN
运行以下命令以检查
gke-system
下istio-ingress
服务的外部 IP 地址:kubectl get svc istio-ingress -n gke-system
如果网域的外部 IP 地址与入站 IP 地址不匹配,请重新配置您的 DNS 记录以映射到正确的 IP 地址。
(更新的)DNS 记录生效后,运行以下命令删除订单对象,以重新触发请求 TLS 证书的过程:
kubectl delete order DOMAIN -n NAMESPACE
替换
- 将 DOMAIN 替换为您使用的域名。
- 将 NAMESPACE 替换为您使用的命名空间。
授权失败
如果 DNS 记录未及时传播到全球范围,则可能会出现授权失败的问题。在这种情况下,Let's Encrypt 无法验证网域的所有权。
检查订单状态。请在状态的
acmeAuthorizations
字段下找到 authz 链接。网址应如下所示: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 地址不匹配,请配置 DNS 记录以将用户的网域映射到外部 IP 地址。(更新的)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