K8s 单个 Pod 拖垮整个集群的雪崩效应排查与防御
2026-08-11 00:53:03 # Kubernetes

问题背景

凌晨告警炸锅:集群节点逐一变成 NotReady,所有 Pod Pending,机器 CPU 飙满、IO 打满、频繁 OOM。事后定位,元凶是一个未设置 resource limits 的 Prometheus 监控 Pod——随着采集数据量增长,它吃光了所在节点的全部 CPU 和内存,kubelet 等系统进程被 OOM Kill,节点失联;节点失联又触发其上 Pod 重建,重建进一步压垮其他节点,故障像多米诺骨牌一样蔓延。

排查思路

先找”资源异常”的节点:

1
2
kubectl get nodes
kubectl top nodes

锁定问题节点后,登录查看哪个容器在吞噬资源:

1
2
3
4
5
# 按内存 / CPU 排序找元凶
kubectl top pods -A --sort-by=memory | head
kubectl top pods -A --sort-by=cpu | head
# 或直接在节点用 cgroup 工具
sudo systemd-cgtop

确认元凶 Pod 是否缺 limits:

1
2
kubectl get pod <元凶> -n <ns> -o jsonpath='{.spec.containers[*].resources}'
# 输出为空或没有 limits 字段,即“无限制”

解决过程

紧急止血

1
2
3
4
5
# 1. 先封锁问题节点,停止继续调度
kubectl cordon <问题节点>
# 2. 把高消耗负载挪走
kubectl drain <问题节点> --ignore-daemonsets --delete-emptydir-data
# 3. 紧急扩容更高规格节点承接负载

长效防御——强制所有 Pod 设 limits

LimitRange 给命名空间设默认上限,ResourceQuota 限总量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: LimitRange
metadata:
name: mem-cpu-limit-range
namespace: default
spec:
limits:
- default:
cpu: "1"
memory: 1Gi
defaultRequest:
cpu: "0.5"
memory: 512Mi
type: Container
1
kubectl apply -f limitrange.yaml

经验总结

  • 不给 Pod 设 limits 是 K8s 运维的头号大忌,尤其监控、批处理这类”会随时间增长”的负载。
  • 核心组件(kube-system 下)更要限,否则一个组件失控会连带干掉控制面。
  • LimitRange + ResourceQuota 是”强制纪律”的兜底手段,建议全集群默认开启。
  • 雪崩发生时,先 cordon/drain 止血、再扩容、最后查根因,顺序不能反。