深色模式
etcd 原理与运维实践
摘要:本文面向生产 SRE,深入 etcd——Kubernetes 全部集群状态的唯一存储。覆盖 Raft 一致性、HA 成员数、备份/恢复、碎片整理、磁盘与网络敏感性及排障。覆盖版本:Kubernetes v1.28+(推荐 etcd 3.5.11+/3.4.29+)。
适用版本与前提
- Kubernetes:v1.28+;etcd 3.5.11+ 或 3.4.29+(官方推荐的生产最低版本)
- 工具:
etcdctl(v3 API)、etcdutl、能访问 etcd 端点的权限 - 前提:理解 Raft、quorum、TLS 基本概念
背景与问题:etcd 是集群的"真相之源"
Kubernetes 的"声明式"之所以能成立,是因为所有对象(Pod、Service、Secret、RBAC……)最终都序列化成 key-value 写进 etcd。kube-apiserver 是唯一能直接读写 etcd 的组件;其余组件通过 API Server 间接读写。因此:
能访问 etcd ≈ 拥有集群 root 权限;etcd 挂了/数据错了,集群就"失忆"了。
etcd 是 leader-based 的分布式 KV 存储,基于 Raft 共识算法保证强一致与高可用。写入需 leader 接受并复制到多数(quorum)follower 才算提交。
底层原理:Raft 与 quorum
- 奇数成员:3 成员容忍 1 个失效,5 成员容忍 2 个。永远用奇数,因为
quorum = (N/2)+1,偶数不提升容错反而增加写复制成本。 - 心跳与选举超时:leader 周期性向 follower 发心跳。网络/磁盘抖动导致心跳超时,会触发重新选举,期间集群不可写。
- 强一致代价:每次写都要多数确认,因此 etcd 写吞吐受限于最慢的 follower 与磁盘 fsync 延迟。这是 K8s 扩展性最根本的硬约束之一。
资源饥饿是头号杀手
etcd 对网络与磁盘 I/O 极其敏感。CPU/内存/磁盘任一饥饿都会拉长 WAL fsync,进而心跳超时、leader 反复切换、集群不稳定。官方明确建议 etcd 跑在专属机器或隔离环境,并保障低延迟磁盘(如本地 SSD)。不要和其余高 IO 负载混部。
生产部署:成员数与拓扑
官方建议生产用 5 成员集群;至少也得 3 成员。两种典型拓扑:
- 堆叠式(Stacked):etcd 与 kube-apiserver 同节点(kubeadm 默认用 static pod)。部署简单,但控制面节点挂了会同时损失 etcd 成员。
- 外部 etcd(External):etcd 独立集群,kube-apiserver 用
--etcd-servers指向它。容错更好,运维更复杂。
bash
# kube-apiserver 指向多成员 etcd(或用 LB 前置)
kube-apiserver \
--etcd-servers=https://10.0.0.1:2379,https://10.0.0.2:2379,https://10.0.0.3:2379 \
--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt \
--etcd-certfile=/etc/kubernetes/pki/etcd/server.crt \
--etcd-keyfile=/etc/kubernetes/pki/etcd/server.key1
2
3
4
5
6
2
3
4
5
6
安全建议
etcd 之间的 peer 通信与客户端通信都应启用基于 x509 PKI 的 TLS。配置 --client-cert-auth + --trusted-ca-file 后,只有持合法证书的客户端(即 API Server)能访问。etcd 自身认证不在 Kubernetes 计划内——所以必须靠网络隔离 + TLS 把访问面收敛到 API Server。
备份与恢复(生产必做)
所有 Kubernetes 对象都在 etcd 里,定期备份是灾难恢复的底线。
步骤 1:快照备份(推荐方式)
bash
ETCDCTL_API=3 etcdctl \
--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 \
snapshot save /backup/etcd-$(date +%F-%H%M).db
# 校验快照完整性/状态
ETCDCTL_API=3 etcdutl snapshot status /backup/etcd-$(date +%F-%H%M).db1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
备份加密
快照含全部集群敏感数据(Secret 明文)。务必加密快照文件并严控访问权限,否则备份本身成为泄露源。
步骤 2:恢复(灾难场景)
bash
# 在目标成员上用快照恢复出数据目录
ETCDCTL_API=3 etcdutl snapshot restore /backup/etcd-<ts>.db \
--data-dir /var/lib/etcd-restore \
--name member1 \
--initial-cluster member1=http://10.0.0.1:2380 \
--initial-cluster-token etcd-cluster-1
# 然后用该 data-dir 启动 etcd 成员,多成员需逐个恢复并重组集群1
2
3
4
5
6
7
2
3
4
5
6
7
生产危险
恢复 etcd 会覆盖现有集群状态并可能导致控制面短暂不可用。务必先在隔离环境演练,确认备份可用后再在生产执行;全量恢复前建议冻结写流量(停止 kube-apiserver)。
碎片整理(defragmentation)
etcd 删除 key 后空间不会立刻回收,历史版本累积会让 db 文件膨胀、影响性能。需定期 defrag:
bash
# 在线碎片整理(逐个成员执行,避免同时操作引发抖动)
ETCDCTL_API=3 etcdctl \
--endpoints=https://10.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 \
defrag1
2
3
4
5
6
7
2
3
4
5
6
7
自动化
kubeadm 部署的 etcd 可借助 etcd-defrag 等定时任务做自动 defrag,但必须串行、错峰执行,且监控 db 大小触发阈值再执行,避免业务高峰操作。
替换失效成员
成员损坏时,建议逐个替换(多成员同时坏也要一个一个来):
bash
# 1) 列出成员拿到失效成员的 ID
etcdctl member list
# 2) 移除失效成员
etcdctl member remove <member-id>
# 3) 添加新成员
etcdctl member add member4 --peer-urls=http://10.0.0.4:2380
# 4) 在新机器以 existing 状态启动 etcd,指向剩余成员
export ETCD_INITIAL_CLUSTER_STATE=existing
# 5) 把新成员加入 kube-apiserver 的 --etcd-servers 并重启 apiserver1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
常见失败模式
| 现象 | 常见根因 | 排查方向 |
|---|---|---|
| leader 频繁切换 | 磁盘 fsync 慢 / 网络抖动 | etcd_disk_wal_fsync_duration_seconds、etcd_server_leader_changes_seen_total |
| 写超时、API 变慢 | etcd 过大 / 未 defrag / 配额满 | db 大小、配额、碎片率 |
| 集群不可写 | 少于 quorum(如 3 成员坏 2 个) | 成员存活、网络分区 |
| 启动失败 | data-dir 损坏 / 证书过期 | 快照恢复、检查 TLS 证书有效期 |
可观测性:必看指标
etcd_server_leader_changes_seen_total:短时间内持续增长 = 不稳定,红警。etcd_disk_wal_fsync_duration_seconds(p99):应远低于选举超时(默认 100ms 心跳、1s 选举超时量级)。etcd_mvcc_db_total_size_in_bytes:监控膨胀,触发 defrag 阈值。etcd_network_peer_round_trip_time_seconds:peer 间 RTT,反映网络健康。
性能、容量与成本
- etcd 官方有推荐硬件配置(见 etcd 运维指南 hardware 章节)。生产建议:专用核、低延迟 SSD、分离的网络。
- 单 etcd 集群能支撑的对象量有限(经验上数十万级对象开始吃力,[版本相关]具体上限随 K8s 版本与对象大小变化,需按自身负载压测)。超大集群应优先多集群分片而非无限堆大 etcd。
- 成本:5 成员 etcd 意味着 5 台专属/隔离机器,有固定开销;托管 K8s 由云厂商承担但同样受底层约束。
安全与合规
- 最小访问面:只允许 API Server 访问 etcd;用防火墙 + TLS 客户端证书双重约束。
- 证书有效期:etcd/API Server 间 TLS 证书过期会导致控制面全面失联,纳入证书轮换与到期监控。
- 加密静态数据:除备份加密外,可对 etcd 落盘启用静态加密(K8s EncryptionConfiguration),但注意密钥管理自身也是风险点。
替代方案与权衡
- 外部 etcd vs 堆叠 etcd:外部容错更强、运维更重;堆叠部署简单、控制面节点故障会同时损失 etcd 成员。按对可用性要求取舍。
- 多集群 / 分片:当单集群 etcd 成为瓶颈,拆集群比纵向堆资源更可持续。
- etcd 之外的存储:Kubernetes 设计上绑定 etcd,无官方替代存储后端;不要尝试用其他 KV 替换。
FAQ
Q:3 成员和 5 成员怎么选? A:小规模/成本敏感用 3(容忍 1 失败);大规模、对控制面可用性要求极高用 5(容忍 2 失败,且能容忍一次维护不掉容错)。
Q:etcd 能和业务混部吗? A:强烈不建议。官方要求专属/隔离资源,资源饥饿会直接拖垮整个集群。
参考资料
- Operating etcd clusters for Kubernetes - Kubernetes 官方文档,访问日期:2026-10-08。
- etcd 官方运维文档(hardware / clustering / recovery),访问日期:2026-10-08。
- etcd FAQ - Failure tolerance,访问日期:2026-10-08。