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


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

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

所有錯誤:檢查 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 狀態並不代表有特定錯誤,而是表示容器在重新啟動後一直當機。如果容器在啟動後不久當機或結束 (CrashLoop),Kubernetes 會嘗試重新啟動容器。每次重新啟動失敗後,下一次嘗試前的延遲時間 (BackOff) 會依指數遞增 (10 秒、20 秒、40 秒等),最多為五分鐘。

下列各節有助於找出容器可能當機的原因。

使用 Pod 當機循環問題的互動式應對手冊

如要開始排解導致 CrashLoopBackOff 狀態的問題,請使用 Google Cloud 控制台中的互動式劇本:

  1. 前往 Pod 當機循環問題的互動式應對手冊:

    前往 Playbook

  2. 在「叢集」下拉式清單中,選取要排解問題的叢集。如果找不到叢集,請在「Filter」(篩選) 欄位中輸入叢集名稱。

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

  4. 請逐一查看各個部分,找出原因:

    1. 找出應用程式錯誤
    2. 調查記憶體不足問題
    3. 調查節點服務中斷情形
    4. 調查有效性探測失敗問題
    5. 找出變更事件的關聯性
  5. 選用:如要接收日後發生錯誤的通知,請在「日後補救提示」部分選取「建立快訊」CrashLoopBackOff

檢查記錄

造成容器當機的原因有很多,檢查 Pod 的記錄檔可能對疑難排解根本原因有所幫助。

您可以使用 Google Cloud 控制台或 kubectl 指令列工具檢查記錄。

控制台

請執行下列步驟:

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

    前往「Workloads」(工作負載)

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

  3. 在「受管理的 Pod」區段中,按一下有問題的 Pod。

  4. 在 Pod 選單中,按一下 [記錄] 分頁標籤。

kubectl

  1. 查看叢集中執行的所有 Pod:

    kubectl get pods
    
  2. 在上述指令的輸出內容中,找出 Status 欄中出現 CrashLoopBackOff 錯誤的 Pod。

  3. 取得 Pod 的記錄:

    kubectl logs POD_NAME
    

    POD_NAME 替換為有問題的 Pod 名稱。

    如果 Pod 容器先前有執行個體,您也可以傳遞 -p 標記來取得該執行個體的記錄。

檢查當機容器的結束代碼

如要進一步瞭解容器當機的原因,請找出結束代碼:

  1. 描述 Pod:

    kubectl describe pod POD_NAME
    

    POD_NAME 替換為有問題的 Pod 名稱。

  2. 查看 containers: CONTAINER_NAME: last state: exit code 欄位中的值:

    • 若結束代碼為 1,表示容器是因為應用程式當機所以當機。
    • 如果結束代碼為 0,請檢查應用程式執行了多久時間。當應用程式的主程序結束時,容器也會結束。如果應用程式很快就執行完畢,容器可能會繼續執行並重新啟動。如果遇到這項錯誤,其中一個解決方法是將 restartPolicy 欄位設為 OnFailure。進行這項變更後,應用程式只會在結束代碼不是 0 時重新啟動。

連線至執行中的容器

如要從容器執行 bash 指令,以便測試網路或檢查您是否能存取應用程式所用的檔案或資料庫,請開啟 Pod 的殼層:

kubectl exec -it POD_NAME -- /bin/bash

如果 Pod 中有多個容器,請加入 -c CONTAINER_NAME

錯誤:ImagePullBackOff 和 ErrImagePull

ImagePullBackOffErrImagePull 狀態表示無法從映像檔登錄檔載入容器使用的映像檔。

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

錯誤:Pod 無法排程

PodUnschedulable 狀態表示您的 Pod 因為資源不足或一些設定上的錯誤而無法排程。

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

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

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

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

    前往 Playbook

  2. 在「叢集」下拉式清單中,選取要排解問題的叢集。如果找不到叢集,請在「Filter」(篩選) 欄位中輸入叢集名稱。

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

  4. 為協助您找出原因,請完成劇本中的每個章節:

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

錯誤:資源不足

您遇到的錯誤指出缺少 CPU、記憶體或其他資源。例如:No nodes are available that match all of the predicates: Insufficient cpu (2) 表示兩個節點上沒有足夠的 CPU 可完成 Pod 要求。

如果 Pod 資源要求超過任何符合資格節點集區的單一節點,GKE 不會安排 Pod 時程,也不會觸發擴充作業來新增節點。如要讓 GKE 排程 Pod,您必須減少 Pod 的資源要求,或是建立資源充足的新節點集區。

您也可以啟用節點自動佈建,讓 GKE 自動建立節點集區,並在節點中執行未排程的 Pod。

預設的 CPU 要求為 100m 或 CPU (或一個核心) 的 10%。如要要求更多或更少資源,請在 Pod 規格中,於 spec: containers: resources: requests 下方指定值。

錯誤:MatchNodeSelector

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

如要進行確認,請檢查 Pod 規格 spec: nodeSelector 下方的 nodeSelector 欄位中指定的標籤。

如要查看叢集中的節點標籤,請執行下列指令:

kubectl get nodes --show-labels

如要為節點加上標籤,請執行下列指令:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

更改下列內容:

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

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

錯誤:PodToleratesNodeTaints

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

若要確認這個情況,請執行以下指令:

kubectl describe nodes NODE_NAME

在輸出結果中,檢查 Taints 欄位。這個欄位會列出鍵/值組合和排程效果。

若排程效果為「NoSchedule」,表示除非 Pod 有相對應的容許條件,否則系統將無法在該節點上排程任何 Pod。

其中一個解決方法是移除 taint。舉例來說,如要移除「NoSchedule」taint,請執行下列指令:

kubectl taint nodes NODE_NAME key:NoSchedule-

錯誤:PodFitsHostPorts

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

如要解決這個問題,請考慮採用 Kubernetes 最佳做法,並使用 NodePort 而非 hostPort

如果必須使用 hostPort,請檢查 Pod 的資訊清單,並確保同一節點上的所有 Pod 都為 hostPort 定義了專屬值。

錯誤:未達最低可用性

如果節點有足夠的資源,但您仍看到 Does not have minimum availability 訊息,請檢查 Pod 的狀態。如果狀態為 SchedulingDisabledCordoned,節點就無法排定新的 Pod。您可以使用 Google Cloud 主控台或 kubectl 指令列工具檢查節點狀態。

控制台

請執行下列步驟:

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

    前往「Google Kubernetes Engine」

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

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

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

  2. 在「節點詳細資料」部分,按一下「取消限制」

kubectl

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

kubectl get nodes

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

kubectl uncordon NODE_NAME

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

如果叢集中所有節點都達到「每個節點的 Pod 數量上限」,Pod 會停滯在「無法排程」狀態。在 Pod 的「事件」分頁下方,您會看到包含 Too many pods 片語的訊息。

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

  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,請變更叢集自動調度資源設定

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

如果節點集區已達到節點數量上限,且叢集自動配置器已停用,GKE 就無法使用該節點集區排定 Pod。增加節點集區的大小,或啟用叢集自動調度資源,讓 GKE 自動調整叢集大小。

錯誤:未繫結的 PersistentVolumeClaim

Unbound PersistentVolumeClaims 表示 Pod 參照未繫結的 PersistentVolumeClaim。如果 PersistentVolume 佈建失敗,即可能發生此錯誤。您可以取得 PersistentVolumeClaim 的事件,並檢查是否有失敗情形,藉此確認佈建失敗。

如要取得事件,請執行下列指令:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

更改下列內容:

  • STATEFULSET_NAME:StatefulSet 物件的名稱。
  • PVC_NAME:PersistentVolumeClaim 物件的名稱。

如果您手動預先佈建 PersistentVolume,並將其繫結至 PersistentVolumeClaim 時發生設定錯誤,也可能導致這個問題。

如要解決這個錯誤,請嘗試再次預先佈建磁碟區。

錯誤:配額不足

確認專案的 Compute Engine 配額充足,可供 GKE 擴充叢集。如果 GKE 嘗試將節點新增至叢集來排定 Pod,但擴充作業會超出專案的可用配額,您會收到 scale.up.error.quota.exceeded 錯誤訊息。

詳情請參閱「ScaleUp 錯誤」。

問題:已淘汰的 API

請確認您未在叢集次要版本中,使用已移除的已淘汰 API。詳情請參閱「功能和 API 淘汰項目」。

錯誤:沒有可用的連接埠,無法滿足要求的 Pod 連接埠

如果看到類似下列內容的錯誤,可能是因為同一個節點上有相同值的多個 Pod,且這些值定義在 hostPort 欄位中:

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 會限制 GKE 可排程 Pod 的位置,因為每個 hostIPhostPortprotocol 組合都必須是唯一的。

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

如果必須使用 hostPort,請檢查 Pod 的資訊清單,並確保同一節點上的所有 Pod 都為 hostPort 定義了專屬值。

後續步驟