Skip to content

06 — etcd 运维与调优深度教材

etcd 是 K8s 的状态存储核心,etcd 故障等于集群故障。本章覆盖 Raft 协议、性能基准、备份恢复、证书轮换、脑裂处置。


1. Raft 协议核心原理

Raft 共识算法要点:
  Leader 选举 → 日志复制 → 安全性保证

  3 节点集群:容忍 1 节点故障(quorum = 2)
  5 节点集群:容忍 2 节点故障(quorum = 3)
  
  写入流程:
    Client → Leader → AppendEntry → Follower 确认 → Commit → 响应 Client
    写入延迟 ≈ Leader→Follower 网络延迟(通常 <1ms 同机房)
    
  读流程(默认):
    Client → Leader → 检查 commit index → 响应
    Serializable read:Leader 需要与 quorum 确认自己仍是 leader

2. etcd 性能基准与调优

2.1 硬件要求

最低配置(开发/测试):
  CPU: 2 cores, RAM: 8GB, Disk: 50 IOPS SSD

生产推荐:
  CPU: 4-8 cores
  RAM: 16-32GB(etcd 主要吃内存用于 cache)
  Disk: NVMe SSD, 10000+ IOPS, <1ms 延迟
  Network: 1Gbps+, <1ms 节点间延迟

磁盘延迟是 etcd 性能瓶颈:
  fsync 延迟 >10ms → 写入延迟显著增加
  推荐 NVMe,不推荐 HDD 或远程存储(NFS/iSCSI)

2.2 性能基准测试

bash
# etcd 官方基准测试
etcd --version

# 检查磁盘性能(关键!)
fio --name=etcd-test --filename=/var/lib/etcd/fio-test \
    --size=1G --bs=256 --fdatasync=1 --rw=write \
    --ioengine=libaio --direct=1
# 关注:99th percentile fsync latency
# <5ms = 优秀, <10ms = 可接受, >10ms = 需要升级磁盘

# etcd 内置性能检查
etcdctl endpoint health --cluster
etcdctl endpoint status --cluster -w table
# 关注:isLearner, RAFT TERM, DB SIZE, LEADER

# 查看 etcd 内部指标
curl -s http://localhost:2379/metrics | grep -E 'wal_fsync|backend_commit'
# etcd_disk_wal_fsync_duration_seconds_bucket
# etcd_disk_backend_commit_duration_seconds_bucket
# 99th percentile 应 <25ms

2.3 关键参数调优

bash
# etcd 启动参数(生产推荐)
--heartbeat-interval=100          # 心跳间隔(默认 100ms)
--election-timeout=1000           # 选举超时(默认 1000ms)
--quota-backend-bytes=8589934592  # DB 大小上限 8GB(默认 2GB 太小)
--max-request-bytes=1572864       # 请求大小上限 1.5MB
--snapshot-count=10000            # 快照触发的事务数
--auto-compaction-retention=8     # 自动压缩保留 8 小时
--auto-compaction-mode=periodic   # 按时间压缩

# 磁盘优化:单独挂载 SSD
mount /dev/nvme0n1 /var/lib/etcd -o noatime,nodiratime

3. 备份与恢复

3.1 自动备份脚本

bash
#!/bin/bash
# /usr/local/bin/etcd-backup.sh
BACKUP_DIR="/backup/etcd"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

# 快照备份
ETCDCTL_API=3 etcdctl snapshot save "$BACKUP_DIR/etcd-$TIMESTAMP.db" \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# 验证快照
ETCDCTL_API=3 etcdctl snapshot status "$BACKUP_DIR/etcd-$TIMESTAMP.db" -w table

# 清理旧备份
find "$BACKUP_DIR" -name '*.db' -mtime +$RETENTION_DAYS -delete

# 建议:每 2 小时备份一次,保留 30 天
# crontab: 0 */2 * * * /usr/local/bin/etcd-backup.sh

3.2 灾难恢复

bash
# 从快照恢复(单节点)
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd/etcd-20260824.db \
  --data-dir=/var/lib/etcd-restored \
  --name=node1 \
  --initial-cluster=node1=https://192.168.1.1:2380 \
  --initial-advertise-peer-urls=https://192.168.1.1:2380

# 替换数据目录
systemctl stop etcd
mv /var/lib/etcd /var/lib/etcd.bak
mv /var/lib/etcd-restored /var/lib/etcd
chown -R etcd:etcd /var/lib/etcd
systemctl start etcd

# 多节点集群恢复:
# 1. 停止所有 etcd 节点
# 2. 在一个节点上恢复快照
# 3. 启动该节点
# 4. 其他节点作为新成员加入集群

4. 证书轮换

bash
# 查看证书过期时间
for cert in /etc/kubernetes/pki/etcd/*.crt; do
  echo "=== $cert ==="
  openssl x509 -in "$cert" -noout -dates
done

# kubeadm 集群证书轮换
kubeadm certs check-expiration
kubeadm certs renew all

# RKE2 证书轮换
# RKE2 自动在证书过期前轮换,也可手动触发:
rm -f /var/lib/rancher/rke2/server/tls/dynamic-cert.json
systemctl restart rke2-server

5. 常见故障与排查

bash
# 故障 1:etcd 响应慢
# 检查磁盘延迟
curl -s http://localhost:2379/metrics | grep wal_fsync
# 解决:升级磁盘到 NVMe

# 故障 2:DB 空间满(NOSPACE alarm)
ETCDCTL_API=3 etcdctl alarm list
# alarm:NOSPACE
ETCDCTL_API=3 etcdctl defrag --endpoints=https://127.0.0.1:2379 \
  --cacert=... --cert=... --key=...
ETCDCTL_API=3 etcdctl alarm disarm

# 故障 3:leader 频繁切换
journalctl -u etcd | grep -i 'leader changed\|election'
# 原因:网络抖动或磁盘延迟
# 解决:增大 election-timeout 或修复网络/磁盘

# 故障 4:脑裂
# 原因:网络分区导致两个 leader
# 解决:检查网络,确保 quorum 节点在同一分区

6. 面试要点

Q: etcd 为什么要求奇数节点?

3 节点:quorum=2,容忍 1 故障
4 节点:quorum=3,容忍 1 故障(与 3 节点相同,但多了一个节点开销)
5 节点:quorum=3,容忍 2 故障
偶数节点没有增加容错能力,反而增加写入延迟

Q: etcd 数据量大会怎样?怎么处理?

etcd 默认 DB 大小 2GB,超过会触发 NOSPACE alarm。
处理步骤:
1. 压缩历史版本:etcdctl compact <revision>
2. 碎片整理:etcdctl defrag(每个节点依次执行)
3. 调大 quota-backend-bytes(最大 8GB)
4. 排查哪些资源占用空间大(通常是大量 ConfigMap/Secret 或 CRD)