Kubernetes 故障排查最怕“看到异常就重启”。盲目重启可能暂时掩盖问题,也可能清掉现场证据。更有效的方法是先确定影响范围,再沿着对象关系逐层缩小问题。
一、先回答五个问题
1. 影响一个 Pod、一个应用、一个命名空间,还是整个集群?
2. 问题从什么时候开始?
3. 最近发生过哪些发布、配置、证书、网络或节点变更?
4. 是无法创建、无法启动、无法就绪,还是无法访问?
5. 问题能否稳定复现?
先记录时间线、错误信息和相关对象,避免处理过程中丢失证据。
二、确认上下文与集群入口
kubectl config current-context
kubectl config get-contexts
kubectl version
kubectl cluster-info
如果 kubectl 无法连接,先区分:
1. DNS 解析失败。
2. TCP 连接超时或被拒绝。
3. TLS 证书错误。
4. Unauthorized 或 Forbidden。
5. API Server 返回 5xx。
依次检查本地网络、VPN、代理、kubeconfig server 地址、证书有效期、API Server 前的负载均衡和防火墙。
三、先看全局状态和事件
kubectl get nodes
kubectl get pods -A -o wide
kubectl get events -A \
--sort-by=.metadata.creationTimestamp
事件能快速暴露调度失败、镜像拉取、卷挂载、探针、驱逐和配额问题,但事件有保留时间,出现故障后应尽早收集。
四、Pod Pending
Pending 通常表示 Pod 尚未成功调度或仍在准备资源。
kubectl describe pod <POD_NAME> -n <NAMESPACE>
重点查看 Events:
1. Insufficient cpu/memory:节点资源不足或 requests 过高。
2. taint/toleration 不匹配。
3. nodeSelector、亲和性或拓扑约束无法满足。
4. PVC 未绑定。
5. ResourceQuota 或 LimitRange 拒绝。
6. 调度器或 Webhook 异常。
不要因为 Pending 就直接重启 kubelet。先阅读调度事件给出的具体原因。
五、ImagePullBackOff
检查:
kubectl describe pod <POD_NAME> -n <NAMESPACE>
常见原因包括镜像名称或标签错误、仓库不可达、DNS/代理问题、凭据无效、镜像不存在、架构不兼容和限流。
确认 imagePullSecrets、ServiceAccount 和节点到镜像仓库的网络。不要为了快速恢复而替换为来历不明的镜像源。
六、CrashLoopBackOff
先查看当前与上一次容器日志:
kubectl logs <POD_NAME> -n <NAMESPACE> \
-c <CONTAINER_NAME>
kubectl logs <POD_NAME> -n <NAMESPACE> \
-c <CONTAINER_NAME> --previous
再检查退出码、启动命令、环境变量、ConfigMap、Secret、文件权限和依赖服务。
如果 reason 为 OOMKilled,应检查实际内存、limit、应用泄漏和节点压力,而不是只无限提高 limit。
如果应用启动较慢,livenessProbe 可能过早杀死容器,应考虑 startupProbe;不要简单删除所有探针。
七、Running 但不 Ready
Running 只代表容器进程存在,不代表应用能接收流量。
kubectl get pod <POD_NAME> -o yaml
kubectl describe pod <POD_NAME>
检查 readinessProbe、ReadinessGates、依赖服务、证书、线程池和连接池。Pod 不 Ready 时,通常不会进入 Service 的可用 EndpointSlice。
八、Service 无法访问
按完整链路检查:
客户端 → DNS → Service → EndpointSlice → Pod IP:targetPort → 应用进程
命令:
kubectl get service <SERVICE_NAME> -o yaml
kubectl get endpointslice \
-l kubernetes.io/service-name=<SERVICE_NAME> -o wide
kubectl get pod -l <LABEL_SELECTOR> -o wide
从集群内测试 DNS 和 Service,再直接测试 Pod IP 与端口。如果 Pod 可访问但 Service 不可访问,重点检查 selector、port/targetPort、EndpointSlice 和服务数据面。
如果两者都失败,检查应用监听地址。应用只监听 127.0.0.1 时,其他 Pod 无法访问。
还要检查 NetworkPolicy、Service Mesh、节点防火墙和 CNI。
九、Ingress 或 Gateway 无法访问
检查顺序:
1. DNS 是否指向正确入口。
2. 外部负载均衡地址和健康检查。
3. IngressClass/GatewayClass 是否匹配控制器。
4. TLS Secret 和域名是否正确。
5. 路由规则是否指向正确 Service 端口。
6. Service 是否有健康 EndpointSlice。
7. 控制器日志是否报错。
可以临时指定 Host 头,把 DNS 与路由问题分离:
curl -H 'Host: app.example.com' \
http://<INGRESS_ADDRESS>/
十、Node NotReady
kubectl describe node <NODE_NAME>
kubectl get pod -A \
--field-selector spec.nodeName=<NODE_NAME>
关注 Node Conditions:Ready、MemoryPressure、DiskPressure、PIDPressure 和 NetworkUnavailable。
如果还能登录节点,检查:
systemctl status kubelet
journalctl -u kubelet --since '30 min ago'
crictl ps -a
crictl info
同时检查磁盘、inode、内存、时间同步、证书、容器运行时、CNI、路由和节点到 API Server 的连接。
kubectl debug node/<NODE_NAME> 可以在部分场景创建节点调试 Pod,但它依赖 kubelet和调度链路仍可工作,并且需要较高权限。节点完全离线时不能依靠它。
十一、控制面异常
检查 API Server 就绪端点:
kubectl get --raw='/readyz?verbose'
kubeadm 静态控制面还应在控制平面节点检查:
1. /etc/kubernetes/manifests 是否完整。
2. kubelet 是否正常。
3. 容器运行时中的静态 Pod 容器。
4. etcd 健康、磁盘空间和证书。
5. API Server、Scheduler、Controller Manager 日志。
不要使用已弃用的 ComponentStatus 作为唯一健康依据。
十二、DNS 故障
从测试 Pod 查询:
nslookup kubernetes.default.svc.cluster.local
检查:
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get service -n kube-system
kubectl logs -n kube-system -l k8s-app=kube-dns
DNS 异常可能来自 CoreDNS 配置、上游 DNS、NetworkPolicy、节点 resolv.conf、CNI 或 Service 数据面。
十三、存储故障
kubectl get pvc,pv
kubectl describe pvc <PVC_NAME>
kubectl describe pod <POD_NAME>
kubectl get storageclass
关注 PVC Pending、FailedMount、FailedAttachVolume、Multi-Attach、拓扑限制和 CSI 日志。不要在不了解回收策略时删除 PVC 或 PV;删除对象可能同时删除后端卷。
十四、建立标准证据包
每次故障至少保存:
1. 时间范围和影响面。
2. 相关 YAML 与 describe 输出。
3. 事件、当前日志和 previous 日志。
4. 节点状态和资源使用。
5. 最近变更记录。
6. 网络、存储和控制器依赖状态。
7. 已尝试操作及结果。
敏感字段、Token、Secret、证书和内部地址在对外分享前必须脱敏。
十五、处理原则
1. 先只读检查,再执行变更。
2. 一次只改变一个变量。
3. 任何重启、驱逐、回滚和删除都要有影响评估。
4. 生产操作前准备回滚。
5. 修复后持续观察,不以“Pod 变绿”作为唯一成功标准。
6. 故障结束后补充监控、告警和自动化检查,防止复发。
总结
Kubernetes 排障应沿对象关系逐层推进:上下文与 API → Node → Pod → 容器 → Service/EndpointSlice → Ingress/Gateway → 网络、DNS、存储和外部依赖。先确定范围、保留证据、验证假设,再做最小变更,通常比反复重启更快找到根因。
参考资料:
https://kubernetes.io/docs/tasks/debug/debug-application/
https://kubernetes.io/docs/tasks/debug/debug-application/debug-service/
https://kubernetes.io/docs/tasks/debug/debug-cluster/