2. etcd 架构速览:Raft 共识算法、MVCC 存储、Watch 机制、Lease 机制
etcd 是 Kubernetes 控制平面的唯一状态存储,其架构设计直接决定了集群的可靠性、一致性与响应性能。在生产排障中,理解 etcd 的四大核心机制——Raft 共识算法、MVCC 存储、Watch 机制、Lease 机制——是定位发布流水线异常的关键前提。本节从架构视角速览这四大组件,为后续日志关联与根因分析打下基础。
2.1 整体架构分层
etcd 内部可划分为三层:
- 网络层:基于 gRPC 的客户端-服务器通信与节点间 Raft 消息传递。
- 共识层:Raft 算法实现,负责日志复制、领导者选举与集群成员变更。
- 存储层:基于 BoltDB(底层 B+ 树)的 MVCC 键值存储,配合 Watch 与 Lease 提供分布式协调原语。
排障提示: 发布流水线异常时,首先判断故障发生在哪一层——网络层超时、共识层分裂、还是存储层写入延迟?分层定位能大幅缩小根因范围。
2.2 Raft 共识算法
Raft 是 etcd 保证强一致性的核心。它将共识问题分解为三个子问题:领导者选举、日志复制、安全性。
| 子问题 | 核心机制 | 异常场景(发布流水线相关) |
|---|---|---|
| 领导者选举 | 基于随机超时(150~300ms)的选举触发;获得多数票的节点成为 Leader | 网络分区导致频繁选举 → 写入延迟飙升 → 发布超时 |
| 日志复制 | Leader 将日志条目并行复制到 Follower;多数派确认后提交 | 磁盘 I/O 抖动导致 Follower 追加慢 → 提交延迟 → 发布卡顿 |
| 安全性 | 只有拥有最新已提交日志的节点才能当选 Leader;日志条目一旦提交永不丢失 | 旧 Leader 恢复后尝试覆盖新日志 → 日志冲突 → 集群拒绝服务 |
关键指标: 发布流水线异常时,优先检查
etcd_server_leader_changes_seen_total 和 etcd_disk_wal_fsync_duration_seconds。Leader 频繁切换是 Raft 层故障的典型信号。
2.3 MVCC 存储
etcd 采用多版本并发控制(MVCC)实现快照隔离。每次写操作不覆盖旧值,而是生成一个新版本号(revision)。
- 键值存储:每个键维护一个版本链,读操作可指定版本号读取历史数据。
- 压缩(Compaction):定期回收旧版本,防止存储无限增长。压缩后历史版本不可读。
- 事务支持:基于 revision 的比较-交换(CAS)操作,实现乐观锁。
# 查看当前集群的 revision 状态
etcdctl endpoint status --write-out=table
# 手动压缩到指定 revision(生产慎用)
etcdctl compact 123456
排障陷阱: 发布流水线中如果出现 "mvcc: database space exceeded" 错误,说明 etcd 存储空间耗尽。此时需要立即执行碎片整理(defrag)或调整自动压缩参数,否则集群将进入只读模式。
2.4 Watch 机制
Watch 是 etcd 实现事件驱动架构的核心。客户端可以监听某个键或某个前缀,当键值发生变化时,etcd 通过 gRPC 流实时推送事件。
| Watch 类型 | 行为 | K8s 使用场景 |
|---|---|---|
| 单键 Watch | 监听单个键的 Put/Delete 事件 | 监听特定 ConfigMap 变更 |
| 前缀 Watch | 监听某个前缀下的所有键变更 | 监听 /registry/pods/ 下所有 Pod 变化 |
| 创建式 Watch(Create) | 仅监听键被创建的事件 | 监听新 Service 注册 |
排障要点: 当发布流水线出现 "too many watchers" 或 watch 响应延迟时,检查
etcd_debugging_mvcc_watcher_total 指标。大量无效或重复的 watch 会消耗 etcd 内存与 CPU,导致关键事件推送延迟。
2.5 Lease 机制
Lease(租约)是 etcd 提供的分布式心跳与超时淘汰机制。Kubernetes 大量使用 Lease 实现节点心跳、Leader 选举和临时状态管理。
- 创建 Lease:指定 TTL(生存时间),etcd 保证在 TTL 内 Lease 有效。
- 续约(KeepAlive):客户端定期发送心跳刷新 Lease,防止过期。
- 绑定键值:将键与 Lease 关联,Lease 过期时自动删除关联键。
# 创建一个 TTL=60s 的 Lease
etcdctl lease grant 60
# 将 key 绑定到 Lease
etcdctl put --lease=694d6e6e6e6e6e6e /mykey myvalue
# 手动续约
etcdctl lease keep-alive 694d6e6e6e6e6e6e
发布流水线异常案例: 当 K8s 节点心跳 Lease 过期(通常 TTL=40s),kube-controller-manager 会标记节点为 NotReady,导致 Pod 被驱逐。排查时检查
etcd_lease_ttl_seconds 与 etcd_lease_expired_total 指标,确认是否存在 Lease 续约失败。
2.6 四大机制协同关系
在发布流水线场景中,四大机制并非孤立运行,而是紧密协作:
- Raft 保证所有节点上的 MVCC 写入日志一致。
- MVCC 为每个写入生成唯一 revision,Watch 基于 revision 实现增量推送。
- Watch 将键值变更实时推送给 K8s 控制器,驱动发布流程状态转换。
- Lease 管理临时资源生命周期,过期时触发 Watch 删除事件,实现自动清理。
根因定位口诀: 写入看 Raft(日志复制延迟),读取看 MVCC(压缩与空间),事件看 Watch(推送积压),存活看 Lease(续约超时)。四者交叉验证,即可锁定发布异常根因。