即使 Pod 正在執行,如果 Google Kubernetes Engine (GKE) 中的 Ingress 健康狀態檢查失敗,流量就無法抵達應用程式。
請參閱本文,瞭解 Ingress 健康狀態檢查的運作方式、BackendConfig 和就緒探查注意事項,以及診斷應用程式沒有回應或缺少防火牆規則等問題。
平台管理員和營運人員以及應用程式開發人員,會設定及管理 Ingress 資源,並需要確保應用程式向負載平衡器正確回報健康狀態,因此這項資訊非常重要。如要進一步瞭解我們在 Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。
瞭解 Ingress 健康狀態檢查的運作方式
在進行疑難排解步驟之前,建議先瞭解 GKE 中的健康狀態檢查運作方式,以及確保健康狀態檢查順利進行的注意事項。
使用預設 Ingress 控制器透過 Ingress 公開一或多個 Service 時,GKE 會建立傳統型應用程式負載平衡器或內部應用程式負載平衡器。這兩種負載平衡器都支援單一網址對應上的多個後端服務。每個後端服務都對應至 Kubernetes 服務,且每個後端服務都必須參照Google Cloud 健康狀態檢查。這項健康檢查與 Kubernetes 執行中或已就緒探測器不同,因為健康檢查是在叢集外部實作。
負載平衡器健康狀態檢查是依後端服務指定。雖然可以對負載平衡器的所有後端服務使用相同的健康狀態檢查,但系統不會為整個負載平衡器 (在 Ingress 物件本身) 指定健康狀態檢查參照。
GKE 會根據下列其中一種方法建立健康狀態檢查:
BackendConfigCRD:自訂資源定義 (CRD),可精確控管服務與負載平衡器的互動方式。BackendConfigCRD 可讓您為與對應後端服務相關聯的健康狀態檢查指定自訂設定。這些自訂設定可讓您更靈活地控管 Ingress 建立的傳統版應用程式負載平衡器和內部應用程式負載平衡器的健康狀態檢查。- 完備性探測:診斷檢查,判斷 Pod 內的容器是否已準備好處理流量。GKE Ingress 控制器會根據該 Service 服務 Pod 使用的就緒探測器,為 Service 的後端服務建立健康狀態檢查。您可以從就緒探查定義衍生健康狀態檢查參數,例如路徑、通訊埠和通訊協定。
- 預設值:未設定
BackendConfigCRD 或定義就緒探查屬性時使用的參數。
使用 BackendConfig CRD,盡可能控管負載平衡器健康狀態檢查設定。
GKE 會使用下列程序,為 Kubernetes 服務對應的每個後端服務建立健康狀態檢查:
如果 Service 參照含有
healthCheck資訊的 CRDBackendConfig,GKE 會使用該資訊建立健康狀態檢查。GKE Enterprise Ingress 控制器和 GKE Ingress 控制器都支援以這種方式建立健康狀態檢查。如果 Service 未參照
BackendConfigCRD:
注意事項
本節將說明設定 BackendConfig CRD 或使用就緒探針時,應注意的幾項事項。
BackendConfig CRD
設定 BackendConfig CRD 時,請注意下列事項:
- 如果您使用容器原生負載平衡,請確認
BackendConfig資訊清單中的健康狀態檢查通訊埠與提供服務的 Pod 的containerPort相符。 - 如果是執行個體群組後端,請確認
BackendConfig資訊清單中的健康狀態檢查通訊埠與 Service 暴露的nodePort相符。 - Ingress 不支援自訂健康狀態檢查設定的 gRPC。
BackendConfig僅支援使用 HTTP、HTTPS 或 HTTP2 通訊協定建立健康狀態檢查。如要查看如何在BackendConfigCRD 中使用通訊協定的範例,請參閱 gke-networking-recipes。
詳情請參閱「何時使用 BackendConfig CRD」。
完備性探測
使用 GKE Ingress 搭配 HTTP 或 HTTPS 負載平衡時,GKE 會傳送健康狀態檢查探測,判斷應用程式是否正常運作。只要符合下列條件,這些健康狀態檢查探針就會傳送至 Pod YAML 設定 spec.containers[].readinessProbe.httpGet.port 區段中定義的 Pod 特定通訊埠:
spec.containers[].readinessProbe.httpGet.port中指定的就緒探查通訊埠編號,必須與應用程式在容器中實際監聽的通訊埠相符,該通訊埠定義於 Pod 設定的containers[].spec.ports.containerPort欄位中。- 提供服務的 Pod
containerPort必須與 Service 的targetPort相符。這可確保流量從服務導向 Pod 上的正確通訊埠。 - Ingress 服務後端通訊埠規格必須參照 Service 設定的
spec.ports[]區段中的有效通訊埠。方法有以下兩種:- Ingress 中的
spec.rules[].http.paths[].backend.service.port.name與對應 Service 中定義的spec.ports[].name相符。 - Ingress 中的
spec.rules[].http.paths[].backend.service.port.number與對應 Service 中定義的spec.ports[].port相符。
- Ingress 中的
排解常見的健康狀態檢查問題
請使用下列疑難排解流程圖,找出健康狀態檢查問題:
在這份流程圖中,下列疑難排解指引有助於判斷問題所在:
調查 Pod 健康狀態:如果健康狀態檢查失敗,請檢查服務的服務 Pod 狀態。如果 Pod 未執行且運作正常:
- 檢查 Pod 記錄檔,確認是否有任何錯誤或問題導致 Pod 無法執行。
- 檢查 readiness 和 liveness 探測的狀態。
健康狀態檢查記錄:請確認您已啟用健康狀態檢查記錄。
確認防火牆設定:確認防火牆規則允許健康狀態檢查探測器連線至 Pod。如果問題未獲解決,請採取下列動作:
- 檢查防火牆規則,確認規則允許來自健康狀態檢查探測器 IP 位址範圍的連入流量。
- 視需要調整防火牆規則,以配合這些 IP 位址範圍。
分析封包擷取:如果防火牆設定正確,請執行封包擷取,確認應用程式是否會回應健康狀態檢查。如果封包擷取作業顯示回應成功,請聯絡Google Cloud 支援團隊,尋求進一步協助。
排解應用程式問題:如果封包擷取作業未顯示成功回應,請調查應用程式為何無法正確回應健康狀態檢查要求。確認健康狀態檢查是否以 Pod 上正確的路徑和通訊埠為目標,並檢查應用程式記錄、設定檔和依附元件。如果找不到錯誤,請聯絡 Google Cloud 支援團隊。
應用程式未回應健康狀態檢查
在設定的路徑和通訊埠上進行健康狀態檢查時,應用程式未傳回預期的狀態碼 (HTTP 為 200 OK,TCP 為 SYN、ACK)。
如果應用程式無法正確回應健康狀態檢查,可能是因為下列其中一個原因:
- 網路端點群組(NEG):
- 應用程式未在 Pod 中正常運作。
- 應用程式未監聽設定的通訊埠或路徑。
- 發生網路連線問題,導致健康狀態檢查無法連線至 Pod。
- 執行個體群組:
- 執行個體群組中的節點健康狀態不佳。
- 應用程式無法在節點上正常運作。
- 健康狀態檢查要求未送達節點。
如果健康狀態檢查失敗,請根據設定,按照下列方式排解問題:
NEG:
使用
kubectl exec存取 Pod:kubectl exec -it pod-name -- command-it旗標提供互動式終端機工作階段 (i 代表互動式,t 代表 TTY)。更改下列內容:
pod-name:Pod 的名稱。command:要在 Pod 中執行的指令。最常見的指令是bash或sh,可取得互動式殼層。
執行
curl指令,測試連線能力和應用程式回應速度:curl localhost:<Port>/<Path>curl -v http://<POD_IP>/[Path configured in HC]curl http://localhost/[Path configured in HC]
執行個體群組:
- 確認節點健康狀態良好,且會回應預設健康狀態檢查探測。
- 如果節點健康狀態良好,但應用程式 Pod 沒有回應,請進一步調查應用程式。
- 如果要求未送達 Pod,可能是 GKE 網路問題。如需協助,請與 Google Cloud 支援團隊聯絡。
編輯 Pod 的就緒探針時發生錯誤
嘗試編輯 Pod 的完備性探測,變更健康狀態檢查參數時,會導致類似下列的錯誤:
Pod "pod-name" is invalid: spec: Forbidden: pod updates may not change fields
如果您修改與服務相關聯的 Pod 完備性探測器,而該服務已連結至 Ingress (及其對應的負載平衡器),GKE 不會自動更新負載平衡器上的健康狀態檢查設定。這會導致 Pod 的就緒檢查與負載平衡器的健康狀態檢查不符,造成健康狀態檢查失敗。
如要解決這個問題,請重新部署 Pod 和 Ingress 資源。這會強制 GKE 重新建立負載平衡器及其健康狀態檢查,並納入新的準備狀態探測設定。
部署作業和負載平衡器無法啟動
如果部署作業無法啟動,且 Ingress 控制器的負載平衡器後方後端服務標示為健康狀態不良,可能是因為完備性探測失敗。
您可能會看到下列錯誤訊息,指出就緒探查失敗:
Readiness probe failed: connection refused
Pod 中的應用程式無法正確回應 Pod YAML 設定中設定的完備性探查。這可能是因為多種原因,例如應用程式無法正常啟動、監聽的連接埠錯誤,或初始化期間發生錯誤。
如要解決這個問題,請按照下列步驟,調查並修正應用程式設定或行為中的任何差異:
- 確認應用程式已正確設定,並在就緒探查參數中指定的路徑和連接埠上回應。
- 查看應用程式記錄,並排解任何啟動問題或錯誤。
- 確認 Pod 設定中的
containerPort與 Service 中的targetPort和 Ingress 中指定的後端通訊埠相符。
缺少自動輸入防火牆規則
您已建立 Ingress 資源,但流量未抵達後端服務。
系統缺少自動建立的 Ingress 防火牆規則 (通常是在建立 Ingress 資源時由 GKE 建立),或是規則遭到誤刪。
如要還原後端服務的連線,請按照下列步驟操作:
- 確認虛擬私有雲網路中是否有自動輸入防火牆規則。
- 如果規則遺失,您可以手動重新建立,或是刪除並重新建立 Ingress 資源,觸發系統自動建立規則。
- 確認防火牆規則允許適當通訊埠和通訊協定的流量,如 Ingress 資源中所定義。
BackendConfig 資訊清單中使用的通訊協定有誤
如果您使用 TCP 類型通訊協定設定 BackendConfig CRD,就會看到以下錯誤訊息:
Error syncing to GCP: error running backend syncing routine:
error ensuring health check: Protocol "TCP" is not valid, must be one of ["HTTP","HTTPS","HTTP2"]'
BackendConfig 僅支援使用 HTTP、HTTPS 或 HTTP/2 通訊協定建立健康狀態檢查。詳情請參閱「HTTP、HTTPS 和 HTTP/2 的成功標準」。
後續步驟
如要在單一叢集中為 Ingress 設定自訂健康狀態檢查,請參閱 GKE 網路食譜。
如果無法在說明文件中找到問題的解決方法,請參閱「取得支援」一文,瞭解如何尋求進一步的協助, 包括下列主題的建議:
- 與 Cloud 客戶服務聯絡,建立支援案件。
- 在 StackOverflow 上提問,並使用
google-kubernetes-engine標記搜尋類似問題,向社群尋求支援。你也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開版 Issue Tracker 開啟錯誤或功能要求。