K8s 生产 10 大故障复盘
生产环境出问题往往不是因为 K8s 有 bug,而是:配置不当、资源规划不合理、缺乏监控告警、操作流程不规范、对某些机制理解不深。每一个案例都是血泪教训。
故障总览
| # | 故障 | 影响范围 | 严重程度 | 核心教训 |
|---|---|---|---|---|
| 1 | etcd 磁盘写满 | 整个集群 | P0 灾难 | etcd 独立盘 + 配额 + 告警 |
| 2 | API Server OOM | 整个集群 | P0 灾难 | API Server 资源预留 + 限流 |
| 3 | 证书过期 | 整个集群 | P0 灾难 | 证书监控 + 自动续期 |
| 4 | 节点批量 NotReady | 多节点 | P1 严重 | kubelet 资源 + 磁盘压力排查 |
| 5 | PDB 阻断节点驱逐 | 应用级 | P1 严重 | PDB minAvailable 合理性 |
| 6 | 资源配额耗尽 | 命名空间 | P2 中等 | ResourceQuota + 告警 |
| 7 | 滚动更新卡住 | 应用级 | P2 中等 | readinessProbe + maxUnavailable |
| 8 | ConfigMap 热更新踩坑 | 应用级 | P2 中等 | subPath 只读 + 重启策略 |
| 9 | HPA 抖动风暴 | 应用级 | P2 中等 | 冷却窗口 + 指标选择 |
| 10 | 镜像拉取失败雪崩 | 多应用 | P2 中等 | imagePullPolicy + 私有仓库 |
集群级灾难(P0)
案例 1:etcd 磁盘写满
故障链: 周五下午监控突然告警 API Server 超时、节点 Unknown、Pod 无法调度 → 登录发现 etcd 磁盘 100% → etcd 无法写入 Raft 日志 → 整个集群只读。
根因: 大量 CRD 变更产生过多 etcd 事件,未配置自动压缩和碎片整理。
排查命令:
df -h /var/lib/etcd
etcdctl endpoint status --write-out=table
etcdctl compact $(etcdctl endpoint status --write-out=json | jq -r '.[0].Status.header.revision')
etcdctl defrag
止血: 立即 compact + defrag → 扩容磁盘 → 配置自动压缩 --auto-compaction-mode=periodic --auto-compaction-retention=1h。
预防: etcd 独立 SSD 盘、磁盘使用率 >80% 告警、开启定期压缩。
案例 2:API Server OOM
故障链: 集群突然不可用 → kubectl 全部 timeout → 发现 API Server Pod 被 OOMKilled 循环重启。
根因: 某应用频繁 LIST 全量 Pod(每 10 秒),导致 API Server 内存中对象缓存暴涨。
排查:
kubectl get events -A --field-selector reason=OOMKilled
kubectl logs -n kube-system kube-apiserver-master01 --tail=50
# 审计日志定位高频请求来源
grep "list pods" /var/log/kubernetes/audit.log | awk '{print $NF}' | sort | uniq -c | sort -rn
修复: 增加 API Server 内存 limit、配置 APF(API Priority and Fairness)限流、通知应用方降低 LIST 频率。
案例 3:证书过期
故障链: 某天上班发现 kubectl 全部报 x509: certificate has expired → 整个集群不可管理。
排查:
kubeadm certs check-expiration
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
修复: kubeadm certs renew all → 重启 API Server/controller-manager/scheduler。
预防: 证书过期监控(Prometheus ssl_cert_expiry)、kubeadm 1.29+ 自动续期 --feature-gates=RotateKubeletServerCertificate=true。
节点级故障(P1)
案例 4:节点批量 NotReady
故障链: 凌晨 3 点,5 个节点同时变为 NotReady → 大量 Pod 被驱逐。
根因: 定时任务在所有节点同时运行磁盘清理脚本,kubelet 因磁盘 IO 打满导致心跳超时。
排查:
kubectl describe node <node> | grep -A5 Conditions
journalctl -u kubelet --since "1 hour ago" | grep -i error
修复: 分散定时任务执行时间、kubelet --node-status-update-frequency=10s(默认 10s)、--node-monitor-grace-period=40s。
案例 5:PDB 阻断节点驱逐
故障链: 节点维护执行 kubectl drain,命令卡住不动。
根因: PDB 设了 minAvailable: 2,但只有 3 副本且其中 1 个已经在 CrashLoopBackOff → 驱逐违反 PDB。
排查:
kubectl get pdb -A
kubectl drain <node> --ignore-daemonsets --dry-run=client
修复: 临时调整 PDB 或先扩容副本 → 再 drain。长期方案:PDB 配合 maxUnavailable 更灵活。
应用级故障(P2)
案例 6:资源配额耗尽
故障链: 新部署一直 Pending,Events 提示 exceeded quota。
排查:
kubectl describe resourcequota -n <ns>
kubectl get resourcequota -n <ns> -o yaml
修复: 扩容 ResourceQuota 或清理未使用资源 → 设置告警:资源使用率 > 80%。
案例 7:滚动更新卡住
故障链: kubectl rollout status 一直等待,新 Pod 反复创建-终止。
根因: readinessProbe 配置过严 + maxUnavailable=0 → 新 Pod 未 Ready 前旧 Pod 不能删,但调度资源不足。
修复: 合理设置 maxUnavailable: 1(允许先删一个旧 Pod)、调整探针阈值。
案例 8:ConfigMap 热更新踩坑
故障链: 更新 ConfigMap 后应用没有加载新配置。
根因: ConfigMap 以 subPath 方式挂载 → 不会自动更新(subPath 是原子挂载)。
修复: 不挂载单个文件(不用 subPath),挂载整个目录 → ConfigMap 更新后会自动同步(约 60-90 秒),或配合 kubectl rollout restart 主动重启。
案例 9:HPA 抖动风暴
故障链: 副本数在 2-20 之间快速波动,服务不稳定。
根因: 使用 CPU 作为指标 + 低阈值(50%)+ 无冷却窗口 → 轻微流量波动导致频繁扩缩。
修复: 提高阈值到 70%、设置 --horizontal-pod-autoscaler-downscale-stabilization=5m(默认 5 分钟冷却)、使用更稳定的指标(如 QPS、延迟)。
案例 10:镜像拉取失败雪崩
故障链: 一个新 Deployment 因镜像 tag 写错,所有 Pod 反复 ImagePullBackOff → 同时大量拉取请求打满私有仓库带宽。
修复: imagePullPolicy: IfNotPresent(避免重复拉取)、私有仓库限流 + 镜像预缓存(Harbor P2P)、CI 中验证镜像存在后再部署。
通用排查模式
发现问题 → 判断影响范围 → 先止血后根因
├─ API Server 异常 → etcd / OOM / 证书
├─ 节点异常 → kubelet / 磁盘 / 网络
├─ Pod 异常 → describe → events → logs
└─ 部署异常 → rollout status → resourcequota → pdb
关键预防清单
| 维度 | 措施 |
|---|---|
| etcd | 独立 SSD、定期 compact+defrag、磁盘告警 |
| API Server | 资源预留、APF 限流、审计日志 |
| 证书 | 过期监控、kubeadm 1.29+ 自动续期 |
| 节点 | kubelet 资源预留、分散定时任务 |
| PDB | 谨慎设置 minAvailable、配合 maxUnavailable |
| 资源 | ResourceQuota + 使用率告警 |
| 滚动更新 | readinessProbe 宽松化 + maxUnavailable > 0 |
| ConfigMap | 避免 subPath、或配合 rollout restart |
| HPA | 避免纯 CPU、设冷却窗口、选稳定指标 |
| 镜像 | IfNotPresent、私有仓库限流、CI 预验证 |
关联页面
| 页面 | 关联案例 |
|---|---|
| node-troubleshooting | 案例 4:节点 NotReady 排查 |
| resource-rbac-scheduling-troubleshooting | 案例 2/6/9:OOMKilled / 资源配额 / HPA |
| k8s-rolling-update-pitfalls | 案例 5/7:PDB / 滚动更新卡住 |
| configmap-mount-pitfalls | 案例 8:ConfigMap subPath 热更新陷阱 |
| pod-troubleshooting | 案例 10:ImagePullBackOff |
| docker-image-optimization | 案例 10:镜像拉取策略 |
| k8s-capacity-planning-qos-cost-optimization | K8s 容量规划方法论与成本优化 — 从流量到资源预算的完整框架,含 QoS 策略、弹性伸缩协同、落 |
| k8s-resource-limits-configuration | 案例 2/6:资源限制与配额 |