15.2. 排错手册
排错不是「猜一个原因然后重启」。先确定故障边界,再收集证据,最后验证假设。这份手册给你一套可以重复执行的流程,以及一张按现象索引的故障表。
- 层级:
L5 · 参考
- 难度:
进阶
- 用途:
故障处理
- 前置:
核心对象、网络、存储
15.2.1. 五步排错法
图:不要跳过「确定边界」。同一个 502,可能是 Pod、Service、Ingress、CNI 或外部 LB 的问题。
定义现象:谁访问谁、什么时间、错误码/超时、影响范围。
确定边界:单个 Pod?单个节点?单个 namespace?全部服务?
收集证据:
get、describe、logs、events、top、节点日志。提出假设:一次只验证一个,写出「如果假设成立,应该看到什么」。
验证并修复:修复后做回归,确认没有引入新问题。
警告
先取证,再重启
kubectl delete pod 会清掉容器日志与上一次退出状态。先执行 kubectl logs --previous、describe、保存事件,再考虑重启。
15.2.2. 第一分钟做什么
# 1. 集群是否健康
kubectl get --raw='/readyz?verbose'
# 2. 节点是否 Ready
kubectl get nodes -o wide
# 3. 异常 Pod
kubectl get pods -A --field-selector=status.phase!=Running
# 4. 最近事件
kubectl get events -A --sort-by=.lastTimestamp | tail -30
# 5. 控制平面
kubectl get pods -n kube-system -o wide
如果 API 都连不上,先跳到「控制平面」一节,不要在应用层浪费时间。
15.2.3. 按 Pod 状态索引
15.2.3.1. Pending
Pod 没有被调度到节点。
kubectl describe pod <pod> -n <ns> | sed -n '/Events/,$p'
事件关键词 |
原因 |
处理 |
|---|---|---|
|
节点资源不足 |
降 requests、扩容节点、清理僵尸 Pod |
|
污点未容忍 |
加 toleration,或调度到其他节点 |
|
亲和性不满足 |
检查 |
|
PVC 不存在 |
创建 PVC 或修正名字 |
|
PVC 未绑定 |
|
|
资源配额 |
调整 ResourceQuota |
|
没有可调度节点 |
检查节点状态与 cordon |
15.2.3.2. ImagePullBackOff / ErrImagePull
kubectl describe pod <pod> -n <ns> | grep -A5 -i 'failed'
原因 |
验证 |
处理 |
|---|---|---|
镜像名 / tag 错 |
|
修正镜像 |
私有仓库无凭据 |
|
创建 docker-registry Secret |
仓库不可达 |
节点上 |
配 mirror / 代理 |
架构不匹配 |
|
用多架构镜像 |
限流 |
事件中有 |
配镜像加速或重试 |
15.2.3.3. CrashLoopBackOff
容器启动后反复退出。
kubectl logs <pod> -n <ns> --previous
kubectl describe pod <pod> -n <ns> | grep -E 'Exit Code|Reason|Last State'
退出码 |
含义 |
常见原因 |
|---|---|---|
0 |
正常退出 |
前台进程结束,容器没有常驻进程 |
1 |
应用错误 |
配置错、依赖不可用、启动异常 |
127 |
命令不存在 |
|
137 |
被 SIGKILL / OOM |
内存超限、liveness 重启 |
143 |
SIGTERM |
优雅终止、被删除 |
15.2.3.4. Running 但 0/1
readiness 探针失败,Pod 不接收流量。
kubectl describe pod <pod> -n <ns> | grep -A10 -i readiness
kubectl exec <pod> -n <ns> -- wget -qO- http://localhost:<port>/<path>
kubectl get endpoints <svc> -n <ns>
常见原因:探针路径/端口错、应用启动慢但 initialDelaySeconds 太短、依赖未就绪、host 头不匹配。
15.2.3.5. Terminating 卡住
kubectl get pod <pod> -n <ns> -o yaml | grep -A3 finalizers
kubectl describe pod <pod> -n <ns>
finalizer 未清理:找到对应控制器;
优雅终止超时:
terminationGracePeriodSeconds;节点失联:
kubectl delete pod --force --grace-period=0(确认容器已停)。
15.2.4. 按故障域索引
15.2.4.1. Service 访问不通
kubectl get svc <svc> -n <ns> -o yaml
kubectl get endpoints <svc> -n <ns>
kubectl get endpointslice -n <ns> -l kubernetes.io/service-name=<svc>
kubectl get pods -n <ns> --show-labels
检查点 |
正常 |
异常处理 |
|---|---|---|
selector |
与 Pod 标签一致 |
修正 selector |
Endpoints |
有 Pod IP |
检查 readiness、namespace |
targetPort |
与容器端口一致 |
修正端口名/号 |
NetworkPolicy |
允许来源 |
加放行规则 |
DNS |
|
查 CoreDNS |
kube-proxy |
Pod Running |
查规则 / 日志 |
15.2.4.2. DNS 解析失败
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50
kubectl run dns --image=busybox:1.36 --rm -it --restart=Never -- \
nslookup kubernetes.default
CoreDNS Pod 是否 Ready;
是否被 NetworkPolicy 阻断 53 端口;
/etc/resolv.conf的nameserver是否是 Service CIDR 内的地址;跨 namespace 是否用了短名。
15.2.4.3. Ingress 502 / 404
kubectl get ingress -n <ns> -o yaml
kubectl get svc -n ingress-nginx
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller --tail=100
kubectl get endpoints <backend-svc> -n <ns>
404:host / path 不匹配,或 IngressClass 不对;
502:后端未 Ready、端口错、协议错(HTTPS 后端需注解);
504:后端超时,检查
proxy-read-timeout与应用性能。
15.2.4.4. PVC Pending
kubectl describe pvc <pvc> -n <ns>
kubectl get storageclass
kubectl get pv
kubectl get pods -n kube-system | grep -E 'csi|provisioner'
原因 |
处理 |
|---|---|
没有默认 StorageClass |
指定 |
|
先创建使用它的 Pod |
容量不足 / 访问模式不匹配 |
调整请求或 PV |
provisioner Pod 异常 |
查 CSI 日志 |
拓扑限制 |
用 |
15.2.4.5. 节点 NotReady
kubectl describe node <node>
ssh <node> 'systemctl status kubelet; journalctl -u kubelet -n 100 --no-pager'
ssh <node> 'df -h; free -h; systemctl status containerd'
原因 |
现象 |
处理 |
|---|---|---|
kubelet 挂了 |
|
重启 kubelet,查配置 |
磁盘压力 |
|
清理镜像/日志 |
内存压力 |
|
驱逐低优先级 Pod |
网络插件异常 |
CNI Pod 未就绪 |
重启 CNI |
证书过期 |
kubelet 报 x509 |
轮换证书 |
时间不同步 |
TLS 错误 |
修 NTP |
15.2.4.6. 控制平面异常
kubectl get pods -n kube-system
kubectl get --raw='/readyz?verbose'
sudo crictl ps | grep -E 'kube-apiserver|etcd|kube-controller|kube-scheduler'
sudo journalctl -u kubelet -n 200 --no-pager
API Server 起不来:看静态 Pod 清单
/etc/kubernetes/manifests/与容器日志;etcd 异常:检查磁盘、证书、
/var/lib/etcd空间;证书过期:
kubeadm certs check-expiration;全部静态 Pod 异常:检查 kubelet 与容器运行时。
15.2.4.7. 资源与性能
kubectl top nodes
kubectl top pods -A --sort-by=cpu
kubectl describe node <node> | sed -n '/Allocated resources/,/Events/p'
kubectl get pod <pod> -o jsonpath='{.status.qosClass}'
CPU 高但未限流:看应用本身;
CPU 被 throttle:提高 limits 或优化;
内存持续增长:查泄漏,设置合理 limit;
节点磁盘满:清理未使用镜像
crictl rmi --prune。
15.2.5. 常用证据命令
kubectl get events -n <ns> --sort-by=.lastTimestamp
kubectl describe pod <pod> -n <ns>
kubectl logs <pod> -n <ns> --all-containers --tail=200
kubectl logs <pod> -n <ns> --previous
kubectl get pod <pod> -n <ns> -o yaml
kubectl get endpoints,endpointslice -n <ns>
kubectl get pvc -n <ns>
kubectl get --raw='/readyz?verbose'
15.2.6. 不要做的事
不要一上来就删 Pod / 重启节点;
不要同时改多个变量;
不要在没看 Events 的情况下猜镜像问题;
不要把
latest镜像用于生产;不要用
--force删除有状态 Pod 而不确认数据;不要把「Pod Running」当成「服务可用」。