本文介紹關於Pod異常問題的診斷流程、排查方法、常見問題及解決方案。
本文目錄
類別 | 內容 |
診斷流程 | |
常見排查方法 | |
常見問題及解決方案 |
診斷流程
查看Pod是否處於異常狀態,具體操作,請參見檢查Pod的狀態。
如果Pod狀態異常,可通過查看Pod的事件、Pod的日誌、Pod的配置等資訊確定異常原因。具體操作,請參見常見排查方法。關於Pod異常狀態及處理方式,請參見常見的Pod異常狀態及處理方式。
如果Pod狀態為Running但未正常工作,請參見Pod狀態為Running但沒正常工作。
若確認是Pod OOM異常問題,請參見Pod OOM異常問題處理。
如果問題仍未解決,請提交工單。
常見的Pod異常狀態及處理方式
Pod狀態 | Pod含義 | 解決方案 |
Pending | Pod未被調度到節點上。 | |
Init:N/M | Pod包含M個Init容器,其中N個已經啟動完成。 | |
Init:Error | Init容器已啟動失敗。 | |
Init:CrashLoopBackOff | Init容器啟動失敗,反覆重啟。 | |
Completed | Pod的啟動命令已執行完畢。 | |
CrashLoopBackOff | Pod啟動失敗,反覆重啟。 | |
ImagePullBackOff | Pod鏡像拉取失敗。 | |
Running |
| |
Terminating | Pod正在關閉中。 | |
Evicted | Pod被驅逐。 |
常見排查方法
檢查Pod的狀態
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面左上方選擇Pod所在的命名空間,查看Pod狀態。
若狀態為Running,說明Pod運行正常。
若狀態不為Running,說明Pod狀態異常,請參見常見的Pod異常狀態及處理方式進行處理。
檢查Pod的詳情
在控制台左側導覽列,單擊叢集。
在叢集列表頁面中,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面左上方選擇Pod所在的命名空間,然後單擊目標Pod名稱或者目標Pod右側操作列下的詳情,查看Pod的名稱、鏡像、Pod IP、所在節點等詳細資料。
檢查Pod的配置
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面左上方選擇Pod所在的命名空間,然後單擊目標Pod名稱或者目標Pod右側操作列下的詳情。
在Pod詳情頁面右上方單擊編輯,查看Pod的YAML檔案和詳細配置。
檢查Pod的事件
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面左上方選擇Pod所在的命名空間,然後單擊目標Pod名稱或者目標Pod右側操作列下的詳情。
在Pod詳情頁面下方單擊事件頁簽,查看Pod的事件。
說明Kubernetes預設保留最近1小時的事件,若需儲存更長時間的事件,請參見建立並使用K8s事件中心。
檢查Pod的日誌
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面左上方選擇Pod所在的命名空間,然後單擊目標Pod名稱或者目標Pod右側操作列下的詳情。
在Pod詳情頁面下方單擊日誌頁簽,查看Pod的日誌。
說明阿里雲ACK叢集整合了Log Service,您可在建立叢集時啟用Log Service,快速採集叢集的容器日誌,包括容器的標準輸出及容器內的文字檔。更多資訊,請參見通過Log Service採集Kubernetes容器日誌。
檢查Pod的監控
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列中,選擇 。
在Prometheus監控頁面,單擊叢集監控概覽頁簽,選擇查看Pod的CPU、記憶體、網路I/O等監控大盤。
使用終端進入容器
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面,單擊目標容器組右側操作列下的終端。
可通過終端進入容器,在容器內查看本地檔案等資訊。
Pod故障診斷
在控制台左側導覽列,單擊叢集。
在叢集列表頁面,單擊目的地組群名稱或者目的地組群右側操作列下的詳情。
在叢集管理頁左側導覽列,選擇 。
在容器組頁面,單擊目標容器組右側操作列下的診斷。
對該容器組進行故障診斷,根據診斷結果解決問題。更多資訊,請參見使用叢集診斷。
Pod狀態為Pending
問題原因
若Pod停留在Pending狀態,說明該Pod不能被調度到某一個節點上。通常是由於資源依賴、資源不足、該Pod使用了hostPort、汙點和容忍等原因導致叢集中缺乏需要的資源。
問題現象
Pod的狀態為Pending。
解決方案
查看Pod的事件,根據事件描述,定位Pod不能被調度到節點的原因。主要原因有以下幾類:
資源依賴
建立Pod時,需要依賴於叢集中ConfigMap、PVC等資源。例如,Pod添加儲存卷聲明前,儲存卷聲明需要先與儲存卷綁定。
資源不足
在叢集資訊頁面,選擇
,查看容器組、CPU、記憶體的使用方式,確定叢集的資源使用率。說明某個節點實際使用的CPU、記憶體資源非常低,新加入一個Pod時,如果會導致實際使用的資源超過該節點最大可供使用的資源,則發送器不會將該Pod分配到該節點。這樣可避免在日常的流量高峰時段,節點上出現資源短缺的情況。
若叢集中的CPU或記憶體都已經耗盡,可參考如下方法處理。
刪除或減少不必要的Pod。具體操作,請參見管理容器組(Pod)。
根據自身業務情況,調整Pod的資源配置。具體操作,請參見設定容器的CPU和記憶體資源上下限。
在叢集中添加新的節點。具體操作,請參見建立節點池。
為節點進行升配。具體操作,請參見升配Worker節點的資源。
該Pod使用了hostPort
如果您使用了hostPort,那麼Deployment或ReplicationController中
Replicas
值不能超過叢集中的節點數,因為每個執行個體的任意連接埠只有一個。如果該連接埠被其他應用佔用,將導致Pod調度失敗。因此建議您不要使用hostPort,您可以使用Service訪問Pod,更多資訊,請參見Service。汙點和容忍
當您在Pod的事件中看到Taints或Tolerations時,說明是由於汙點導致,您可以刪除汙點或者給Pod設定容忍。更多資訊,請參見管理節點汙點、建立無狀態工作負載Deployment和汙點和容忍。
Pod狀態為Init:N/M(Init:Error和Init:CrashLoopBackOff)
問題原因
若Pod停留在Init:N/M狀態,說明該Pod包含M個Init容器,其中N個已經啟動完成,但仍有M-N個Init容器未啟動成功。
若Pod停留在Init:Error狀態,說明Pod中的Init容器啟動失敗。
若Pod停留在Init:CrashLoopBackOff狀態,說明Pod中的Init容器啟動失敗並處於反覆重啟狀態。
問題現象
Pod的狀態為Init:N/M。
Pod的狀態為Init:Error。
Pod的狀態為Init:CrashLoopBackOff。
解決方案
Pod狀態為ImagePullBackOff
問題原因
若Pod停留在ImagePullBackOff狀態,說明此Pod已被調度到某個節點,但拉取鏡像失敗。
問題現象
Pod的狀態為ImagePullBackOff。
解決方案
通過查看該Pod的事件描述,查看具體拉取失敗的鏡像名稱。
確認容器鏡像名稱是否正確。
登入到Pod所在的節點,執行
docker pull [$Image]
命令,查看是否能正常抓取容器鏡像。說明[$Image]
為容器鏡像的名稱。若鏡像拉取失敗,請參見docker pull失敗解決。
如果您使用的是私人鏡像倉庫,請參見使用私人鏡像倉庫建立應用解決。
Pod狀態為CrashLoopBackOff
問題原因
若Pod停留在CrashLoopBackOff狀態,說明容器中應用程式有問題。
問題現象
Pod的狀態為CrashLoopBackOff。
解決方案
查看Pod的事件,確認當前Pod是否存在異常。具體操作,請參見檢查Pod的事件。
查看Pod的日誌,通過日誌內容排查問題。具體操作,請參見檢查Pod的日誌。
查看Pod的配置,確認容器中的健全狀態檢查配置是否正常。具體操作,請參見檢查Pod的配置。關於Pod健全狀態檢查的更多資訊,請參見配置存活、就緒和啟動探測器。
Pod狀態為Completed
問題原因
若Pod出現Completed狀態,說明容器中的啟動命令已執行完畢,容器中的所有進程都已退出。
問題現象
Pod的狀態為Completed。
解決方案
Pod狀態為Running但沒正常工作
問題原因
部署使用的YAML檔案有問題。
問題現象
Pod狀態為Running但沒正常工作。
解決方案
查看Pod的配置,確定Pod中容器的配置是否符合預期。具體操作,請參見檢查Pod的配置。
使用以下方法,排查環境變數中的某一個Key是否存在拼字錯誤。
以command拼字成commnd為例,說明拼字問題排查方法。
說明建立Pod時,環境變數中的某一個Key拼字錯誤的問題會被叢集忽略,如Command拼字為Commnd,您仍能夠使用該YAML檔案建立資源。但容器運行時,不會執行有拼字問題的YAML檔案,而是執行鏡像中的預設命令。
在執行
kubectl apply -f
命令前為其添加--validate
,然後執行kubectl apply --validate -f XXX.yaml
命令。如果您將command拼字成commnd,將看到錯誤資訊
XXX] unknown field: commnd XXX] this may be a false alarm, see https://gXXXb.XXX/6842pods/test
。執行以下命令,將輸出結果的pod.yaml檔案與您建立Pod使用的檔案進行對比。
kubectl get pods [$Pod] -o yaml > pod.yaml
說明[$Pod]
為異常Pod的名稱,您可以通過kubectl get pods
命令查看。pod.yaml檔案比您建立Pod所使用的檔案多幾行,說明已建立的Pod符合預期。
如果您建立Pod所使用檔案裡的程式碼在pod.yaml檔案中沒有,說明您建立Pod使用的檔案存在拼字問題。
查看Pod的日誌,通過日誌內容排查問題。具體操作,請參見檢查Pod的日誌。
可通過終端進入容器查看容器內的本地檔案是否符合預期。具體操作,請參見使用終端進入容器。
Pod狀態為Terminating
問題原因
若Pod的狀態為Terminating,說明此Pod正處於關閉狀態。
問題現象
Pod狀態為Terminating。
解決方案
Pod停留在Terminating狀態一段時間後會被自動刪除。若Pod一直停留在Terminating狀態,可執行如下命令強制移除:
kubectl delete pod [$Pod] -n [$namespace] --grace-period=0 --force
Pod狀態為Evicted
問題原因
當節點的記憶體、磁碟空間、檔案系統的inode和作業系統可分配的PID等資源中的一個或者多個達到特定的消耗水平,就會引發kubelet主動地驅逐節點上一個或者多個Pod,以回收節點資源。
問題現象
Pod的狀態為Evicted。
解決方案
執行以下命令,查看Pod的
status.message
欄位,來確定Pod被驅逐的原因。kubectl get pod [$Pod] -o yaml -n [$namespace]
預期輸出:
status: message: 'Pod the node had condition: [DiskPressure].' phase: Failed reason: Evicted
通過上述
status.message
欄位,可以判斷當前Pod是因為節點磁碟壓力 (DiskPressure) 被驅逐。說明注意這裡僅以磁碟壓力驅逐為例,其它例如記憶體壓力(MemoryPressure)和PID壓力(PIDPressure)等也會以類似的方式展示。
執行以下命令,刪除被驅逐的Pod。
kubectl get pods -n [$namespace]| grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n [$namespace]
以下匯總如何避免Pod被驅逐的方法:
記憶體壓力:
根據自身業務情況,調整Pod的資源配置。具體操作,請參見設定容器的CPU和記憶體資源上下限。
為節點進行升配。具體操作,請參見升配Worker節點的資源。
磁碟壓力:
定時清理節點上的業務Pod日誌,避免磁碟被日誌打滿。
為節點進行磁碟擴容。具體操作,請參見步驟一:擴容雲端硬碟容量。
PID壓力:根據自身業務情況,調整Pod的資源配置,具體操作,請參見進程ID約束與預留。
Pod OOM異常問題處理
問題原因
當叢集中的容器使用超過其限制的記憶體,容器可能會被終止,觸發OOM(Out Of Memory)事件,導致容器異常退出。關於OOM事件,請參見為容器和Pod分配記憶體資源。
問題現象
若被終止的進程為容器的阻塞進程,可能會導致容器異常重啟。
若出現OOM異常問題,登入Container Service管理主控台,在Pod詳情頁面單擊事件頁簽可看到OOM事件pod was OOM killed。具體操作,請參見檢查Pod的事件。
若叢集配置了叢集容器副本異常警示,則OOM事件出現時可收到相關警示。關於配置警示,請參見Container Service警示管理。
解決方案
查看發生OOM異常的Pod所在的節點。
命令列方式查看:執行以下命令,查看容器資訊。
kubectl get pod [$Pod] -o wide -n [$namespace]
預期輸出:
NAME READY STATUS RESTARTS AGE IP NODE pod_name 1/1 Running 0 25h 172.20.6.53 cn-hangzhou.192.168.0.198
控制台方式查看:查看Pod詳情下的節點資訊,請參見檢查Pod的詳情。
登入Pod所在的Node,查看核心日誌
/var/log/message
。在日誌中查詢關鍵字out of memory
,確認具體被OOM終止的進程。如果該進程是容器的阻塞進程,OOM終止後容器會重啟。通過Pod記憶體監控查看記憶體增長曲線,確定異常出現時間。具體操作,請參見檢查Pod的監控。
根據監控、記憶體增長時間點、日誌、進程名等資訊,排查Pod內對應進程是否存在記憶體流失。
若OOM是進程記憶體流失導致,請您自行排查泄露原因。
若進程運行狀態正常,則根據實際運行需要,適當增大Pod的記憶體限制,建議Pod的記憶體實際使用量不超過記憶體限制值的80%。具體操作,請參見設定容器的CPU和記憶體資源上下限。
Pod訪問資料庫機率性網路斷聯
針對ACK叢集中Pod訪問資料庫有機率性網路斷聯的問題,可以按照以下排查步驟進行分析和解決:
檢查Pod:
檢查節點:
查看節點的資源使用方式,確認是否有記憶體、磁碟等資源不足等情況。操作詳情,請參見監控節點。
測試節點到與目標資料庫是否出現機率性網路斷聯。
檢查資料庫:
檢查資料庫的狀態和效能指標,是否出現重啟或效能瓶頸。
查看異常串連數,連線逾時設定,並根據業務需要調整。
檢查日誌資料庫可能有相關中斷連線的日誌。
叢集組件狀態:
叢集組件異常會影響Pod與叢集內其他組件的通訊。使用如下命令,檢查ACK叢集組件狀態。
kubectl get pod -n kube-system # 查看組件Pod狀態。
檢查網路外掛程式:
coredns組件的狀態和日誌,確保Pod能正常解析資料庫服務的地址。
Flannel外掛程式可查看kube-flannel組件的狀態和日誌。
Terway外掛程式可查看terway-eniip組件的狀態和日誌。
網路流量分析:
可以使用
tcpdump
來抓包並分析網路流量,以協助定位問題的原因。使用以下命令確定資料庫連接斷開問題發生在哪個Pod和哪個節點上。
kubectl get pod -n [namespace] -o wide
登入到目標節點。操作步驟詳情,請參見通過密碼或密鑰認證登入Linux執行個體。
使用以下命令,分別擷取不同版本的容器進程PID。
1.22版本以上,使用containerd服務:
執行以下命令查看容器
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"
1.22版本及以下,使用Docker服務:
執行以下命令查看容器
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,
執行抓包命令。
Pod端與目標資料庫端之間抓包。使用擷取到的容器PID,執行以下命令。
nsenter -t <容器PID> tcpdump -i any -n -s 0 tcp and host <資料庫IP地址>
Pod端與宿主機端之間抓包。使用擷取到的容器PID,執行以下命令。
nsenter -t <容器PID> tcpdump -i any -n -s 0 tcp and host <節點IP地址>
宿主機端與資料庫端之間抓包。
tcpdump -i any -n -s 0 tcp and host <資料庫IP地址>
最佳化商務應用程式:
在商務應用程式中實現資料庫連接的自動重連機制,確保資料庫發生切換或遷移時,應用程式能夠無需人工幹預自動回復串連。
使用持久化的長串連而非短串連來與資料庫通訊。長串連能顯著降低效能損耗和資源消耗,提高系統整體效率。