本页面介绍问题排查策略以及一些常见错误的解决方案。
对 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 容器。
检查 Service 状态
运行以下命令以获取已部署的 Knative serving 服务的状态:
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 状态
每项 Knative serving 服务都会管理一个路由,它表示针对服务的修订版本的当前路由状态。
您可以通过查看服务状态来检查 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 状态
Knative serving 使用一个名为 istio-ingressgateway
的负载均衡器服务,该服务负责处理从集群外部传入的流量。
如需获取负载均衡器的外部 IP,请运行以下命令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
将 ASM-INGRESS-NAMESPACE 替换为 Cloud Service Mesh 入站流量所在的命名空间。如果您使用默认配置安装了 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-IP 为 pending
,请参阅下面的 EXTERNAL-IP 长时间为 pending
。
检查 Revision 状态
如需获取 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 资源。如果此条件的
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
状态。例如,您可以通过调用以下命令来确认这一点:
如需获取负载均衡器的外部 IP,请运行以下命令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
将 ASM-INGRESS-NAMESPACE 替换为 Cloud Service Mesh 入站流量所在的命名空间。如果您使用默认配置安装了 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 的命名空间,默认为“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
状态。默认情况下,内部负载均衡器无法与证书授权机构进行外部通信。
检查特定网域映射的状态
如需检查特定网域映射的状态,请执行以下操作:
运行以下命令:
gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE
替换
- 将 DOMAIN 替换为您使用的域名。
- 将 NAMESPACE 替换为您用于网域映射的命名空间。
在此命令的
yaml
结果中,检查CertificateProvisioned
字段的条件以确定错误的性质。如果显示错误,则该错误应与下表中的某个错误相匹配。请按照表格中的建议解决问题。
用户配置错误
错误代码 | 详细信息 |
---|---|
DNSErrored | Message:
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 名称不能与其映射到的路由的主机名完全相同。请使用其他域名来作为 DomainMapping 名称。 |
ChallengeServingErrored | 消息:System failed to serve HTTP01 request.
如果
|
系统错误
错误代码 | 详细信息 |
---|---|
OrderErrored
AuthzErrored ChallengeErrored |
如果 Let's Encrypt 对网域所有权的验证失败,则会出现这三种类型的错误。 这些错误通常是暂时性错误,Knative serving 将重新尝试解决错误。 重新尝试的延迟时间以指数增加,最短为 8 秒,最长为 8 小时。 如果您要手动重新尝试解决错误,可以手动删除失败的订单。
|
ACMEAPIFailed | 如果 Knative serving 无法调用 Let's Encrypt,则会出现这种类型的错误。此错误通常是暂时性错误,Knative serving 将重新尝试解决错误。 如果您要手动重新尝试解决错误,请手动删除失败的订单。
|
UnknownErrored | 此错误表示 GKE 集群中极少出现的未知系统错误。如果您看到此错误,请与 Cloud 支持团队联系以获得调试帮助。 |
检查订单状态
订单状态记录了与 Let's Encrypt 交互的过程,因此可用于调试与 Let's Encrypt 相关的问题。如果需要,请通过运行以下命令检查订单的状态:
kubectl get order DOMAIN -n NAMESPACE -oyaml
替换
- 将 DOMAIN 替换为您使用的域名。
- 将 NAMESPACE 替换为您用于网域映射的命名空间。
如果订单成功,则结果将包含已发放的证书以及其他信息。
订单超时
如果订单对象仍然无法获取证书,则会在 20 分钟后超时。
检查网域映射状态。对于超时,请在状态输出中查找如下错误消息:
order (test.your-domain.com) timed out (20.0 minutes)
超时问题的一个常见原因是您的 DNS 记录未正确配置,无法将您使用的网域映射到入站流量服务的 IP 地址。请运行以下命令来检查 DNS 记录:
host DOMAIN
检查入站流量负载均衡器的外部 IP 地址:
如需获取负载均衡器的外部 IP,请运行以下命令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
将 ASM-INGRESS-NAMESPACE 替换为 Cloud Service Mesh 入站流量所在的命名空间。如果您使用默认配置安装了 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 地址。
(更新的)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 传播错误,请执行以下操作:
检查入站流量负载均衡器的外部 IP 地址:
如需获取负载均衡器的外部 IP,请运行以下命令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
将 ASM-INGRESS-NAMESPACE 替换为 Cloud Service Mesh 入站流量所在的命名空间。如果您使用默认配置安装了 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 地址。
通过运行以下命令检查网域的 DNS 记录:
host DOMAIN
如果 DNS 记录的 IP 地址与入站流量负载均衡器的外部 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
,您可能需要在 istio-system
命名空间中重启 istiod
部署(如果您使用的是集群内控制平面 Cloud Service Mesh)。此错误在 kubernetes 1.14
上更加常见;如果服务是在 istiod
准备开始协调 VirtualServices
并将 Envoy 配置推送到入站网关之前创建的,则可能会出现此错误。
如需解决此问题,请缩减部署规模,然后使用类似如下的命令再次扩大部署规模:
kubectl scale deployment istiod -n istio-system --replicas=0
kubectl scale deployment istiod -n istio-system --replicas=1
缺失请求数和请求延迟时间指标
如果您启用了 Workload Identity,并且未向您的服务使用的服务账号授予某些权限,则您的服务可能不会报告修订版本请求计数和请求延迟时间指标。
您可以按照使用 Workload Identity 启用集群上的指标部分中的步骤来解决此问题。