K8S常見Pod 異常狀態的處理

一般來說,無論 Pod 處於什麼異常狀態,都可以執行以下命令來查看 Pod 的狀態

  • kubectl get pod <pod-name> -o yaml 查看 Pod 的配置是否正確
  • kubectl describe pod <pod-name> 查看 Pod 的事件
  • kubectl logs <pod-name> [-c <container-name>] 查看容器日誌

Pod --Pending狀態
Pending 說明 Pod 還沒有調度到某個 Node 上面。可以通過 
kubectl describe pod <pod-name> 命令查看到當前 Pod 的事件,進而判斷爲什麼沒有調度。可能的原因包括

  • 資源不足,集羣內所有的 Node 都不滿足該 Pod 請求的 CPU、內存、GPU 等資源
  • HostPort 已被佔用,通常推薦使用 Service 對外開放服務端口

Pod --Waiting 或 ContainerCreating狀態
首先還是通過 kubectl describe pod <pod-name> 命令查看到當前 Pod 的事件。可能的原因包括

  • 鏡像拉取失敗,比如配置了鏡像錯誤、Kubelet 無法訪問鏡像、私有鏡像的密鑰配置錯誤、鏡像太大,拉取超時等
  • CNI 網絡錯誤,一般需要檢查 CNI 網絡插件的配置,比如無法配置 Pod 、無法分配 IP 地址
  • 容器無法啓動,需要檢查是否打包了正確的鏡像或者是否配置了正確的容器參數

Pod -- ImagePullBackOff狀態
這也是我們測試環境常見的,通常是鏡像拉取失敗。這種情況可以使用 docker pull <image> 來驗證鏡像是否可以正常拉取。

或者docker images | grep <images>查看鏡像是否存在(系統有時會因爲資源問題自動刪除一部分鏡像),

Pod -- CrashLoopBackOff狀態 
CrashLoopBackOff 狀態說明容器曾經啓動了,但可能又異常退出了。此時可以先查看一下容器的日誌
kubectl logs <pod-name> kubectl logs --previous <pod-name>
這裏可以發現一些容器退出的原因,比如

  • 容器進程退出
  • 健康檢查失敗退出

Pod --Error 狀態
通常處於 Error 狀態說明 Pod 啓動過程中發生了錯誤。常見的原因包括

  • 依賴的 ConfigMap、Secret 或者 PV 等不存在
  • 請求的資源超過了管理員設置的限制,比如超過了 LimitRange 等
  • 違反集羣的安全策略,比如違反了 PodSecurityPolicy 等
  • 容器無權操作集羣內的資源,比如開啓 RBAC 後,需要爲 ServiceAccount 配置角色綁定

Pod --Terminating 或 Unknown 狀態
從 v1.5 開始,Kubernetes 不會因爲 Node 失聯而刪除其上正在運行的 Pod,而是將其標記爲 Terminating 或 Unknown 狀態。想要刪除這些狀態的 Pod 有三種方法:

  • 從集羣中刪除該 Node。使用公有云時,kube-controller-manager 會在 VM 刪除後自動刪除對應的 Node。而在物理機部署的集羣中,需要管理員手動刪除 Node(如 kubectl delete node <node-name>。
  • Node 恢復正常。Kubelet 會重新跟 kube-apiserver 通信確認這些 Pod 的期待狀態,進而再決定刪除或者繼續運行這些 Pod。
  • 用戶強制刪除。用戶可以執行 kubectl delete pods <pod> --grace-period=0 --force 強制刪除 Pod。除非明確知道 Pod 的確處於停止狀態(比如 Node 所在 VM 或物理機已經關機),否則不建議使用該方法。
    特別是 StatefulSet 管理的 Pod,強制刪除容易導致腦裂或者數據丟失等問題。

Pod -- Evicted狀態

出現這種情況,多見於系統內存或硬盤資源不足,可df-h查看docker存儲所在目錄的資源使用情況,如果百分比大於85%,就要及時清理下資源,尤其是一些大文件、docker鏡像。

清除狀態爲Evicted的pod:

kubectl get pods | grep Evicted | awk '{print $1}' | xargs kubectl delete pod

刪除所有狀態異常的pod:

kubectl delete pods $(kubectl get pods | grep -v Running | cut -d ' ' -f 1)

刪除集羣中沒有在使用的docker鏡像(慎用):

docker system prune -a

查看pod對應的服務(鏡像)版本:

kubectl --server=127.0.0.1:8888 get rc -o yaml | grep image: |uniq | sort | grep ecs-core

附:

刪除某類歷史鏡像(僅保留當前使用的)

docker images | grep ecs-core | grep -v `docker images | grep ecs-core -m 1 | awk '{print $2}'` | awk '{print $3}' | xargs docker rmi -f

發佈了19 篇原創文章 · 獲贊 60 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章