2. etcd 架构与数据模型:Raft 共识算法、MVCC、键值存储、Watch 机制、租约

etcd 是一个高可用的分布式键值存储系统,其核心架构围绕 Raft 共识算法、MVCC(多版本并发控制)、键值存储引擎、Watch 机制 和 租约(Lease) 五大支柱构建。理解这些组件是掌握 etcd 准入策略与安全门禁的基础。

2.1 整体架构分层

etcd 的架构自底向上分为三层:

  • 网络层:基于 gRPC 的 HTTP/2 通信,处理客户端请求与节点间 Raft 消息。
  • 共识层(Raft):保证集群数据一致性与高可用,是分布式安全的基石。
  • 存储层:包含 MVCC 键值存储、Watch 索引、租约管理,直接响应读写请求。
etcd 核心架构分层 网络层 — gRPC / HTTP/2 客户端请求入口 · 节点间 Raft 消息 · 流式 Watch 共识层 — Raft 算法 Leader 选举 · 日志复制 · 安全性保证 存储层 — 数据模型 MVCC 键值存储 · Watch 机制 · 租约管理 后端:BoltDB(持久化) + 内存索引

2.2 Raft 共识算法

Raft 是 etcd 分布式一致性的核心,通过 Leader 选举 和 日志复制 确保集群中所有节点数据最终一致。etcd 的准入策略必须与 Raft 的提交阶段协同工作。

Raft 角色 职责 安全影响
Leader 处理所有客户端写入,管理日志复制 准入策略在 Leader 端执行,拒绝的请求不会进入 Raft 日志
Follower 被动复制日志,处理只读请求 Follower 可配置线性化读,需向 Leader 确认提交索引
Candidate 选举阶段临时角色 选举期间集群不可写入,准入策略暂停执行
安全提示: 准入策略在 Raft 日志提交前执行。如果策略拒绝写入,该请求不会进入 Raft 日志,从而避免无效日志复制,降低集群负载。

2.3 MVCC 与键值存储

etcd 使用 MVCC(多版本并发控制) 管理键值对。每次写入生成一个新版本,旧版本保留一段时间用于历史查询和 Watch 事件回溯。

  • Key-Value 存储:底层基于 BoltDB(现为 bbolt),键值对以 /namespace/key 形式组织。
  • 版本号(revision):全局单调递增的整数,标识每次写入操作。
  • MVCC 工作流程:
    1. 客户端发起 Put 请求。
    2. etcd 分配新的全局 revision。
    3. 写入 BoltDB,同时更新内存中的 B-tree 索引。
    4. 触发关联的 Watch 事件。
MVCC 写入流程 客户端 准入策略 Raft 日志 MVCC 存储 MVCC 关键特性 • 每次 Put 生成新 revision,旧版本保留在 BoltDB 中 • 读操作可指定 revision 实现时间点查询(快照读) • 压缩(Compact)定期清理旧版本,释放存储空间 • 准入策略可基于 key 前缀或 revision 范围进行过滤

2.4 Watch 机制

Watch 是 etcd 的核心观察者模式,客户端可以监听特定键或前缀的变化。Watch 事件基于 MVCC 版本号触发,保证事件不丢失、不重复。

Watch 类型 触发条件 典型场景
Key Watch 单个键的 Put / Delete 监听 Pod 状态变化
Prefix Watch 匹配前缀的所有键变化 监听 Namespace 下所有资源
Revision Watch 从指定 revision 开始的历史事件 断线重连后的事件回溯
安全风险: 大量 Watch 连接会消耗 etcd 内存。恶意客户端可创建大量 Watch 导致 OOM。准入策略应限制每个客户端的 Watch 数量。

2.5 租约(Lease)

租约是 etcd 实现 TTL(生存时间) 和 节点心跳 的机制。每个租约有一个过期时间,关联的键在租约过期后自动删除。

  • 租约创建:客户端通过 LeaseGrant 创建租约,指定 TTL。
  • 租约续期:客户端定期发送 LeaseKeepAlive 保持租约活跃。
  • 键关联:Put 操作可指定租约 ID,键的生命周期与租约绑定。
  • 租约过期:租约到期后,所有关联键被自动删除,触发 Delete Watch 事件。
Kubernetes 场景: Node 心跳使用租约实现。每个 Node 创建一个租约,定期续期。如果 Node 失联,租约过期,K8s 标记 Node 为 NotReady。准入策略可监控租约过期频率,识别异常节点。

2.6 数据模型总结

下表对比了 etcd 核心组件在安全门禁中的关注点:

组件 安全关注点 准入策略切入点
Raft 日志复制一致性,防止分裂脑 在日志提交前拦截非法写入
MVCC 版本爆炸导致存储膨胀 限制单个 key 的版本数量
Watch 连接数过多导致内存泄漏 限制每个客户端的 Watch 数量
租约 租约过期导致数据意外删除 验证租约 TTL 是否在合理范围