排解已部署工作負載的問題

本頁說明如何解決在 Google Kubernetes Engine (GKE) 中部署工作負載時發生的錯誤。

如需有關排解應用程式問題的一般建議,請參閱 Kubernetes 說明文件中的「疑難排解應用程式」。

所有錯誤:檢查 Pod 狀態

如果工作負載的 Pod 發生問題,Kubernetes 會更新 Pod 狀態,並顯示錯誤訊息。如要查看這些錯誤,請使用 Google Cloud 控制台或 kubectl 指令列工具檢查 Pod 狀態。

控制台

請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 選取要調查的工作負載。「總覽」分頁會顯示工作負載的狀態。

  3. 在「代管的 Pod」部分中,按一下任何錯誤狀態訊息。

kubectl

如要查看在叢集中執行的所有 Pod,請執行以下指令:

kubectl get pods

輸出結果會與下列內容相似:

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

「潛在錯誤」Status欄會列出潛在錯誤。

如要進一步瞭解特定 Pod,請執行下列指令:

kubectl describe pod POD_NAME

將 POD_NAME 替換為要調查的 Pod 名稱。

在輸出內容中,Events 欄位會顯示錯誤的詳細資訊。

如要瞭解詳情,請查看容器記錄:

kubectl logs POD_NAME

這些記錄可協助您判斷容器中的指令或程式碼是否導致 Pod 停止運作。

找出錯誤後,請參閱下列各節,嘗試解決問題。

錯誤:CrashLoopBackOff

CrashLoopBackOff 狀態並不代表發生特定錯誤,而是表示容器在重新啟動後不斷當機。

詳情請參閱「排解 CrashLoopBackOff 事件」。

錯誤:ImagePullBackOff 和 ErrImagePull

如果狀態為 ImagePullBackOff 或 ErrImagePull,表示容器使用的映像檔無法從映像檔登錄檔載入。

如需排解這些狀態的指引,請參閱「排解映像檔提取問題」。

錯誤:OutOfPods

OutOfPods 狀態表示節點已達 Pod 容量上限,因此無法執行 Pod。

問題

Pod 的事件中可能會顯示類似下列的訊息:

Node didn't have enough resource: pods, requested: 1, used: 32, capacity: 32

原因

如果要求在容量已滿的節點上排程 Pod,就會發生這個錯誤。舉例來說,節點啟動期間通常會發生這種情況,因為 kube-scheduler 元件會在 kubelet 代理程式回報 kube-proxy 元件等靜態 Pod 的存在之前,將 Pod 指派給新節點,而這些靜態 Pod 需要自己的 Pod 容量。

解析度

如要解決這個問題,請嘗試下列任一解決方法:

  • 提高每個節點的 Pod 數量上限。如果節點經常達到 Pod 數量上限,請提高節點集區的 --max-pods-per-node 設定。增加 Pod 數量可能需要較大的節點,才能處理增加的資源需求。

  • 啟用叢集自動配置器和自動佈建節點功能。如果 Pod 容量經常不足,啟用叢集自動配置器和自動佈建節點功能,可確保叢集有足夠的節點,滿足工作負載需求。

  • 變更自動調度資源設定檔。如果您已使用叢集自動配置器,請嘗試將自動調整資源配置設定檔變更為 balanced 設定檔,而非 optimize-utilization 設定檔。optimize-utilization 設定檔會嘗試將 Pod 放置在最常使用的節點上,因此可能會增加發生 OutOfPods 錯誤的機率。

錯誤:Pod 無法排程

如果狀態為 PodUnschedulable,表示 Pod 無法排程,因為資源不足或發生設定錯誤。

如果您已設定控制層指標,可以透過排程器指標和 API 伺服器指標,進一步瞭解這些錯誤。

使用無法排程的 Pod 互動式應對手冊

您可以使用 Google Cloud 控制台中的互動式劇本,排解 PodUnschedulable 錯誤:

  1. 前往無法排程的 Pod 互動式應對手冊:

    前往 Playbook

  2. 在「叢集」下拉式選單中,選取要進行疑難排解的叢集。如果找不到叢集,請在「篩選」欄位中輸入叢集名稱。

  3. 在「命名空間」下拉式選單中,選取要疑難排解的命名空間。如果找不到命名空間,請在「篩選器」欄位中輸入命名空間。

  4. 為找出原因,請逐一查看教戰手冊中的各個部分:

    1. 調查 CPU 和記憶體問題
    2. 調查每個節點的 Pod 數量上限問題
    3. 調查自動配置器行為問題
    4. 調查其他失敗模式
    5. 找出變更事件的關聯性
  5. 選用:如要接收日後 PodUnschedulable 錯誤的通知,請在「Future Mitigation Tips」(日後緩解提示) 部分選取「Create an Alert」(建立快訊)。

錯誤:資源不足

如果 CPU、記憶體或其他資源不足,無法滿足 Pod 的要求,就會出現 PodUnschedulable 狀態。

問題

您可能會遇到錯誤,指出 CPU、記憶體或其他資源不足。例如:No nodes are available that match all of the predicates: Insufficient cpu (2)。這則訊息表示兩個節點的 CPU 不足,無法滿足 Pod 的要求。

原因

如果 Pod 資源要求超出任何符合資格節點集區的單一節點,GKE 不會安排 Pod 時程,也不會觸發擴充作業來新增節點。

叢集會在 kube-system 命名空間中執行系統容器。這些容器也會使用叢集資源。

解析度

請嘗試下列解決方法:

  • 在 spec: containers: resources: requests 欄位中指定較低的值,即可調整 Pod 的資源要求。預設 CPU 要求為 100m 或 CPU 的 10% (或一個核心)。

  • 建立新的節點集區,內含的節點資源充足,可滿足 Pod 的要求。

  • 啟用自動佈建節點功能,讓 GKE 自動建立節點集區,並在節點中執行未排定的 Pod。

錯誤:MatchNodeSelector

MatchNodeSelector 錯誤表示沒有符合 Pod 標籤選取器的節點。

問題

Pod 狀態或事件顯示 MatchNodeSelector 錯誤。

原因

Pod 資訊清單的 nodeSelector 欄位中指定的標籤,在叢集中的任何節點上都不存在。

解析度

如要解決這項錯誤,請確保 Pod 的 nodeSelector 欄位中指定的標籤,與叢集中至少一個節點上的標籤相符:

  1. 查看 Pod 的 spec: nodeSelector 欄位,找出 Pod 要求的標籤。

  2. 如要查看是否有任何標籤符合 Pod 的需求,請查看指派給叢集節點的實際標籤:

    kubectl get nodes --show-labels
    
  3. 如果節點要執行這個 Pod,請附加必要的標籤:

    kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
    

    更改下列內容:

    • NODE_NAME:要新增標籤的節點。
    • LABEL_KEY:標籤的鍵。
    • LABEL_VALUE:標籤的值。

詳情請參閱 Kubernetes 說明文件中的「將 Pod 指派給節點」。

錯誤:PodToleratesNodeTaints

PodToleratesNodeTaints 錯誤表示 Pod 無法排程至任何節點,因為 Pod 沒有對應現有節點 taint 的容許條件。

問題

Pod 狀態或事件顯示 PodToleratesNodeTaints 錯誤。

原因

Pod 沒有對應現有節點 taint 的容許條件,因此無法排定到任何節點。

解析度

  1. 檢查節點上的汙點:

    kubectl describe nodes NODE_NAME
    

    在輸出內容中,檢查 Taints 欄位,其中會列出鍵/值組合和排程效果。如果列出的效果是 NoSchedule,除非 Pod 具有相符的容許條件,否則無法排程到該節點。

  2. 從節點中移除汙點。例如,如要移除 NoSchedule 污點,請執行下列指令:

    kubectl taint nodes NODE_NAME key:NoSchedule-
    

錯誤:PodFitsHostPorts

PodFitsHostPorts 錯誤表示節點嘗試使用的通訊埠已遭占用。

問題

Pod 狀態顯示 PodFitsHostPorts 錯誤。

原因

Pod 要求的主機通訊埠已由目標節點上的其他 Pod 或程序使用。

解析度

如要解決這個問題,請考慮遵循 Kubernetes 最佳做法,並使用 NodePort 服務,而非 hostPort 設定。

如必須使用主機連接埠,請檢查 Pod 的資訊清單,並確保相同節點上的所有 Pod 都為 hostPort 設定定義專屬值。

錯誤:未達最低可用性

如果節點有足夠的資源,但無法用於排程,就可能發生這項錯誤。

問題

  • 系統顯示 Does not have minimum availability 錯誤。

  • 節點狀態顯示 SchedulingDisabled 或 Cordoned。

原因

節點處於封鎖狀態,因此無法排定新的 Pod。

解析度

如要讓節點再次可供排定 Pod,請取消封鎖:

控制台

請執行下列步驟:

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 選取要調查的叢集。「節點」分頁會顯示節點及其狀態。

如要在節點上啟用排程,請按照下列步驟操作:

  1. 在清單中,按一下要調查的節點。

  2. 在「節點詳細資料」部分,按一下「Uncordon」(取消封鎖)。

kubectl

如要取得節點狀態,請執行下列指令:

kubectl get nodes

如要在節點上啟用排程,請執行下列指令:

kubectl uncordon NODE_NAME

錯誤:已達每個節點的 Pod 數上限

Too many pods 錯誤表示 Pod 無法排程,因為目標節點已達設定的 Pod 容量上限。

問題

  • Pod 停滯在 Unschedulable 狀態。
  • 您看到包含「Too many pods」一詞的訊息。

原因

叢集中的所有節點都已達到「每節點的 Pod 數上限」。

解析度

如要解決這項錯誤,請完成下列步驟:

  1. 在 Google Cloud 控制台的 GKE 叢集詳細資料中,查看「Nodes」(節點) 分頁的 Maximum pods per node 設定。

  2. 取得節點清單:

    kubectl get nodes
    
  3. 針對每個節點,確認節點上執行的 Pod 數量:

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. 如果達到上限,請新增節點集區,或在現有節點集區中新增節點。

問題:啟用叢集自動配置器後,節點集區大小達到上限

如果節點集區已達到叢集自動調度資源設定的大小上限,就會發生這個問題。

問題

GKE 不會為原本會透過這個節點集區排程的 Pod 觸發向上擴充作業。Pod 會維持 Pending 狀態。

原因

根據叢集自動調度資源設定,節點集區已達到大小上限。

解析度

如要增加節點集區的大小上限,請變更叢集自動調度資源設定。

問題:停用叢集自動配置器後,節點集區大小達到上限

如果節點集區已達上限,且叢集自動配置器已停用,就會發生這個問題。

問題

GKE 無法使用節點集區排定 Pod。

原因

節點集區的節點數量已達上限,且叢集自動配置器已停用。

解析度

如要解決這個問題,請嘗試下列任一解決方法:

錯誤:未繫結的 PersistentVolumeClaim

Unbound PersistentVolumeClaims 錯誤表示 Pod 參照的 PersistentVolumeClaim 未繫結。

問題

Pod 狀態或事件顯示 Unbound PersistentVolumeClaims 錯誤。

原因

發生這項錯誤的原因如下:

  • 無法佈建 PersistentVolume。
  • 手動預先佈建 PersistentVolume 並將其繫結至 PersistentVolumeClaim 時,發生設定錯誤。

解析度

  1. 如要確認佈建是否失敗,請取得 PersistentVolumeClaim 的事件:

    kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
    

    更改下列內容:

    • STATEFULSET_NAME:StatefulSet 物件的名稱。
    • PVC_NAME:PersistentVolumeClaim 物件的名稱。
  2. 再次嘗試預先佈建磁碟區。

錯誤:配額不足

如果 GKE 嘗試擴充叢集來排程 Pod,但遇到配額限制,擴充作業就會失敗。

問題

Pod 事件中會顯示 scale.up.error.quota.exceeded 錯誤訊息。

原因

擴大叢集會超過專案的可用配額。

解析度

確認專案有足夠的 Compute Engine 配額,可供 GKE 擴充叢集。詳情請參閱「ScaleUp 錯誤」。

問題:已淘汰的 API

如果資訊清單中使用的 API 已停止支援,工作負載可能無法部署。

問題

工作負載因使用已淘汰的 API 而無法部署或執行。

原因

您的資訊清單使用已淘汰的 API,這些 API 會在叢集的小版本中移除。

解析度

確認您未使用已淘汰的 API。更新資訊清單,改用支援的 API。詳情請參閱「功能和 API 淘汰」。

錯誤:要求的 Pod 連接埠沒有可用的連接埠

將 Pod 繫結至主機通訊埠會限制 GKE 可排定 Pod 的位置,因為每個 hostIP 位址、hostPort 設定和 protocol 值組合都必須不重複。

問題

您會看到類似下列內容的錯誤:

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

原因

同一節點上的多個 Pod 指定了 hostPort 欄位中定義的相同值。

解析度

如要解決這個問題,請嘗試下列任一解決方法:

  • 請遵循 Kubernetes 最佳做法,並使用 NodePort 服務,而非主機通訊埠。
  • 如果必須使用主機通訊埠,請檢查 Pod 的資訊清單,並確認同一節點上的所有 Pod 都為 hostPort 欄位定義了不重複的值。

問題:Pod 中的應用程式和探測失敗

如果執行使用 HTTPS 與伺服器通訊的應用程式,就會發生這個問題。

問題

這些應用程式的失敗情形如下:

  • Pod 無法啟動,容器當機並顯示結束代碼 137。
  • Liveness 或 readiness 探測失敗,並顯示類似下列的錯誤訊息:

    probeResult="failure" output="Get "https://example.com/healthy": EOF"
    
  • Pod 正常運作,但應用程式記錄顯示連線失敗。

原因

Kubernetes 1.30 以上版本使用的 Golang 版本會停用下列 TLS 加密套件:

  • TLS_RSA_WITH_AES_128_GCM_SHA256
  • TLS_RSA_WITH_AES_256_GCM_SHA384
  • TLS_RSA_WITH_AES_128_CBC_SHA
  • TLS_RSA_WITH_AES_256_CBC_SHA
  • TLS_RSA_WITH_3DES_EDE_CBC_SHA

解析度

使用 TLS 1.2 以上版本支援的加密套件。

後續步驟