来源:不爱笑的青年 | 发布日期:2026-07-15
K8s 故障排查快速参考 — 从现象到根因
不靠重启玄学,靠分层定位。铁律:先看后动,不要上来就 delete pod 或 restart 容器运行时——这会清空最关键的排查现场。
黄金五步思维模型
| 步骤 |
动作 |
核心问题 |
| ① 定界 |
问题在哪一环 |
应用挂了?网络不通?节点宕了? |
| ② 看状态 |
资源处于什么状态 |
Pod/CrashLoopBackOff/NodeNotReady? |
| ③ 看事件 |
发生了什么 |
kubectl describe 的 Events 是排查第一入口 |
| ④ 看日志 |
应用说了什么 |
容器日志、系统组件日志有没有报错 |
| ⑤ 看指标 |
资源够不够 |
CPU/内存/磁盘/网络是否打满 |
90% 的 K8s 故障,kubectl describe + kubectl logs 就能定位。
Pod 常见故障定位
Pending(调度不出去)
| 可能原因 |
判断依据 |
解决 |
| 资源不足 |
describe Events 显示 "Insufficient cpu/memory" |
降低 requests 或扩节点 |
| 节点污点 |
Events 显示 "node(s) had taint" |
Pod 加 tolerations 或节点去污点 |
| PVC 未绑定 |
Events 显示 "persistentvolumeclaim not found" |
排查存储 |
第一步: kubectl describe pod <pod> -n <ns> — 重点看 Events 段落。
ImagePullBackOff / ErrImagePull
| 原因 |
现象 |
解决 |
| 镜像名/Tag 写错 |
manifest unknown |
核对 image 字段 |
| 缺 imagePullSecret |
unauthorized |
创建 Secret 并配给 Pod |
| 节点网络不通仓库 |
timeout / i/o timeout |
检查节点到仓库网络 |
CrashLoopBackOff
定位顺序:
- 看日志:
kubectl logs <pod> --previous(上一个崩溃容器的日志)
- 看退出码:
kubectl describe pod 里 Last State: Terminated, Exit Code
OOMKilled 与 Exit Code
| 退出码 |
含义 |
行动 |
| 137 |
SIGKILL,通常 OOM |
调大 limits.memory 或排查内存泄漏 |
| 143 |
SIGTERM,正常终止信号 |
滚动更新/驱逐,非故障 |
| 1 |
应用主动退出(报错) |
看应用日志定位异常 |
Node NotReady
| 可能原因 |
排查命令 |
对策 |
| kubelet 挂了 |
systemctl status kubelet |
journalctl -u kubelet 看报错 |
| 磁盘满(/var/lib) |
df -h |
清理容器日志/镜像 |
| 容器运行时故障 |
systemctl status containerd |
看 containerd 日志 |
| 网络断连 |
ping 控制平面IP |
检查节点网络/安全组 |
⚠️ 真实踩坑: 磁盘满是最常见的 NotReady 原因。告警链:磁盘 >85% → kubelet 驱逐 Pod → 100% → NotReady。磁盘监控必须配上。
Service 不通 / Ingress 502
Service 访问不通定位链路
| 层级 |
检查点 |
命令 |
| ① 端点 |
Endpoints 是否为空(Selector 对不对) |
kubectl get endpoints <svc> |
| ② 端口 |
port/targetPort 是否对应 Pod 真实端口 |
kubectl describe svc <svc> |
| ③ DNS |
能解析服务名吗 |
nslookup <svc>.<ns>.svc.cluster.local |
| ④ 策略 |
NetworkPolicy 是否拦了 |
查该 NS 的 NetworkPolicy |
Endpoints 为空的经典原因: Service 的 Selector 和 Pod 的 Label 对不上。用 kubectl get pods --show-labels 核对。
Ingress 502/504
| 现象 |
可能原因 |
定位 |
| 502 Bad Gateway |
后端 Pod 全挂/Endpoints 空 |
先查 Service Endpoints |
| 504 Gateway Timeout |
后端响应超时 |
查后端 Pod 日志与耗时 |
| 连接被拒 |
Ingress 规则 host/path 配错 |
kubectl describe ingress |
PVC Pending
| 现象 |
原因 |
排查 |
| PVC 一直 Pending |
无默认 StorageClass 或 Provisioner 未运行 |
kubectl get sc;查 provisioner Pod |
| 挂载失败/超时 |
后端存储网络不通 |
节点上 telnet NFS_IP 2049 |
| Pod 报 "Volume not found" |
静态 PV 的 spec 不匹配 |
kubectl describe pvc 看 Event |
kubectl describe pvc 的 Events 会直接告诉你为什么绑不上——这一步能解决 80% 的存储故障。
CPU Throttling 与 OOM
| 现象 |
判断 |
对策 |
| 接口延迟高但 CPU 没打满 |
container_cpu_cfs_throttled_periods_total 持续增长 |
调大 limits.cpu 或去掉 limit |
| QoS 为 Burstable 被压 |
同节点 BestEffort Pod 抢资源 |
提高 requests 保证调度水位 |
OOM 建议: limits.memory ≥ 峰值用量 × 1.2,并用监控观察实际 RSS。
⚠️ 经典误区: requests=limits 设成一样,Pod 变成 Guaranteed 等级,一点点超发就被 OOM 或 Throttling。普通无状态服务建议 limits 略大于 requests,给一点弹性空间。
黄金排查命令速查表
# ① 看Pod状态与原因
kubectl get pods -n <ns> -o wide
kubectl describe pod <pod> -n <ns> # 重点看Events
# ② 看日志(上一个崩溃容器加 --previous)
kubectl logs <pod> -n <ns>
kubectl logs <pod> --previous -n <ns>
# ③ 进容器调试
kubectl exec -it <pod> -n <ns> -- sh
# ④ 看Service与Endpoint
kubectl get svc,endpoints -n <ns>
kubectl describe svc <svc> -n <ns>
# ⑤ 看节点
kubectl get nodes
kubectl describe node <node>
kubectl get events -n <ns> --sort-by=.lastTimestamp
# ⑥ 看资源使用(需metrics-server)
kubectl top pods -n <ns>
kubectl top nodes
# ⑦ 看系统组件日志(Master节点上)
journalctl -u kubelet -n 100
journalctl -u containerd -n 100
# ⑧ 网络连通性测试
kubectl run test --rm -it --image=busybox -- nslookup <svc>.<ns>.svc.cluster.local
故障决策树
| 现象 |
第一步该敲什么 |
大概率方向 |
| Pod 一直 Pending |
kubectl describe pod 看 Events |
资源/污点/PVC |
| Pod CrashLoopBackOff |
kubectl logs --previous |
应用报错/OOM |
| Node NotReady |
节点上 systemctl status kubelet;df -h |
kubelet/磁盘满/网络 |
| Service 访问不通 |
kubectl get endpoints <svc> |
Selector/端口/DNS |
| Ingress 502/504 |
先查后端 Service Endpoints |
后端 Pod/超时 |
| PVC 一直 Pending |
kubectl describe pvc 看 Events |
SC/Provisioner/网络 |
| 业务变慢但没崩 |
kubectl top pods + 监控 |
Throttling/OOM/邻居抢资源 |
关联页面