故障排除:Pod、Node、Control Plane 怎麼查

· tech

#kubernetes#troubleshooting

📑 目錄

CKA 佔比最高的一塊是故障排除(30%),但它其實不是新知識——它是把前面整個系列串起來的能力。排障最忌諱用猜的、亂試一通。真正的心法只有一句:沿著 Pod 的生命週期,一關一關問「它卡在哪」——因為 K8s 很貼心,它把「卡在哪一關」直接寫在狀態裡了。

① 排程到 nodeScheduler 挑一台 ② 拉映像檔kubelet 去 registry 拉 ③ 起容器・活著跑起來且不崩 ④ Ready・進 Endpoints通過 readiness 才收流量 ✓ 正常收流量 Pending資源不足 / taint 沒 toleration / PVC 綁不到 ImagePullBackOff · ErrImagePull映像名打錯 / 私有 registry 少 imagePullSecret CrashLoopBackOff · OOMKilled起來就掛一直重啟 / 超過記憶體 limit 被砍 Running 卻 not Ready · 連不到readiness 失敗 / Endpoints 空(selector 錯)/ DNS 解不到 / NetworkPolicy 擋掉
一張圖收掉大半排障:Pod 從 apply 到收流量要過四關,每一關卡住都對應一個特定狀態。看到狀態,就知道問題卡在生命週期的哪一段——這也是為什麼整個系列讀完,排障才會從「亂猜」變成「按圖索驥」

第一步永遠是這三條指令:get → describe → logs

不管什麼症狀,起手式固定這個順序,由外而內剝洋蔥:

kubectl get現在什麼狀態? kubectl describe為什麼?看 Events 段 kubectl logs程式自己說了什麼? exec / debug進去現場戳 但動手前先問一句:這是哪一層的事? Pod 層狀態 / Events / logs上面那組指令就夠最常見、先查這層 Node 層node NotReadykubelet 掛 / 磁碟壓力journalctl -u kubelet Control Plane 層api-server / etcd 掛→ 整個叢集指令失靈看 static pod manifest
排障漏斗:get(什麼狀態)→ describe(為什麼——Events 段是金礦)→ logs(程式說了什麼)→ exec/debug(進現場)。但動手前先分層:多數問題在 Pod 層,查不到再往 NodeControl Plane 上找

最被低估的一條是 kubectl describe:它最下面的 Events 段,幾乎把 K8s 剛才「想做什麼、卡在哪」全寫出來了——排程失敗的原因、映像拉不動的錯誤、readiness probe 一直失敗、被 OOM 砍掉,全在這。很多人一出事就衝去看 logs,但答案往往在 Events 裡,而且更直接。 幾條常用的:

kubectl get pods -o wide              # 狀態、重啟次數、落在哪台 node
kubectl describe pod <p>              # 看最底下 Events 段(最重要)
kubectl logs <p> --previous           # CrashLoop 必用:看「上一個掛掉的」實例日誌
kubectl get events --sort-by=.lastTimestamp   # 全 namespace 依時間排的事件流

logs --previous 是排 CrashLoopBackOff 的關鍵:容器已經崩掉重啟了,當下的 logs 是新實例、常常空的,你要的是上一個崩掉那次留下的最後幾行。

讀懂 Pod 狀態:每個狀態都在指路

把第一張圖的四關攤成一張對照表,看到狀態就知道往哪查、根因大概是什麼:

狀態卡在哪一關最常見根因先查
Pending① 排不進 node資源不夠、[[k8s-scheduling-advancedtaint 沒 toleration]]、PVC 綁不到 PV
ContainerCreating 卡住①→② 之間CNI 沒配好、Volume 掛不上、Secret/ConfigMap 不存在describe Events
ImagePullBackOff② 拉映像映像名 / tag 打錯、私有 registry 少 imagePullSecretdescribe Events(Failed to pull)
CrashLoopBackOff③ 起了就掛程式啟動即崩、設定錯、[[k8s-config-secret少了環境變數]]、probe 設太嚴
OOMKilled③ 記憶體爆實際用量超過 memory limit 被砍describe(Last State: OOMKilled)、調 limit
Running 但 0/1 READY④ 沒通過 readinessreadiness probe 一直失敗 → 不進 [[k8s-serviceEndpoints]]、收不到流量
Running 但連不到④ 網路層selector 打錯 Endpoints 是空的、[[k8s-ingress-dnsDNS]] 解不到、[[k8s-networkpolicy-cni

這張表就是把整個系列反過來用:每一種故障,都是前面某一篇講過的機制在「沒運作」。 排障排的不是新東西,是你懂不懂那些機制。

換一層看:Node 與 Control Plane

如果一整台 node 上的 Pod 全出事,別再盯著 Pod——問題在 Node 層kubectl get nodes 看到 NotReady,通常是那台的 kubelet 掛了、磁碟/記憶體壓力(DiskPressure / MemoryPressure)、或網路斷了。這時候得 SSH 上去用 journalctl -u kubelet 看 kubelet 的日誌、用 crictl 直接問容器執行期,而不是隔著 API 猜。

再往上,如果連 kubectl 本身都開始逾時、整個叢集像失聯——那是 Control Plane 層。api-server 或 etcd 出事,整個叢集的「下命令」能力就癱了。因為它們是 static pod,你得去 control plane 那台看 /etc/kubernetes/manifests、看那幾顆 pod 的容器狀態與日誌。一層一層往上,是因為越上層炸得越大:Pod 掛只影響一個服務,control plane 掛影響整座叢集。

kubectl debug:連 shell 都沒有時

有個實務常撞的牆:現在很多映像檔為了精簡與安全,是 distroless / 沒有 shell 的,你 kubectl exec -it -- sh 直接失敗,無從進去看。kubectl debug 就是解法——它用 ephemeral container 把一個帶工具的臨時容器,塞進同一個 Pod、共享它的網路與行程空間,讓你在旁邊 curl、看檔案、抓封包,而完全不動原本的容器:

kubectl debug -it <p> --image=busybox --target=<container>   # 塞一個臨時容器進去查
kubectl debug node/<node> -it --image=busybox                # 連 node 都能開一個特權容器來查

不用為了 debug 去改映像檔硬塞工具、也不用重啟 Pod 破壞現場——這是排查那些「精簡到沒東西可用」的 Production 容器時,最該記住的一招。

反思

排障的功力,不在背指令,在有沒有一張「生命週期地圖」

我看過太多人排障靠玄學:狀態沒細看,就開始重啟 Pod、砍了重建、改一堆設定碰運氣。真正有效的排障,是心裡有第一張圖那張生命週期地圖——看到 Pending 就知道是排程關、看到 ImagePullBackOff 就知道是映像關、看到 not Ready 就知道往 readiness 與 Endpoints 查。狀態不是報錯,是 K8s 在告訴你它走到哪一步走不下去了。 把這張地圖內化之後,排障就從「亂試到好」變成「看一眼就知道往哪挖」,這中間的效率差距是十倍起跳。這也呼應我在 SRE 排障那篇的核心主張:系統化的心智模型,永遠贏過臨場的靈光一閃。

Events 段是最被低估的金礦

如果只能留一條排障建議,我會說:describe,看 Events。 它是 K8s 主動幫你寫好的「剛才發生了什麼」——排程器為什麼放不進、映像為什麼拉不動、probe 為什麼失敗,全在那幾行。我早年的壞習慣是一出事就鑽進 logs,結果 logs 是應用層的輸出,常常跟「Pod 起不來」這種平台層問題根本無關。先問平台(Events)、再問應用(logs),這個順序讓我少走無數冤枉路。工具早就把答案攤在那了,差別只在你有沒有先看對地方。

這一篇讀完,整個系列才真的閉環

寫到這裡,我特別有感:故障排除之所以是 CKA 最大宗,正因為它不是獨立的一章,而是全部的驗收。你得懂 reconcile loop 才知道 Pod 為什麼會自己重啟、懂 排程才看得懂 Pending、懂 ServiceDNS 才追得到「連不到」、懂 etcd 與 control plane才敢動最上層。排障能力是這些理解的總和,騙不了人。 所以我從不把「會不會查問題」當成一種獨立技能去練——它是你對這個系統理解夠不夠深的溫度計。整個系列走到這,從「宣告式」到「排障」,剛好繞回原點:你越懂它平常怎麼運作,出事時就越知道它是哪裡沒運作。