偵錯 Pods

本指南旨在協助使用者偵錯部署到 Kubernetes 且行為不正確的應用程式。這不是想要偵錯叢集的人員的指南。如需該資訊,您應該查看本指南

診斷問題

疑難排解的第一步是分類。問題是什麼?是您的 Pods、您的 Replication Controller 還是您的服務?

偵錯 Pods

偵錯 Pod 的第一步是查看它。使用以下命令檢查 Pod 的目前狀態和最近事件

kubectl describe pods ${POD_NAME}

查看 Pod 中容器的狀態。它們是否都在 Running 狀態?最近是否有重新啟動?

根據 Pod 的狀態繼續偵錯。

我的 Pod 保持在 pending 狀態

如果 Pod 卡在 Pending 狀態,表示它無法排程到節點上。通常這是因為資源不足,導致無法排程。查看上面 kubectl describe ... 命令的輸出。應該會有來自排程器的訊息,說明為何無法排程您的 Pod。原因包括

  • 您沒有足夠的資源:您可能已耗盡叢集中的 CPU 或記憶體供應,在這種情況下,您需要刪除 Pods、調整資源請求,或將新節點新增至叢集。請參閱運算資源文件以取得更多資訊。

  • 您正在使用 hostPort:當您將 Pod 繫結到 hostPort 時,可以排程該 Pod 的位置數量有限。在大多數情況下,hostPort 是不必要的,請嘗試使用 Service 物件來公開您的 Pod。如果您確實需要 hostPort,那麼您可以排程的 Pod 數量只能與 Kubernetes 叢集中的節點數量一樣多。

我的 Pod 保持在 waiting 狀態

如果 Pod 卡在 Waiting 狀態,則表示它已排程到工作節點,但無法在該機器上執行。同樣地,來自 kubectl describe ... 的資訊應該具有參考價值。Waiting Pods 最常見的原因是無法提取映像檔。有三件事要檢查

  • 確定您輸入的映像檔名稱正確。
  • 您是否已將映像檔推送至登錄檔?
  • 嘗試手動提取映像檔,以查看是否可以提取映像檔。例如,如果您在 PC 上使用 Docker,請執行 docker pull <image>

我的 Pod 保持在 terminating 狀態

如果 Pod 卡在 Terminating 狀態,表示已發出 Pod 的刪除指令,但控制平面無法刪除 Pod 物件。

如果 Pod 具有 finalizer,而且叢集中安裝了 許可 Webhook,而該 Webhook 阻止控制平面移除 finalizer,則通常會發生這種情況。

若要識別這種情況,請檢查您的叢集是否有任何 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration,其目標是 pods 資源的 UPDATE 作業。

如果 Webhook 由第三方提供

  • 請確定您使用的是最新版本。
  • 停用 UPDATE 作業的 Webhook。
  • 向相應的提供者回報問題。

如果您是 Webhook 的作者

  • 對於 mutating Webhook,請確定它永遠不會變更 UPDATE 作業上的不可變更欄位。例如,通常不允許變更容器。
  • 對於 validating Webhook,請確定您的驗證策略僅適用於新的變更。換句話說,您應該允許具有現有違規的 Pods 通過驗證。這允許在安裝 validating Webhook 之前建立的 Pods 繼續執行。

我的 Pod 正在崩潰或不健康

一旦您的 Pod 已排程,偵錯執行中 Pods 中描述的方法可用於偵錯。

我的 Pod 正在執行,但沒有執行我告訴它執行的動作

如果您的 Pod 行為不如預期,可能是您的 Pod 描述 (例如您本機上的 mypod.yaml 檔案) 中有錯誤,而且在您建立 Pod 時,該錯誤被靜默地忽略了。通常 Pod 描述的某個區段巢狀結構不正確,或是索引鍵名稱輸入錯誤,因此該索引鍵會被忽略。例如,如果您將 command 拼錯為 commnd,Pod 將會被建立,但不會使用您預期的命令列。

首先要做的是刪除您的 Pod,然後嘗試使用 --validate 選項再次建立它。例如,執行 kubectl apply --validate -f mypod.yaml。如果您將 command 拼錯為 commnd,則會出現像這樣的錯誤

I0805 10:43:25.129850   46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973   46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod

接下來要檢查的是 apiserver 上的 Pod 是否與您想要建立的 Pod 相符 (例如您本機上的 yaml 檔案)。例如,執行 kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml,然後手動比較原始 Pod 描述 mypod.yaml 與您從 apiserver 取得的版本 mypod-on-apiserver.yaml。通常「apiserver」版本上會有一些原始版本上沒有的行。這是預期的。但是,如果原始版本上有行在 apiserver 版本上沒有,則可能表示您的 Pod 規格有問題。

偵錯 Replication Controllers

複製控制器相當簡單明瞭。它們可以建立 Pod,不然就無法建立。如果它們無法建立 Pod,請參閱上述說明來偵錯您的 Pod。

您也可以使用 kubectl describe rc ${CONTROLLER_NAME} 來檢視與複製控制器相關的事件。

偵錯服務

服務在 Pod 集合之間提供負載平衡。有幾個常見問題可能會導致服務無法正常運作。以下說明應有助於偵錯服務問題。

首先,驗證服務是否有端點。對於每個服務物件,apiserver 都會提供一個 endpoints 資源。

您可以使用以下命令檢視此資源

kubectl get endpoints ${SERVICE_NAME}

請確保端點與您預期成為服務成員的 Pod 數量相符。例如,如果您的服務適用於具有 3 個副本的 nginx 容器,您應該會在服務的端點中看到三個不同的 IP 位址。

我的服務缺少端點

如果您缺少端點,請嘗試使用服務使用的標籤列出 Pod。假設您有一個服務,其標籤為

...
spec:
  - selector:
     name: nginx
     type: frontend

您可以使用

kubectl get pods --selector=name=nginx,type=frontend

列出符合此選擇器的 Pod。驗證清單是否與您預期提供服務的 Pod 相符。驗證 Pod 的 containerPort 是否與服務的 targetPort 相符

網路流量未轉發

請參閱偵錯服務以取得更多資訊。

下一步

如果以上皆無法解決您的問題,請按照偵錯服務文件中的說明,確認您的 Service 正在執行、具有 Endpoints,且您的 Pods 實際上正在提供服務;您的 DNS 運作正常、iptables 規則已安裝,且 kube-proxy 看起來沒有異常行為。

您也可以造訪疑難排解文件以取得更多資訊。

上次修改時間:2024 年 1 月 20 日晚上 11:44 PST:[en] 更正不正確的表達式 (5fcc71ad51)