Kubernetes 故障排查与最佳实践
集群出问题时,慌是没用的,按「状态 → 事件 → 日志」的路径排查效率最高。本章汇总最常见的故障现象与排查命令组合,并给出长期运维该遵守的最佳实践清单,作为日常排障与加固的速查手册。
排障通用路径
看到 Pod 状态异常,先用 get 看现象,再 describe 看事件、logs 看日志:
kubectl get pods -o wide # 状态:Pending/Running/CrashLoopBackOff...
kubectl describe pod myapp-xxxx # 事件里写明原因(拉镜像失败、探针失败等)
kubectl logs myapp-xxxx # 看应用自身日志
kubectl logs myapp-xxxx --previous # 容器重启过则看上一次的日志
kubectl get events --sort-by=.lastTimestamp | tail -20 # 集群事件
常见故障与排查命令组合
| 现象 | 常见原因 | 排查要点 |
|---|---|---|
| Pod 一直 Pending | 资源不足、无匹配节点、PVC 未绑定 | describe 看 FailedScheduling 事件,检查 requests、污点、存储 |
| ImagePullBackOff | 镜像名写错、私有仓库未认证 | describe 看拉取错误,检查 imagePullSecrets,本地先 docker pull 验证 |
| CrashLoopBackOff | 应用启动即崩溃、探针误配 | logs --previous 看崩溃原因,describe 看探针事件 |
| OOMKilled | 内存超过 limits | 调大内存限制或优化应用内存占用 |
| 节点 NotReady | kubelet 异常、磁盘满、网络故障 | 登录节点查 kubelet 状态与日志 |
| Service 不通 | selector 不匹配、端口不对 | kubectl get endpoints 确认有无后端,检查 targetPort |
节点 NotReady 排查示例:
ssh node01
systemctl status kubelet # kubelet 是否存活
journalctl -u kubelet -n 50 # 查看 kubelet 最近日志
df -h # 磁盘是否写满
最佳实践清单
- 资源限制:所有容器都写 requests/limits,防止单个应用拖垮节点,也是 HPA 生效的前提。
- 探针齐全:核心服务配置 liveness + readiness,慢启动应用加 startupProbe,实现自愈与无损发布。
- 镜像 tag 策略:生产用不可变 tag(如 git commit),禁止用 latest,便于定位与回滚。
- 多副本与反亲和:关键服务至少 2 副本,并用 podAntiAffinity 分散到不同节点,避免单点。
- 优雅停机:应用处理 SIGTERM 完成收尾,必要时用 preStop 钩子延迟退出:
spec:
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"] # 等存量请求处理完
- 数据安全:etcd 定期备份并演练恢复,它是集群状态的唯一真源;Secret 较多时开启 etcd 加密。
- 升级顺序:先备后升——升级前备份 etcd,按「基础组件 → 控制面 → 节点 → 业务」分批灰度推进,升级后观察核心 workload。
- 日常纪律:变更先 apply --dry-run=client 校验,删除前确认无引用,生产谨慎使用 force 与 delete namespace。
小结:排查记住「状态 → 事件 → 日志」三板斧,Pending/ImagePullBackOff/CrashLoopBackOff 各有固定入口;把资源限制、探针、不可变 tag、反亲和、优雅停机、etcd 备份这些基本功做扎实,故障自然远离。