K8s etcd 数据库碎片化导致集群脑裂崩溃排查
2026-08-11 00:53:03
# Kubernetes
凌晨 API Server 无响应、所有节点状态异常、etcd 健康检查超时——这类 P0 级事故,背后常是 etcd 数据库碎片化。它不会立刻报错,而是渐进式变慢,直到某个时间点突然触发连锁故障。
问题现象与背景原因
典型现象:API Server 无响应,etcd 健康检查卡住或超时。
1 | ETCDCTL_API=3 etcdctl \ |
核心原因:etcd 数据库碎片化(Fragmentation)严重。
- K8s 所有状态都存在 etcd。etcd 用 MVCC(多版本并发控制),每次写都保留历史版本,由后台 compaction 清理。
- 若 compaction 不及时或写入量巨大,历史版本堆积,底层 boltdb 文件产生大量”空洞”,DB Size 膨胀到数 GB(健康通常几百 MB)。
- 文件碎片化后,读写需扫描大量空洞,性能急剧下降,etcd 响应变慢 → 与 API Server 心跳超时 → 集群脑裂 / 控制面崩溃。
提示:etcd 慢是”沉默的杀手”。它不会立刻报错,而是渐进式变慢,直到某个时间点(常是凌晨批量任务 / 大量对象变更)突然触发连锁故障。
排查过程(思路与定位方法)
第一步:看 etcd 健康与 DB 大小。
1 | export ETCDCTL_API=3 |
关注 DB SIZE 列,正常应 < 500MB;若到 GB 级说明已膨胀。
第二步:看是否有 alarm(如 NOSPACE 空间不足告警)。
1 | ectl alarm list |
第三步:看碎片率(粗略判断)。 用 endpoint status 的 DB SIZE 与磁盘上实际文件大小对比,差异越大碎片化越严重。
第四步:看 API Server / etcd 日志里的 slow 请求。
1 | journalctl -u kube-apiserver -u etcd --since 1h | grep -iE 'slow|timeout|lag' |
最终的解决方法
核心操作:etcdctl defrag 碎片整理(需在维护窗口内,会阻塞写)。
1 | # 对每个 etcd 端点执行在线碎片整理 |
配套措施(黄金法则):
- 定期 compaction + defrag 脚本化,纳入定时维护。
- 定期快照备份(见下)。
- 监控 DB SIZE 与磁盘延迟,设阈值告警。
- 控制写入量:避免集群对象(Pod / Secret / CRD 实例)无限增长。
周期性维护示例:
1 | # 先 compact 到当前版本 |
快照备份(救命用):
1 | ectl snapshot save /backup/etcd-$(date +%F).db |
操作命令(可直接复制执行)
1 | # 设别名简化(控制面节点执行) |