前言
前六篇文章我们从理论到实战,完整走了一遍 etcd 的学习和迁移过程。这篇文章整理了一些线上常见的 etcd 问题及排查方法,希望能帮你在实际工作中少走弯路。
一、集群状态类问题
问题 1:集群 degraded
现象:
bash
etcdctl cluster-health
# 输出:cluster is degraded
原因: 某个 etcd 节点的 2379 端口不可达。
排查步骤:
bash
# 1. 看哪个节点不通
etcdctl member list
# 2. 测试端口连通性
# 2379 是 client 端口,2380 是 peer 端口
timeout 3 bash -c 'echo > /dev/tcp/10.0.0.2/2379' && echo "通" || echo "不通"
timeout 3 bash -c 'echo > /dev/tcp/10.0.0.2/2380' && echo "通" || echo "不通"
# 3. 看不通节点的 etcd 进程是否活着
ssh 10.0.0.2 "systemctl status etcd"
# 4. 看不通节点的日志
ssh 10.0.0.2 "journalctl -u etcd --no-pager -n 50"
# 5. 检查防火墙规则
ssh 10.0.0.2 "firewall-cmd --list-all"
# 或
ssh 10.0.0.2 "iptables -L -n"
常见原因和解决:
| 原因 | 解决 |
|---|---|
| 防火墙拦截了 2379/2380 | 添加 firewalld 规则放行 |
| etcd 进程挂了 | systemctl start etcd 重启 |
| 网络不通 | 检查交换机/路由策略 |
| etcd 配置错误 | 检查 etcd.conf 中的 IP 是否正确 |
问题 2:集群健康但写入超时
现象:
应用写入 etcd 时经常超时
但 cluster-health 显示 healthy
排查:
bash
# 1. 看 leader 是否稳定
journalctl -u etcd --no-pager | grep "elected leader"
# 如果 leader 频繁切换,说明网络不稳定
# 2. 看磁盘延迟
iostat -x 1 5
# svctm > 10ms 说明磁盘太慢
# 3. 看 etcd 进程的磁盘写入延迟
# 在 etcd metrics 中查看
curl http://127.0.0.1:2379/metrics 2>/dev/null | grep wal_fsync
# wal_fsync_duration_seconds > 0.01 说明磁盘写入慢
解决:
如果是磁盘慢 → 换 SSD
如果是 leader 频繁切换 → 检查网络延迟
如果是节点负载高 → 检查 CPU 和内存
二、节点故障类问题
问题 3:一台 etcd 节点彻底坏了
场景: 磁盘损坏、操作系统崩溃,节点无法恢复。
恢复步骤:
bash
# 1. 在正常节点上移除坏节点
# 先获取坏节点的 member ID
etcdctl member list
# 移除
etcdctl member remove <坏节点的 member ID>
# 2. 现在集群只剩 2 个节点
# 3 节点集群挂 1 台,还能正常工作(quorum=2)
# 3. 修复或重建节点后,重新加入集群
etcdctl member add etcd-vm-3-new http://10.0.0.3:2380
# 4. 在新节点上启动 etcd(注意用 existing)
# 它会自动从现有集群同步数据
问题 4:两台节点同时坏了
场景: 3 节点集群只剩 1 台。
3 节点集群,quorum = 2
只剩 1 台 → 1 < 2 → 无法写入 ❌
但可以读取旧数据
恢复步骤:
bash
# 1. 在幸存节点上打 snapshot
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 snapshot save /tmp/emergency-snapshot.db
# 2. 重建 3 台新 VM
# 3. 在新 VM 上 restore snapshot
# 参考上一篇的迁移步骤
# 4. 启动新集群
问题 5:Leader 挂了
现象:
应用写入 etcd 超时
etcdctl cluster-health 报错
原理:
Leader 挂了 → follower 收不到心跳
→ 等待选举超时(默认 150ms~300ms)
→ 其中一个 follower 变成 candidate
→ 发起选举 → 获得过半投票 → 成为新 leader
整个过程通常 1 秒内完成
无需人工干预,etcd 会自动恢复。 但如果 leader 频繁切换,需要排查网络问题。
三、磁盘空间类问题
问题 6:磁盘空间不足
现象:
etcd 日志中出现:disk space不足
df -h 显示磁盘使用率 > 80%
排查:
bash
# 查看 etcd 数据量
du -sh /data/etcd/etcd-cluster/
du -sh /data/etcd/etcd-cluster/member/snap/
du -sh /data/etcd/etcd-cluster/member/wal/
解决:
bash
# 方案一:开启自动 compaction
# 在 etcd 启动参数中加
--auto-compaction-retention=1
# 保留最近 1 小时的 revision
# 方案二:手动 compaction
export ETCDCTL_API=3
# 获取当前 revision
REV=$(etcdctl --endpoints=http://127.0.0.1:2379 endpoint status --write-out=fields | grep revision | awk '{print $2}')
# 压缩(删除之前的版本)
etcdctl --endpoints=http://127.0.0.1:2379 compaction $REV
# 方案三:扩容数据盘
问题 7:数据量异常增长
现象:
正常情况下 etcd 数据量应该保持稳定
但发现数据量持续增长,每周增长 10%
可能原因:
1. 没有开启 compaction → 历史版本不删除
2. 应用频繁写入大量数据 → 检查是否有异常写入
3. snapshot count 设置过大 → 默认 100000,一般够用
排查:
bash
# 查看 etcd 的 revision 增长情况
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 endpoint status --write-out=table
# 对比一周前的 revision,看增长了多少
四、网络类问题
问题 8:节点间 2380 不通
现象:
etcdctl cluster-health 显示 degraded
但 ping 能通
排查:
bash
# 测试 2380 端口
timeout 3 bash -c 'echo > /dev/tcp/10.0.0.2/2380' && echo "通" || echo "不通"
# 检查防火墙
firewall-cmd --list-all
iptables -L -n
# 检查 etcd 是否在监听 2380
ss -tlnp | grep 2380
注意: 2380 是 etcd 节点之间同步数据的端口,必须互开。2379 是 client 端口,节点之间不一定需要互开。
问题 9:客户端连不上 2379
现象:
应用报错:dial tcp 10.0.0.1:2379: connect: no route to host
排查:
bash
# 1. 测试端口
timeout 3 bash -c 'echo > /dev/tcp/10.0.0.1/2379' && echo "通" || echo "不通"
# 2. 检查 etcd 是否在监听
ssh 10.0.0.1 "ss -tlnp | grep 2379"
# 3. 检查防火墙
ssh 10.0.0.1 "firewall-cmd --list-all"
五、日常运维 Checklist
每天
bash
# 集群健康检查
etcdctl --endpoints=http://10.0.0.1:2379,http://10.0.0.2:2379,http://10.0.0.3:2379 cluster-health
# 检查 leader 是否稳定
journalctl -u etcd --no-pager -n 20 | grep -E 'error|Error|leader|elected'
每周
bash
# 数据量检查
du -sh /data/etcd/etcd-cluster/
df -h /data
# 查看 revision 增长
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 endpoint status --write-out=table
定期
bash
# 每天备份(建议用 crontab)
export ETCDCTL_API=3
etcdctl --endpoints=http://127.0.0.1:2379 snapshot save /backup/etcd/etcd-snapshot-$(date +%Y%m%d).db
# 保留最近 30 天的备份
find /backup/etcd/ -name "*.db" -mtime +30 -delete
六、总结
etcd 排障的核心思路:
1. 先看集群健康:cluster-health
2. 再看成员列表:member list
3. 测试端口:telnet / timeout + /dev/tcp
4. 看日志:journalctl -u etcd
5. 看防火墙:firewall-cmd / iptables
6. 看磁盘:df -h / du -sh
大部分问题都能通过这六步定位
系列完结
这个 etcd 学习系列一共七篇文章,从入门概念到集群架构,从 Raft 协议到存储模型,从 Watch 机制到运维实战,最后到排障指南。
回顾一下整个学习路径:
第一篇:etcd 是什么?------ 从业务需求出发
第二篇:集群架构 ------ 3 节点如何工作
第三篇:Raft 协议 ------ 分布式一致性
第四篇:存储模型 ------ WAL 和 Snapshot
第五篇:Watch 机制 ------ 配置热加载
第六篇:运维实战 ------ 物理机到虚拟机迁移
第七篇:排障指南 ------ 常见问题与解决方案
希望这个系列对你有帮助。如果有任何问题或建议,欢迎交流讨论~