K8s etcd 磁盘 I/O 延迟高导致集群死亡螺旋排查
2026-08-11 00:53:03 # Kubernetes

节点集体 NotReady、控制面响应变慢、Pod 大规模重建——三件事同时发生且互相加剧,往往是 etcd 磁盘 I/O 跟不上写入,陷入”死亡螺旋”。本文讲怎么识别并打破这个循环。

问题现象与背景原因

典型现象:控制面变慢,节点心跳超时被标记 NotReady,NotReady 又触发大规模 Pod 重建,重建进一步压垮控制面。

1
2
3
4
kubectl get nodes
NAME STATUS ...
node-1 NotReady # 心跳超时
node-2 NotReady
1
2
kubectl get events --sort-by=.lastTimestamp | tail
# 大量 NodeNotReady / 大规模 Pod 重建事件

核心原因:底层存储磁盘性能不足

  • etcd 是强一致、写穿磁盘的数据库,每次写都要 fsync 到磁盘。
  • 若底层是网络存储(如某些云盘 / NFS / 低 IOPS 云盘),写入延迟高,etcd 提交变慢。
  • etcd 写慢 → leader 之间心跳超时 → 频繁选举 / 失联 → API Server 请求堆积超时。
  • 节点 lease 心跳超时 → 节点被标记 NotReady → 控制器大规模重建 Pod → 又产生海量 etcd 写 → 进一步拖慢 etcd,形成”死亡螺旋”。

提示:节点集体 NotReady + 控制面慢 + 磁盘 I/O 高,三者同时出现,优先怀疑 etcd 磁盘,而不是网络或节点本身。

排查过程(思路与定位方法)

第一步:看 etcd 日志里的慢请求 / 磁盘延迟。

1
2
journalctl -u etcd --since 30m | grep -iE 'slow|fsync|backend|took too long'
# 典型:'took too long' / 'failed to send out heartbeat' / 'read-only'

第二步:看节点磁盘实际指标。

1
2
3
# 控制面节点上
iostat -x 1 5 # 看 %util、await、r_await/w_await
# 或用 node-exporter 指标:node:disk_io_time_seconds:sum / node:disk_latency

第三步:用 fio 实测磁盘 IOPS / 延迟(裸盘性能)。

1
2
3
4
fio --name=etcd-test --rw=write --bs=4k --numjobs=1 \
--size=1G --runtime=60 --time_based --direct=1 \
--filename=/var/lib/etcd/fio-test
# 关注 IOPS 与 lat (usec);etcd 建议 SSD,写延迟 < 10ms、IOPS 数千

第四步:看 etcd leader 是否频繁切换。

1
2
3
export ETCDCTL_API=3
ectl endpoint status --write-out=table # 看 LEADER 是否稳定
journalctl -u etcd | grep -iE 'became leader|lost leader|election'

最终的解决方法

  • etcd 必须使用高性能 SSD 硬盘,并独立部署(不与其它负载混盘)。
  • 监控磁盘 IOPS 与延迟,对 etcd 盘设告警(如 await > 10ms 报警)。
  • 发生死亡螺旋时紧急止损:
    1. 切走 etcd Leader / 扩容控制面节点,减少单点压力:
      1
      ectl move-leader <healthy-member-id>
    2. 临时降低写入压力:暂停非关键批量任务、限制大规模对象变更。
    3. 长期:将 etcd 数据盘迁移到本地 NVMe SSD;若用云盘,选高 IOPS 类型并独享。

预防配置(kubeadm 示例,指定 etcd 到高性能盘):

1
2
3
# /etc/kubernetes/manifests/etcd.yaml 中
- --data-dir=/var/lib/etcd # 确保挂载的是高性能 SSD
# 部署时把 SSD 盘挂到该目录

操作命令(可直接复制执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 看 etcd 慢日志
journalctl -u etcd --since 30m | grep -iE 'slow|fsync|took too long'

# 2. 节点磁盘 I/O
iostat -x 1 5

# 3. 实测磁盘性能
fio --name=etcd-test --rw=write --bs=4k --numjobs=1 \
--size=1G --runtime=60 --time_based --direct=1 \
--filename=/var/lib/etcd/fio-test

# 4. etcd leader 状态
ectl endpoint status --write-out=table

# 5. 紧急切 leader
ectl move-leader <healthy-member-id>

# 6. 节点磁盘延迟监控(node-exporter 指标示例)
# node:disk_io_time_seconds:sum{device=~"nvme.*"}