本页面介绍问题排查策略以及一些常见错误的解决方案。
对 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 容器。
检查 Service 状态
运行以下命令以获取已部署的 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 错误信令。
检查 Route 状态
每项 Cloud Run for Anthos 服务都会管理一个路由,它表示针对服务的修订版本的当前路由状态。
您可以通过查看服务状态来检查 Route 的整体状态:
gcloud run services describe SERVICE --format 'yaml(status)'
status
中的 RoutesReady 条件提供 Route 的状态。
您可以通过运行以下命令进一步诊断 Route 状态:
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 使用一个名为 istio-ingress
的 Kubernetes 负载均衡器服务,该服务负责处理从集群外部传入的流量。
如需获取 Ingress 的外部 IP 地址,请使用
kubectl get svc istio-ingress -n gke-system
如果 EXTERNAL-IP
为 pending
,请参阅下面的 EXTERNAL-IP 长时间处于 pending
状态。
检查 Revision 状态
如需获取 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 状态
要获取所有部署的 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
选择一个集群,然后使用以下命令查看其 status
的详细信息。一些有用的字段是 conditions
和 containerStatuses
:
kubectl get pod POD-NAME -o yaml
EXTERNAL-IP 长时间处于 <pending>
状态
有时,您可能无法在创建集群后立即获得外部 IP 地址,从而将外部 IP 地址视为 pending
状态。例如,您可以通过调用以下命令来确认这一点:
要获取 Istio 入站网关的外部 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 替换为您用于网域映射的命名空间。
在此命令的
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 for Anthos 将重新尝试解决错误。 重新尝试的延迟时间以指数增加,最短为 8 秒,最长为 8 小时。 如果您要手动重新尝试解决错误,可以手动删除失败的订单。
|
|
ACMEAPIFailed | 如果 Cloud Run for Anthos 无法调用 Let's Encrypt,则会出现这种类型的错误。此错误通常是暂时性错误,Cloud Run for Anthos 将重新尝试解决错误。 如果您要手动重新尝试解决错误,请手动删除失败的订单。
|
|
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: 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-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