主题
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 确认自己仍是 leader2. 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 应 <25ms2.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,nodiratime3. 备份与恢复
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.sh3.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-server5. 常见故障与排查
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)