Kubernetes Tips:生产排障通用 Playbook(少猜,多证据)
用可复用的流程诊断 Pending、CrashLoopBackOff、流量不通、DNS/网络、节点/存储问题,把排障从“拍脑袋”变成“可验证”。
当 Kubernetes “出问题”时,最快的团队不是靠灵感,而是靠 可重复的排障流程:先分类、再收集证据、形成假设、验证假设,最后才动手改配置/回滚。
这篇 tips 提供一个可在事故中直接使用的 playbook。
先分类:你现在属于哪种故障形态
生产问题多数落在这些桶里:
- 调度/Pending:Pod 放不下去
- 启动/CrashLoopBackOff:容器反复起不来
- 就绪/不接流量:Pod 在跑,但 Service 没把流量打进去
- 网络:DNS、egress、ingress、NetworkPolicy
- 节点/平台:磁盘压力、CNI/CSI、kubelet/runtime
先判断桶,再选工具和路径,否则会做很多无效动作。
总览流程(Mermaid)
flowchart TD A[观察到症状] --> B{Pod Pending?} B -- 是 --> C[看事件与调度约束] B -- 否 --> D{CrashLoopBackOff?} D -- 是 --> E[看日志/退出码/资源/配置] D -- 否 --> F{Ready?} F -- 否 --> G[探针/依赖/Endpoints] F -- 是 --> H{流量仍失败?} H -- 是 --> I[Ingress/Service/DNS/NetworkPolicy] H -- 否 --> J[节点/平台诊断]先跑的 5 个命令(先看大图)
kubectl get pod -n <ns> -o wide
kubectl describe pod -n <ns> <pod>
kubectl get events -n <ns> --sort-by=.lastTimestamp
kubectl logs -n <ns> <pod> -c <container> --previous
kubectl top pod -n <ns> --containers
这 5 个命令能快速回答:
- 卡在哪个阶段(调度/拉镜像/启动/探针)
- 失败原因(事件里通常写得很直白)
- 是否资源/容量相关(top + describe node)
1)Pod Pending(调度失败)
Pending 通常意味着:没有任何节点满足约束。
常见原因
- requests 过大:
Insufficient cpu/memory - nodeSelector/affinity 太严格
- 节点 taints 没有 tolerations
- topology spread constraints 无法满足
- 命名空间配额/限制触发(ResourceQuota/LimitRange)
怎么看证据
kubectl get events -n <ns> --sort-by=.lastTimestamp | rg -n "FailedScheduling|Insufficient|taint|affinity|quota"
然后看节点资源与 taints:
kubectl describe node <node> | rg -n "Allocatable|Allocated resources|Taints"
修复思路(按顺序)
- 先确认 requests 是否贴近真实需求(别盲目降到 0)
- 检查是否存在不必要的约束(亲和性、节点选择器)
- 若容量不足,扩节点池或优化服务资源画像
2)CrashLoopBackOff(反复崩溃)
CrashLoopBackOff 表示容器不断退出并被重启,Kubernetes 进入退避。
必看:previous logs
kubectl logs -n <ns> <pod> -c <container> --previous
常见根因
- 环境变量/配置错(缺 Secret、路径错)
- command/args 错
- 镜像版本错/架构不匹配
- 依赖连接失败(DB/TLS)
- 内存不够导致 OOMKilled
相关桶:ErrImagePull / ImagePullBackOff
如果压根拉不下镜像,会看到 ErrImagePull/ImagePullBackOff。排查点:
- 镜像名/tag 拼写
- imagePullSecrets 是否正确
- 节点到镜像仓库的网络/DNS
- amd64/arm64 架构不匹配
InitContainers:卡在“应用还没启动”
有 initContainers 的 Pod,主容器不会启动直到 init 成功。检查 init 日志:
kubectl logs -n <ns> <pod> -c <init-container>
init 常见失败点:
- 迁移脚本超时
- init 访问外部依赖被 NetworkPolicy 拦
- 权限不足导致写目录失败
3)Pod 在跑但不接流量(Readiness/Endpoints)
这种问题最容易被误判成“网不通”,实际上是 readiness 没通过或 Service selector 不匹配。
看 readiness 与 probe 失败
kubectl describe pod -n <ns> <pod> | rg -n "Readiness probe failed|Liveness probe failed"
kubectl get pod -n <ns> <pod> -o jsonpath='{.status.containerStatuses[*].ready}{"\n"}'
看 Service endpoints 是否为空
kubectl get svc -n <ns>
kubectl get endpoints -n <ns> <svc> -o wide
如果 endpoints 为空:
- selector 不匹配(labels 对不上)
- Pod 没 Ready(探针失败)
从 Pod 网络命名空间里验证
如果镜像里没有 curl,建议用 ephemeral container:
kubectl debug -n <ns> -it pod/<pod> --image=curlimages/curl:8.5.0
curl -sS -i http://<svc>.<ns>.svc.cluster.local:8080/readyz
4)网络问题(DNS / Egress / Ingress / NetworkPolicy)
DNS 排查
在 Pod 内:
nslookup kubernetes.default.svc.cluster.localnslookup <svc>.<ns>.svc.cluster.localcat /etc/resolv.conf
DNS 常见根因:
- CoreDNS 异常
- egress policy 未放行 DNS
- 节点网络/CNI 抖动
Egress 不通
先确认:
- NetworkPolicy egress 是否放行
- NAT/防火墙/路由是否允许
- TLS/SNI 是否正确
Ingress 不通
从入口到后端逐层确认:
- Ingress/Gateway/controller 状态与日志
- Service type、端口、selector
- endpoints 是否存在、Pod 是否 Ready
5)节点/平台问题(Disk/CNI/CSI/kubelet)
DiskPressure
kubectl describe node <node> | rg -n "DiskPressure|ImageFS|Eviction"
磁盘压力会导致:
- Pod 被驱逐
- 拉镜像失败
- kubelet 异常
CNI 问题(网络层)
典型表现:
- Pod 到 Service 不通
- DNS 间歇性失败
- Pod 卡在 ContainerCreating
建议检查 kube-system 中 CNI DaemonSet 状态与节点事件。
CSI/存储问题
kubectl describe pod -n <ns> <pod> | rg -n "MountVolume|AttachVolume|failed"
kubectl get pvc -n <ns>
kubectl describe pvc -n <ns> <pvc>
事故中“别让它更糟”的原则
- 先保存证据(events/logs),再改配置
- 如果变更刚上线且高度相关,优先回滚
- 不要随便删除 Pod/节点,除非知道为什么删
- 临时扩容要建立在“确实资源不足”的证据上
事故后把根因变成护栏
排障的终点不是“修好了”,而是“下次不再这样”:
- 缺 requests/limits => policy/模板强制
- OOM 反复 => 内存画像 + runtime 参数对齐 + VPA 推荐
- 探针误用 => 标准化探针与优雅下线
- NetworkPolicy 翻车 => 平台基线 allow-list + 渐进上线
Checklist(可打印)
- 先分类(Pending/CrashLoop/NotReady/Network/Node)
- 先跑 5 个命令(get/describe/events/logs/top)
- 流量问题先看 endpoints 与 selector
- 网络问题用 Pod 内验证(debug container)
- 优先回滚而不是随机改参数
- 复盘后把根因做成护栏
参考链接
FAQ
Q: 排障第一步看什么?
A: kubectl describe 和 events 往往能直接定位问题。
Q: 如何区分应用问题还是集群问题? A: 对比其它命名空间、检查节点压力,并验证依赖服务。
Q: 什么时候用临时容器? A: 镜像缺少工具、需要进入 Pod 内部排查时。