本頁面提供一些常見錯誤的疑難排解策略以及解決方案。
排解 Knative 服務問題時,請先確認您可以在本機執行容器映像檔。
如果您的應用程式無法在本機執行,您將需要診斷該應用程式並修正問題。 請使用 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 服務頁面,檢查要求記錄和容器記錄。如需完整的詳細資料,請參閱「記錄及查看記錄」。
如果使用 Cloud Logging,則您必須篩選 Kubernetes 容器資源。
檢查服務狀態
執行下列指令,取得已部署的 Knative 服務服務狀態:
gcloud run services describe SERVICE
您可以新增 --format yaml(status)
或 --format json(status)
,取得完整狀態,例如:
gcloud run services describe SERVICE --format 'yaml(status)'
status
中的狀況有助於找出失敗原因。條件可包括 True
、False
或 Unknown
:
- 就緒:
True
表示服務已設定完成,可以接收流量。 - ConfigurationReady:
True
表示基礎設定已準備就緒。如果是False
或Unknown
,請查看最新修訂版本的狀態。 - RoutesReady:
True
表示基礎路徑已準備就緒。如果是False
或Unknown
,請查看路徑狀態。
如要進一步瞭解狀態條件,請參閱「Knative 錯誤信號」。
檢查轉送狀態
每個 Knative 服務都會管理 Route,代表服務修訂版本的目前路由狀態。
如要查看路線的整體狀態,請查看服務狀態:
gcloud run services describe SERVICE --format 'yaml(status)'
status
中的 RoutesReady 狀況會提供 Route 的狀態。
您可以執行下列指令,進一步診斷路徑狀態:
kubectl get route SERVICE -o yaml
status
中的狀況提供失敗原因。您還是可以透過 Google 相簿取得這些內容:
「就緒」表示服務已設定且有可用的後端。如果這是
true
,表示路徑已正確設定。AllTrafficAssigned 會指出服務是否已正確設定,且有可用的後端。如果這個條件的
status
不是True
:請檢查服務各修訂版本的流量拆分加總是否為 100%:
gcloud run services describe SERVICE
如果不是,請使用
gcloud run services update-traffic
指令調整流量分配。請嘗試檢查接收流量的修訂版本狀態。
IngressReady:指出 Ingress 是否已準備就緒。 如果這個條件的
status
不是True
,請嘗試檢查輸入狀態。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 Ingress 所在的命名空間。如果您使用預設設定安裝 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
」。
檢查修訂版本狀態
如要取得 Knative 服務的最新修訂版本,請執行下列指令:
gcloud run services describe SERVICE --format='value(status.latestCreatedRevisionName)'
執行下列指令,取得特定 Knative 服務修訂版本的狀態:
gcloud run revisions describe REVISION
您可以新增 --format yaml(status)
或 --format json(status)
,取得完整狀態:
gcloud run revisions describe REVISION --format yaml(status)
status
中的狀況提供失敗原因。您還是可以透過 Google 相簿取得這些內容:
- 「就緒」:表示執行階段資源是否已準備就緒。如果是
true
,表示修訂版本已正確設定。 - ResourcesAvailable 會指出基礎 Kubernetes 資源是否已佈建。如果這個條件的
status
不是True
,請嘗試檢查 Pod 狀態。 - ContainerHealthy:指出修訂版本就緒檢查是否已完成。
如果這個條件的
status
不是True
,請嘗試檢查 Pod 狀態。 - 有效:表示修訂版本是否正在接收流量。
如果上述任一條件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 Ingress 所在的命名空間。如果您使用預設設定安裝 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
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 & Admin」(IAM 與管理) 頁面,要求額外配額。
閘道會繼續嘗試,直到指派外部 IP 位址為止。這項作業可能需要幾分鐘才能完成。
排解自訂網域和受管理 TLS 問題
請按照下列疑難排解步驟,解決自訂網域和代管傳輸層安全標準 (TLS) 憑證功能的一般問題。
私有內部網路的自訂網域
如果您將自訂網域對應至 Knative 服務叢集,或私人內部網路中的服務,則必須停用代管 TLS 憑證,否則網域設定將無法達到 ready
狀態。根據預設,內部負載平衡器無法與外部的憑證授權單位通訊。
查看特定網域對應的狀態
如要查看特定網域對應的狀態,請按照下列步驟操作:
執行下列指令:
gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE
取代
- DOMAIN 改成您使用的網域名稱。
- NAMESPACE 改成您用於網域對應的命名空間。
在上述指令的
yaml
結果中,檢查CertificateProvisioned
欄位的條件,判斷錯誤性質。如果顯示錯誤,應該會與下方表格中的其中一個錯誤相符。請按照表格中的建議解決問題。
使用者設定錯誤
錯誤代碼 | 詳細資料 |
---|---|
DNSErrored | 訊息:
DNS 記錄設定不正確。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 名稱「%s」不得與 Route URL 主機「%s」相同。
DomainMapping 名稱不得與對應的 Route 主機完全相同。為 DomainMapping 名稱使用其他網域。 |
ChallengeServingErrored | 訊息:系統無法提供 HTTP01 要求。
如果
|
系統錯誤
錯誤代碼 | 詳細資料 |
---|---|
OrderErrored
AuthzErrored ChallengeErrored |
如果 Let's Encrypt 無法驗證網域擁有權,就會發生這 3 種錯誤。 這些通常是暫時性錯誤,Knative 服務會重試。 重試延遲時間會呈指數成長,最短為 8 秒,最長為 8 小時。 如要手動重試錯誤,可以手動刪除失敗的訂單。
|
ACMEAPIFailed | 如果 Knative Serving 無法呼叫 Let's Encrypt,就會發生這類錯誤。這通常是暫時性錯誤,Knative 服務會重試。 如要手動重試錯誤,請手動刪除失敗的訂單。
|
UnknownErrored | 這個錯誤表示發生不明系統錯誤,這在 GKE 叢集中應該非常罕見。如果看到這則訊息,請與 Cloud 支援團隊聯絡,尋求偵錯協助。 |
查看訂單狀態
「訂單狀態」會記錄與 Let's Encrypt 互動的過程,因此可用於偵錯與 Let's Encrypt 相關的問題。如有必要,請執行下列指令,檢查訂單狀態:
kubectl get order DOMAIN -n NAMESPACE -oyaml
取代
- DOMAIN 改成您使用的網域名稱。
- NAMESPACE 改成您用於網域對應的命名空間。
如果訂單成功,結果會顯示核發的認證和其他資訊。
訂單逾時
如果 Order 物件在 20 分鐘後仍無法取得憑證,就會逾時。
檢查網域對應狀態。如為逾時,請在狀態輸出中尋找類似以下的錯誤訊息:
order (test.your-domain.com) timed out (20.0 minutes)
逾時問題的常見原因,是 DNS 記錄未正確設定,無法將使用的網域對應至 Ingress 服務的 IP 位址。執行下列指令來檢查 DNS 記錄:
host DOMAIN
檢查 Ingress 負載平衡器的外部 IP 位址:
如要取得負載平衡器的外部 IP,請執行下列指令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
將 ASM-INGRESS-NAMESPACE 替換為 Cloud Service Mesh Ingress 所在的命名空間。如果您使用預設設定安裝 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 位址與 Ingress IP 位址不符,請重新設定 DNS 記錄,對應至正確的 IP 位址。
(更新後的) DNS 記錄生效後,請執行下列指令刪除 Order 物件,重新觸發要求 TLS 憑證的程序:
kubectl delete order DOMAIN -n NAMESPACE
取代
- DOMAIN 改成您使用的網域名稱。
- NAMESPACE 改為您使用的命名空間。
授權失敗
如果 DNS 記錄未及時在全球傳播,就可能發生授權失敗的情況。因此,Let's Encrypt 無法驗證網域擁有權。
查看訂單狀態。在狀態的
acmeAuthorizations
欄位下方找出授權連結。網址應如下所示:https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
開啟連結。如果看到類似以下的訊息:
urn:ietf:params:acme:error:dns
則問題是因 DNS 傳播不完整所致。
如要解決 DNS 傳播錯誤,請按照下列步驟操作:
檢查 Ingress 負載平衡器的外部 IP 位址:
如要取得負載平衡器的外部 IP,請執行下列指令:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
將 ASM-INGRESS-NAMESPACE 替換為 Cloud Service Mesh Ingress 所在的命名空間。如果您使用預設設定安裝 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 位址與 Ingress 負載平衡器的外部 IP 不符,請設定 DNS 記錄,將使用者的網域對應至外部 IP。
(更新後的) DNS 記錄生效後,請執行下列指令刪除 Order 物件,重新觸發要求 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)。如果服務是在 istiod
準備好開始調解 VirtualServices
並將 Envoy 設定推送至 Ingress 閘道之前建立,就可能發生這項錯誤 (在 Kubernetes 1.14
上更常發生)。
如要修正這個問題,請使用類似下列的指令,先縮減部署作業,然後再擴大:
kubectl scale deployment istiod -n istio-system --replicas=0
kubectl scale deployment istiod -n istio-system --replicas=1
缺少要求數和要求延遲指標
如果您已啟用 Workload Identity Federation for GKE,但未將特定權限授予服務使用的服務帳戶,服務可能不會回報修訂版本要求計數和要求延遲時間指標。
如要修正這個問題,請按照「在啟用 Workload Identity Federation for GKE 的叢集上啟用指標」一節中的步驟操作。