Kubernetes 集羣故障通常集中在 Pod 異常、Service/網絡不通、存儲掛載失敗、節點狀態異常、配置錯誤 等場景。以下按錯誤環境分類,梳理排錯思路、常見原因及對應命令,覆蓋 90% 生產/測試環境問題。
一、Pod 異常環境(最常見)
現象:Pod 處於 Pending、CrashLoopBackOff、ImagePullBackOff、Terminating等狀態,無法正常運行。
1. Pod 處於 Pending狀態(調度失敗)
可能原因:資源不足(CPU/內存/存儲)、調度約束(親和性/反親和性)、PVC 未綁定、節點標籤不匹配。
排查思路:
- 檢查 Pod 事件(Events)中的調度失敗原因;
- 查看節點資源是否充足;
- 檢查調度約束(如
nodeSelector、affinity)是否匹配節點標籤。
關鍵命令:
# 1. 查看 Pod 詳細事件(核心!)
kubectl describe pod <pod-name> [-n <namespace>] | grep -A 20 "Events:"
# 示例輸出關鍵信息:
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# Warning FailedScheduling 2m default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
# 2. 檢查節點資源使用(需 metrics-server)
kubectl top nodes # 查看節點 CPU/內存使用率
kubectl describe nodes | grep -A 10 "Allocatable" # 查看節點可分配資源
# 3. 檢查調度約束(如 nodeSelector)
kubectl get pod <pod-name> -o jsonpath='{.spec.nodeSelector}'
kubectl get nodes --show-labels | grep <label-key> # 檢查節點是否匹配標籤
# 4. 檢查 PVC 是否綁定(若 Pod 掛載 PVC)
kubectl get pvc [-n <namespace>] # 查看 PVC 狀態是否為 Bound
2. Pod 處於 CrashLoopBackOff狀態(反覆重啓)
可能原因:應用啓動失敗(配置錯誤、依賴缺失)、健康檢查(liveness/readiness probe)未通過、容器退出碼非 0。
排查思路:
- 查看容器日誌(定位應用層錯誤);
- 檢查健康檢查配置是否合理;
- 進入容器手動執行啓動命令,驗證環境。
關鍵命令:
# 1. 查看容器日誌(實時追蹤 + 歷史日誌)
kubectl logs -f <pod-name> [-c <container-name>] [-n <namespace>] # 實時日誌
kubectl logs --previous <pod-name> [-c <container-name>] [-n <namespace>] # 上一次啓動日誌(重啓前)
# 示例:查看 Nginx 容器日誌是否有 404/502 錯誤
kubectl logs -f my-nginx -c nginx -n web
# 2. 檢查健康檢查配置
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].livenessProbe}'
# 若配置不當(如端口錯誤、路徑不存在),會導致容器被重啓
# 3. 進入容器手動調試(驗證環境變量、依賴)
kubectl exec -it <pod-name> -- sh # 進入容器 Shell
# 手動執行啓動命令(如查看配置文件是否存在)
cat /etc/nginx/nginx.conf
curl http://localhost:80 # 測試應用是否能本地訪問
3. Pod 處於 ImagePullBackOff狀態(鏡像拉取失敗)
可能原因:鏡像名稱錯誤、鏡像倉庫認證失敗(私有倉庫)、網絡無法訪問鏡像倉庫。
排查思路:
- 檢查鏡像名稱和 tag 是否正確;
- 驗證私有倉庫認證(Secret 是否正確綁定);
- 測試節點/集羣能否訪問鏡像倉庫(如 Docker Hub、Harbor)。
關鍵命令:
# 1. 查看 Pod 事件(確認鏡像拉取錯誤細節)
kubectl describe pod <pod-name> | grep -A 10 "Events:"
# 示例錯誤:"Failed to pull image \"my-private-repo/app:v1\": rpc error: code = Unknown desc = Error response from daemon: pull access denied"
# 2. 檢查鏡像名稱和 tag(YAML 中 image 字段)
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].image}'
# 3. 測試鏡像拉取(在節點上手動執行,需 Docker 環境)
docker pull <image-name>:<tag> # 如 docker pull nginx:latest
# 4. 檢查私有倉庫 Secret(若使用私有倉庫)
kubectl get secret -n <namespace> | grep registry # 查看是否存在 registry-secret
kubectl describe secret <registry-secret> -n <namespace> # 檢查認證信息是否正確
二、Service/網絡不通環境
現象:Pod 間無法通信、外部無法訪問 Service、DNS 解析失敗。
1. Service 無法訪問(外部/內部)
可能原因:Service 類型配置錯誤(如 LoadBalancer 未分配 IP、NodePort 端口未開放)、Endpoint 為空(selector 不匹配)、網絡策略限制。
排查思路:
- 檢查 Service 的
Endpoints是否存在(確認流量能路由到 Pod); - 驗證 Service 端口映射(
port/targetPort/nodePort); - 檢查防火牆/安全組/網絡策略是否放行流量。
關鍵命令:
# 1. 查看 Service 詳情(端口映射、selector)
kubectl describe svc <svc-name> [-n <namespace>]
# 關鍵字段:Ports(port/targetPort/nodePort)、Selector(是否匹配 Pod 標籤)
# 2. 查看 Endpoint(確認是否有 Pod IP)
kubectl get endpoints <svc-name> [-n <namespace>]
# 若 Endpoints 為空:① selector 標籤不匹配;② Pod 未 Running;③ Pod 未通過 readinessProbe
# 3. 測試 Service 訪問(從集羣內部)
kubectl exec -it <any-pod> -- curl http://<svc-cluster-ip>:<port> # ClusterIP 訪問
kubectl exec -it <any-pod> -- curl http://<node-ip>:<nodePort> # NodePort 訪問
# 4. 檢查網絡策略(是否限制流量)
kubectl get networkpolicy [-n <namespace>] # 列出所有網絡策略
kubectl describe networkpolicy <np-name> [-n <namespace>] # 查看允許的 IP/端口
2. 外部無法訪問 LoadBalancer Service
可能原因:MetalLB/IP 分配失敗、NodePort 未開放、防火牆攔截、BGP 路由未配置(若用 BGP 模式)。
排查思路:
- 檢查 LoadBalancer 的
EXTERNAL-IP是否分配(非<pending>); - 驗證節點防火牆是否開放 NodePort 或 LoadBalancer 端口;
- 檢查 MetalLB 配置(IP 池、網絡模式)。
關鍵命令:
# 1. 查看 LoadBalancer Service 狀態
kubectl get svc <svc-name> [-n <namespace>]
# 關鍵字段:EXTERNAL-IP(是否分配)、PORT(S)(外部端口)
# 2. 測試節點端口訪問(若為 NodePort/LoadBalancer)
curl http://<node-ip>:<nodePort> # 替換為實際節點 IP 和端口
# 3. 檢查節點防火牆(以 firewalld 為例)
sudo firewall-cmd --list-ports | grep <nodePort> # 查看端口是否開放
sudo firewall-cmd --add-port=<nodePort>/tcp --permanent && sudo firewall-cmd --reload # 開放端口
3. Pod 間網絡不通
可能原因:網絡插件異常(Calico/Cilium/Flannel)、網絡策略限制、節點路由問題。
排查思路:
- 檢查網絡插件 Pod 是否正常運行;
- 測試 Pod 間連通性;
- 查看網絡策略是否放行。
關鍵命令:
# 1. 檢查網絡插件狀態(以 Calico 為例)
kubectl get pods -n kube-system -l k8s-app=calico-node # 所有 Pod 需為 Running
kubectl logs -n kube-system <calico-pod-name> | grep -i "error" # 查看插件日誌
# 2. 測試 Pod 間連通性(獲取兩個 Pod IP)
POD1_IP=$(kubectl get pod <pod1> -o jsonpath='{.status.podIP}')
POD2_IP=$(kubectl get pod <pod2> -o jsonpath='{.status.podIP}')
kubectl exec <pod1> -- curl -I http://$POD2_IP:80 # 從 Pod1 訪問 Pod2
# 3. 檢查路由表(在節點上執行)
ip route show # 查看是否有到其他節點 Pod 網段的路由(由網絡插件配置)
4. DNS 解析失敗
現象:Pod 內無法解析 Service 名稱(如 nslookup my-svc.my-namespace.svc.cluster.local失敗)。
可能原因:CoreDNS/Kube-DNS 異常、Pod /etc/resolv.conf配置錯誤。
關鍵命令:
# 1. 檢查 CoreDNS 狀態
kubectl get pods -n kube-system -l k8s-app=kube-dns # 所有 Pod 需為 Running
kubectl logs -n kube-system <coredns-pod-name> | grep -i "error" # 查看 DNS 日誌
# 2. 在 Pod 內測試 DNS 解析
kubectl exec <pod-name> -- nslookup <svc-name>.<namespace>.svc.cluster.local
# 示例:nslookup my-nginx.web.svc.cluster.local
# 3. 檢查 Pod 的 /etc/resolv.conf
kubectl exec <pod-name> -- cat /etc/resolv.conf
# 正常應包含 nameserver 10.96.0.10(Cluster DNS IP)和 search 域
三、存儲異常環境
現象:Pod 無法掛載 PVC、數據無法持久化、PVC 處於 Pending狀態。
1. PVC 處於 Pending狀態(未綁定 PV)
可能原因:StorageClass 未配置、PV 不足、PVC 請求參數(如 accessMode、storage)與 PV 不匹配。
排查思路:
- 檢查 PVC 事件(Events)中的綁定失敗原因;
- 驗證 StorageClass 是否存在且配置正確;
- 檢查 PV 是否滿足 PVC 的請求(容量、accessMode)。
關鍵命令:
# 1. 查看 PVC 詳情
kubectl describe pvc <pvc-name> [-n <namespace>]
# 關鍵字段:Status(Pending)、Events(錯誤信息,如 "no persistent volumes available for this claim")
# 2. 檢查 StorageClass
kubectl get storageclass # 查看是否存在 PVC 指定的 StorageClass
kubectl describe storageclass <sc-name> # 檢查 provisioner(如 csi-hostpath)是否正常
# 3. 檢查 PV(動態供應的 PV 由 StorageClass 自動創建)
kubectl get pv # 查看是否有 PV 狀態為 Bound 且容量/模式匹配 PVC
2. Pod 無法掛載卷(MountVolume 失敗)
可能原因:存儲卷權限不足(如 MinIO 數據目錄 UID 不匹配)、存儲插件異常、卷類型不支持。
排查思路:
- 進入 Pod 查看掛載點是否正常;
- 檢查存儲卷權限(如容器用户 UID 是否有讀寫權限);
- 查看 kubelet 日誌是否有卷掛載錯誤。
關鍵命令:
# 1. 查看 Pod 掛載信息
kubectl get pod <pod-name> -o jsonpath='{.spec.volumes[*].persistentVolumeClaim.claimName}'
kubectl describe pod <pod-name> | grep -A 10 "Mounts:" # 查看掛載點和卷名稱
# 2. 進入 Pod 檢查掛載目錄
kubectl exec -it <pod-name> -- df -h /<mount-path> # 查看磁盤空間和使用
ls -ld /<mount-path> # 檢查目錄權限(如 MinIO 需 UID 1000 可寫)
# 3. 查看 kubelet 日誌(節點上執行)
journalctl -u kubelet | grep -i "mount" # 過濾卷掛載錯誤(如 "MountVolume.SetUp failed")
四、節點異常環境
現象:節點狀態 NotReady、Pod 無法調度到節點、kubelet 異常。
1. 節點處於 NotReady狀態
可能原因:kubelet 服務崩潰、節點資源耗盡(DiskPressure/MemoryPressure)、網絡與控制平面斷開。
排查思路:
- 查看節點狀態詳情(Conditions);
- 檢查 kubelet 服務是否運行;
- 驗證節點與 API Server 通信是否正常。
關鍵命令:
# 1. 查看節點狀態
kubectl get nodes
kubectl describe node <node-name> # 查看 Conditions(如 MemoryPressure、DiskPressure)
# 2. 檢查 kubelet 服務狀態(節點上執行)
systemctl status kubelet # 查看是否 Active: running
journalctl -u kubelet -f # 實時查看 kubelet 日誌(核心!)
journalctl -u kubelet | grep -i "error" # 過濾錯誤
# 3. 在節點上測試訪問 API Server(確保節點與控制平面通信正常)
curl -k https://<api-server-ip>:6443/version # 需證書或跳過 TLS
2. 節點資源不足(DiskPressure/MemoryPressure)
現象:節點狀態顯示 DiskPressure或 MemoryPressure,Pod 被驅逐。
排查思路:
- 清理節點磁盤空間(如刪除無用鏡像、日誌);
- 擴容節點資源或遷移 Pod 到其他節點。
關鍵命令:
# 1. 查看節點資源壓力詳情
kubectl describe node <node-name> | grep -A 10 "Conditions:"
# 2. 清理節點 Docker 鏡像(節點上執行,若用 Docker)
docker system prune -af # 清理無用鏡像、容器、卷
# 3. 驅逐 Pod(手動遷移,謹慎操作)
kubectl drain <node-name> --ignore-daemonsets # 驅逐節點上所有 Pod(除 DaemonSet)
五、配置錯誤環境
現象:YAML 語法錯誤、資源定義衝突、環境變量/命令配置錯誤。
1. YAML 語法錯誤(kubectl apply失敗)
可能原因:縮進錯誤、字段拼寫錯誤、非法字符。
排查思路:
- 使用
dry-run校驗 YAML; - 對比官方文檔或已有正確 YAML。
關鍵命令:
# 校驗 YAML 語法(不提交到集羣)
kubectl apply -f <yaml-file> --dry-run=client
# 示例錯誤:"error: error validating \"nginx.yaml\": error validating data: [ValidationError(Deployment.spec.template.spec.containers[0]): missing required field \"image\" in io.k8s.api.core.v1.Container]"
2. 環境變量/命令配置錯誤(Pod 啓動失敗)
可能原因:環境變量未注入、容器啓動命令(command)錯誤、args 參數不匹配。
排查思路:
- 查看 Pod 描述中的環境變量和命令配置;
- 進入容器手動執行命令驗證。
關鍵命令:
# 1. 查看 Pod 環境變量
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].env}'
# 2. 查看容器啓動命令(command/args)
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].command}'
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].args}'
# 3. 進入容器手動執行命令
kubectl exec -it <pod-name> -- <command> # 如 /app/start.sh
六、通用排錯流程總結
- 確認問題現象:明確故障表現(Pod 異常/網絡不通/存儲失敗等)。
- 定位受影響資源:通過
kubectl get列出相關資源(Pod/Service/Node 等)。 - 查看資源狀態和事件:
kubectl describe和kubectl logs是核心,關注 Events 和日誌中的error/warning。 - 檢查關聯資源:如 Service → Endpoint、Pod → PVC、Node → kubelet。
- 驗證配置和環境:YAML 語法、網絡連通性、存儲權限、資源充足性。
- 逐步排除:從應用層(日誌)→ 組件層(kubelet/CoreDNS)→ 基礎設施層(節點/網絡/存儲)。
通過以上分類和命令,可快速定位 K8s 集羣中 90% 以上的常見故障,關鍵是結合“事件+日誌+配置”三要素進行排查。