本文介紹關於Pod異常問題排查的診斷流程、排查方法、常見問題及對應的解決方案。
如果您需要瞭解排查Pod問題常用的控制台介面,例如如何查看Pod狀態、基礎資訊、配置、事件和日誌,使用終端進入容器,啟用Pod故障診斷等,可跳轉至常用排查介面瞭解。
快速診斷流程
查看工作負載Pod異常狀態,進入目標容器組詳情頁,單擊事件頁簽,查看例外狀況事件的對應描述資訊。單擊日誌頁簽,查看最近發生的異常日誌記錄。
Pod持續處於調度中狀態(Pending)
進入,檢查節點狀態、記憶體及CPU使用率。檢查並調整Pod的節點親和性策略,包括節點標籤、nodeSelector、nodeAffinity、汙點和容忍等。更多異常情境,請參考調度問題。
鏡像拉取失敗(ImagePullBackOff/ErrImagePull)
在容器組詳情頁下方,選擇容器頁簽檢查鏡像地址。登入Pod所在節點,使用crictl pull <鏡像地址>或curl -v https://<鏡像地址>驗證與鏡像倉庫網路連通性。單擊右上方YAML編輯,檢查工作負載spec.imagePullSecrets指定的Secret是否存在且正確。更多異常情境,請參考鏡像拉取問題。
Pod啟動失敗(CrashLoopBackOff)
因應用反覆崩潰重啟導致。在容器組詳情頁下方單擊日誌頁簽,勾選顯示上個容器退出時的日誌,會記錄進程發生異常的原因。更多異常情境,請參考Pod啟動失敗排查。
Pod出現記憶體溢出狀態(OOMKilled)
在容器組詳情頁下方單擊日誌頁簽,勾選顯示上個容器退出時的日誌,會記錄OOM日誌。確認應用是否存在記憶體流失或記憶體溢出(Java應用可最佳化-Xmx參數),按需調整應用的記憶體資源限制(resources.limits.memory)。更多異常情境,請參考OOMKilled。
如已配置存活檢查,則Pod只會短暫停留在OOMKilled狀態,然後自動重啟。
完整診斷流程
如果Pod狀態異常,可通過查看Pod的事件、Pod的日誌、Pod的配置等資訊確定異常原因。
階段一:調度問題
Pod未調度到節點
如果Pod長時間處於“未調度到節點”(Pending)狀態,沒有被安排到任何節點上運行,可能是由以下原因導致。
報錯資訊 | 說明 | 推薦的解決方案 |
| 當前叢集中無可用節點可供調度。 |
|
| 叢集中沒有可用節點能夠滿足Pod所需的CPU或記憶體資源。 | 在節點頁面查看容器組、CPU、記憶體的使用方式,確定叢集的資源使用率。 說明 當某個節點的CPU和記憶體利用率維持在較低水平時,即便引入一個新Pod不會立即達到資源使用的上限,調度器也會謹慎考慮,以防該Pod的加入導致未來高峰時段節點資源緊張,避免因資源分派不當而引發的節點資源短缺問題。 若叢集中的CPU或記憶體已經耗盡,可參考如下方法處理。
|
| 叢集現有節點沒有匹配Pod聲明的節點親和性(nodeSelector)要求或Pod親和性(podAffinity和podAntiAffinity)要求。 |
|
| Pod所使用的儲存卷與待調度的節點之間存在親和性衝突,雲端硬碟無法跨可用性區域掛載,導致調度失敗。 |
|
| ECS執行個體不支援掛載的雲端硬碟類型。 | 請參見執行個體規格類型系列確認當前ECS支援的雲端硬碟類型。掛載時,將雲端硬碟類型更新為ECS執行個體當前支援的類型。 |
| 由於節點擁有Pod無法容忍的汙點,導致Pod無法調度。 | |
| 節點臨時儲存容量不足。 |
|
| Pod綁定PVC失敗。 | 檢查Pod所指定的PVC或PV是否已經建立,通過 |
Pod已調度到節點
如果Pod已經被調度到某個節點上但仍處於Pending狀態,請參見下文解決。
判斷Pod是否配置了
hostPort:如果Pod配置了hostPort,那麼每個節點上只能運行一個使用該hostPort的Pod執行個體。因此,Deployment或ReplicationController中Replicas值不能超過叢集中的節點數。如果該連接埠被其他應用佔用,將導致Pod調度失敗。hostPort會帶來一些管理和調度上的複雜性,推薦您使用Service來訪問Pod,請參見服務(Service)。如果Pod沒有配置
hostPort,請參見下方步驟排查。通過
kubectl describe pod <pod-name>命令查看Pod的Event資訊,並解決對應的問題。Event可能會解釋Pod啟動失敗的原因,例如鏡像拉取失敗、資源不足、安全性原則限制、配置錯誤等。Event中沒有有效資訊時,進一步查看該節點kubelet的日誌,進一步排查Pod啟動過程中存在的問題。您可以通過
grep -i <pod name> /var/log/messages* | less命令搜尋系統記錄檔(/var/log/messages*)中包含指定Pod名稱的日誌條目。
階段二:鏡像拉取問題
ImagePullBackOff或ErrImagePull
Pod狀態為ImagePullBackOff或ErrImagePull時,即表明拉取鏡像失敗。在這種情況下,請查看Pod事件(Event),並根據下方的資訊排查問題。
報錯資訊 | 說明 | 推薦的解決方案 |
| 請求訪問鏡像倉庫時被拒絕,建立Pod時未指定 | 檢查工作負載YAML中 使用ACR時,可以使用免密外掛程式拉取鏡像,請參見安裝並使用免密組件非託管版。 |
| 通過HTTPS協議從指定的鏡像倉庫地址拉取鏡像時,鏡像位址解析失敗。 |
|
| 節點磁碟空間不足。 | 參見ECS遠端連線方式概述登入到Pod所在節點,運行 |
| 第三方倉庫使用了非知名或不安全的CA簽署的認證。 |
|
| 操作取消,可能是由於鏡像檔案過大。Kubernetes預設設定了拉取鏡像逾時時間,如果一定時間內鏡像下載沒有任何進度更新,Kubernetes會認為此操作異常或處於無響應狀態,主動取消該任務。 |
|
| 無法串連鏡像倉庫,網路不通。 |
|
| 拉取海外源鏡像時,因網路問題導致的連線逾時。 | 受電訊廠商網路的影響,在ACK叢集中拉取Docker Hub海外源鏡像可能出現拉取失敗的情況。可採用下列解決方案:
|
| DockerHub對使用者拉取容器鏡像的請求設定了上限。 | 將鏡像上傳至Container RegistryACR,從ACR鏡像倉庫中拉取鏡像。 |
一直顯示 | 可能觸發了kubelet的鏡像拉取限流機制。 | 通過自訂節點池kubelet配置功能調整registryPullQPS(鏡像倉庫的QPS上限)和registryBurst(突發性鏡像拉取的個數上限)。 |
階段三:啟動問題
Pod處於init狀態
錯誤資訊 | 說明 | 推薦的解決方案 |
停留在 | 該Pod包含M個Init容器,其中N個已經啟動完成,但仍有M-N個Init容器未啟動成功。 |
關於Init容器的更多資訊,請參見調試Init容器。 |
停留在 | Pod中的Init容器啟動失敗。 | |
停留在 | Pod中的Init容器啟動失敗並處於反覆重啟狀態。 |
Pod建立中(Creating)
錯誤資訊 | 說明 | 推薦的解決方案 |
| Flannel網路外掛程式設計原因,是預期內現象。 | 升級Flannel組件版本至v0.15.1.11-7e95fe23-aliyun及以上版本,請參見Flannel。 |
叢集低於1.20版本時,如果發生Pod反覆重啟、CronJob中的Pod在短時間內完成任務並退出等事件,可能會導致IP地址泄漏。 | 升級叢集版本至1.20及以上,推薦使用最新版本的叢集,請參見手動升級叢集。 | |
containerd、runC存在的缺陷。 | 參見為什麼Pod無法正常啟動,且報錯no IP addresses available in range?進行臨時緊急處理。 | |
| Pod所在的節點中,Terway網路外掛程式維護的用於追蹤和管理網路介面ENI的內部資料庫狀態與實際的網路裝置配置之間存在資料不一致,造成ENI分配失敗。 |
|
| 可能是Terway向vSwitch申請IP時失敗。 |
|
Pod啟動失敗(CrashLoopBackOff)
錯誤資訊 | 說明 | 推薦的解決方案 |
日誌中存在 |
| |
Pod事件中存在 | 存活探針(Liveness Probe)檢測失敗,應用重啟。 |
|
Pod事件中出現 | 啟動探針(Startup Probe)檢測失敗,應用重啟。 |
|
Pod日誌中存在 | 磁碟空間不足。 |
|
啟動失敗,無Event資訊。 | Pod中聲明的Limit資源少於實際所需資源時,會導致啟動容器失敗。 | 檢查Pod的資源配置是否正確。您可以啟用資源畫像,獲得容器Request和Limit的推薦配置。 |
Pod日誌中出現 | 同一Pod中的容器連接埠存在衝突。 |
|
Pod日誌中出現 | 工作負載中掛載了Secret,但Secret對應的值沒有進行Base64加密。 |
|
自身業務問題。 | 查看Pod日誌,通過日誌內容排查問題。 | |
Pod處於黃色Running狀態
報錯資訊 | 說明 | 推薦的解決方案 |
| 就緒探針(Readiness Probe)檢測失敗,目標Pod無法接入流量。 |
|
Pod狀態同上。Pod事件中出現 | 啟動探針(Startup Probe)檢測失敗,目標Pod無法接入流量。 | 同上,配置合適的啟動探測項。 |
階段四:Pod運行問題
OOMKilled
當叢集中的容器使用超過其限制的記憶體,容器可能會被終止,觸發OOM(Out Of Memory)事件,導致容器異常退出。關於OOM事件,請參見為容器和Pod分配記憶體資源。
若被終止的進程為容器的阻塞進程,可能會導致容器異常重啟。
若出現OOM異常問題,在控制台的Pod詳情頁面單擊事件頁簽將展示OOM事件
pod was OOM killed. node:XXX pod:XXX namespace:XXX。若叢集配置了叢集容器副本異常警示,OOM事件出現時會收到相關警示資訊,請參見容器副本異常警示規則集。
OOM層級 | 說明 | 推薦的解決方案 |
節點級 | 查看Pod所在節點的核心日誌 | |
CGroup級 | 查看Pod所在節點的核心日誌 |
|
更多OOM現象出現的原因及解決方案,請參見出現OOM Killer的原因及解決方案。
Terminating
可能原因 | 說明 | 推薦的解決方案 |
節點存在異常,處於NotReady狀態。 | 處於NotReady狀態的節點恢複正常後會被自動刪除。 | |
Pod配置了Finalizers。 | 如果Pod配置了Finalizers,Kubernetes會在刪除Pod之前執行Finalizers指定的清理操作。如果相關的清理操作沒有正常響應,Pod將保持在Terminating狀態。 | 通過 |
Pod的preStop配置異常。 | 如果Pod配置了preStop,Kubernetes會在容器被終止之前執行preStop指定的操作。Pod正處於終止流程的preStop階段時,Pod將處於Terminating狀態。 | 通過 |
Pod配置了優雅退出時間。 | 如果Pod配置了優雅退出時間( | 等待容器優雅退出後,Kubernetes將自動刪除Pod。 |
容器無響應。 | 發起停止或刪除Pod的請求後,Kubernetes會向Pod內的容器發送 |
|
Evicted
可能原因 | 說明 | 推薦的解決方案 |
節點存在資源壓力,包括記憶體不足、磁碟空間不足等,引發kubelet主動驅逐節點上的一個或者多個Pod,以回收節點資源。 | 可能存在記憶體壓力、磁碟壓力、Pid壓力等。
|
|
發生了非預期的驅逐行為。 | 待運行Pod的節點被手動打上了NoExecute的汙點,導致出現非預期的驅逐行為。 | 通過 |
未按照預期流程執行驅逐。 |
| 在小規格的叢集(叢集節點數小於等於50個節點)中,如果故障的節點大於總節點數的55%,執行個體的驅逐會被停止,更多資訊請參見節點驅逐速率限制。 |
在大規模叢集中(叢集節點數大於50),如果叢集中不健康的節點數量佔總節點數的比例超過了預設的閾值 | ||
容器被驅逐後仍然頻繁調度到原節點。 | 節點驅逐容器時會根據節點的資源使用率進行判斷,而容器的調度規則是根據節點上的“資源分派量”進行判斷,被驅逐的Pod有可能被再次調度到這個節點,從而出現頻繁調度到原節點的現象。 | 根據叢集節點的可分配資源檢查Pod的資源Request請求配置是否合理。如需調整,請參見設定容器的CPU和記憶體資源上下限。您可以啟用資源畫像,獲得容器Request和Limit的推薦配置。 |
Completed
Completed狀態下,Pod中容器的啟動命令已執行完畢,容器中的所有進程均已成功退出。Completed狀態通常適用於Job、Init容器等。
常見問題
Pod狀態為Running但沒正常工作
如果您的業務YAML存在問題,Pod可能會處於Running狀態但沒有正常工作。您可以參見以下流程解決。
查看Pod的配置,確定Pod中容器的配置是否符合預期。
使用以下方法,排查YAML配置中的某一個Key是否存在拼字錯誤。
建立Pod時,如果YAML中的某個Key拼字錯誤(例如將
command拼字為commnd),叢集會忽略該錯誤並使用該YAML成功建立資源。但在容器運行過程中,系統無法執行YAML檔案中指定的命令。下文以
command拼字成commnd為例,介紹拼字問題的排查方法。在執行
kubectl apply -f命令前為其添加--validate,然後執行kubectl apply --validate -f XXX.yaml命令。如拼字存在錯誤,會提示報錯
XXX] unknown field: commnd XXX] this may be a false alarm, see https://gXXXb.XXX/6842pods/test。執行以下命令,將輸出結果的pod.yaml與您建立Pod使用的YAML進行對比。
說明[$Pod]為異常Pod的名稱,您可以通過kubectl get pods命令查看。kubectl get pods [$Pod] -o yaml > pod.yamlpod.yaml檔案比您建立Pod所使用的檔案行數更多,表明已建立的Pod符合預期。
如果您建立Pod的YAML程式碼不存在於pod.yaml檔案中,表明YAML中存在拼字問題。
查看Pod的日誌,通過日誌內容排查問題。
通過終端進入容器,查看容器內的本地檔案是否符合預期。
Pod訪問資料庫機率性網路中斷
針對ACK叢集中Pod訪問資料庫有機率性網路中斷的問題,可以按照以下步驟進行排查。
1、檢查Pod
查看目的地組群中該Pod的事件記錄,檢查是否存在串連不穩定的例外狀況事件,例如網路異常、重啟事件、資源不足等。
查看Pod的日誌輸出,確定是否有與資料庫連接相關的錯誤資訊,例如逾時、認證失敗或者重連機制觸發等。
查看Pod的CPU和記憶體使用量情況,避免資源耗盡導致應用程式或資料庫驅動程式異常退出。
查看Pod的資源Request和Limit配置,確保Pod分配了足夠的CPU和記憶體資源。
2、檢查節點
查看節點的資源使用方式,確認是否有記憶體、磁碟等資源不足等情況。具體操作,請參見監控節點。
測試節點與目標資料庫之間是否出現機率性網路中斷。
3、檢查資料庫
檢查資料庫的狀態和效能指標,是否出現重啟或效能瓶頸。
查看異常串連數和連線逾時設定,並根據業務需求進行調整。
檢查資料庫日誌是否有相關中斷連線的記錄。
4、檢查叢集組件狀態
叢集組件異常會影響Pod與叢集內其他組件的通訊。使用如下命令,檢查ACK叢集組件狀態。
kubectl get pod -n kube-system # 查看組件Pod狀態。同時檢查網路組件:
CoreDNS組件:檢查組件狀態和日誌,確保Pod能正常解析資料庫服務的地址。
Flannel外掛程式:查看kube-flannel組件的狀態和日誌。
Terway外掛程式:查看terway-eniip組件的狀態和日誌。
5、分析網路流量
您可以使用 tcpdump 來抓包並分析網路流量,以協助定位問題的原因。
擷取Pod資訊與節點資訊:
使用以下命令擷取指定命名空間中的Pod資訊及其所在節點:
kubectl get pod -n [namespace] -o wide登入到目標節點,使用以下命令查看容器PID。
containerd(1.22以上叢集)
執行以下命令查看容器
CONTAINER。crictl ps |grep <Pod名稱關鍵字>預期輸出:
CONTAINER IMAGE CREATED STATE a1a214d2***** 35d28df4***** 2 days ago Running使用
CONTAINER ID參數,執行以下命令查看容器PIDcrictl inspect a1a214d2***** |grep -i PID預期輸出:
"pid": 2309838, # 目標容器的PID進程號。 "pid": 1 "type": "pid"
Docker(1.22及以下叢集)
執行以下命令查看容器
CONTAINER ID。docker ps |grep <pod名稱關鍵字>預期輸出:
CONTAINER ID IMAGE COMMAND a1a214d2***** 35d28df4***** "/nginx使用
CONTAINER ID參數,執行以下命令查看容器PID。docker inspect a1a214d2***** |grep -i PID預期輸出:
"Pid": 2309838, # 目標容器的PID進程號。 "PidMode": "", "PidsLimit": null,
執行抓包命令。
使用擷取到的容器PID,執行以下命令,捕獲Pod與目標資料庫之間的網路通訊資料包。
nsenter -t <容器PID> tcpdump -i any -n -s 0 tcp and host <資料庫IP地址>使用擷取到的容器PID,執行以下命令,捕獲Pod與宿主機之間的網路通訊資料包。
nsenter -t <容器PID> tcpdump -i any -n -s 0 tcp and host <節點IP地址>執行以下命令,捕獲宿主機與資料庫之間的網路通訊資料包。
tcpdump -i any -n -s 0 tcp and host <資料庫IP地址>
6、最佳化商務應用程式
在商務應用程式中實現資料庫連接的自動重連機制,確保資料庫發生切換或遷移時,應用程式能夠自動回復串連,無需人工幹預。
使用持久化的長串連而非短串連來與資料庫通訊。長串連能顯著降低效能損耗和資源消耗,提高系統整體效率。
常用排查介面
您可以登入Container Service管理主控台,進入叢集的詳情頁面,排查Pod可能存在的問題。
操作 | 控制台介面 |
檢查Pod的狀態 |
|
檢查Pod的基礎資訊 |
|
檢查Pod的配置 |
|
檢查Pod的事件 |
|
查看Pod的日誌 |
說明 ACK叢集整合了Log ServiceSLS。您可在叢集中啟用SLS,快速採集叢集的容器日誌,請參見採集ACK叢集容器日誌。 |
檢查Pod的監控 |
說明 ACK叢集整合了阿里雲Prometheus。您可以在叢集中快速啟用阿里雲Prometheus,以即時監控叢集和容器的健康情況,並查看可視化的Grafana監控資料大盤,請參見接入與配置阿里雲Prometheus監控。 |
使用終端進入容器,進入容器內部查看本地檔案等資訊 |
|
啟用Pod故障診斷 |
說明 容器智能營運平台提供了一鍵故障診斷能力,輔助您定位叢集中出現的問題,請參見使用叢集診斷。 |
叢集中的Pod被異常刪除
問題現象及原因:叢集裡 Completed 的 Pod 數量較多時,KCM(kube-controller-manager)為了避免無用的 Pod 數量過多,影響各類控制器效率,會在數量超過12500個後清理一下無用的 Pod。具體對應的 KCM 配置參數為--terminated-pod-gc-threshold,請參考社區 KCM 參數文檔。
處理建議:定期清理叢集中Completed狀態的Pod,防止數量過多,影響各類控制器效率。
> Containerd 配置。


Pod事件中出現