2. etcd 基础回顾:Raft 协议、键值存储、Watch 机制、租约与鉴权模型
在深入多集群压测沙盘的权限矩阵复核之前,必须对 etcd 的核心基础组件建立精确的认知。etcd 是一个强一致性的分布式键值存储系统,其底层依赖 Raft 协议实现共识,上层通过键值存储、Watch 机制、租约和鉴权模型提供完整的分布式协调能力。本节将逐一拆解这些基础模块,为后续的权限矩阵分析与风险控制奠定技术基石。
2.1 Raft 协议:共识引擎
Raft 协议是 etcd 实现数据一致性的核心。它将分布式共识问题分解为三个子问题:领导者选举、日志复制和安全性。etcd 集群通常由奇数个节点组成(如 3、5、7),通过 Raft 协议确保所有节点上的数据最终一致。
- Leader(领导者): 处理所有客户端请求,负责日志复制与心跳维持。
- Follower(跟随者): 被动接收 Leader 的日志复制和心跳,参与选举投票。
- Candidate(候选者): 选举超时后发起新一轮选举,争取成为 Leader。
Raft 协议的关键流程包括:
- 领导者选举: Follower 在选举超时(election timeout)内未收到 Leader 心跳,则转为 Candidate,发起投票请求(RequestVote RPC)。获得多数票(N/2+1)的节点成为新 Leader。
- 日志复制: Leader 将客户端写入请求封装为日志条目,通过 AppendEntries RPC 并行复制到所有 Follower。当日志条目被多数节点持久化后,Leader 提交该条目并通知 Follower。
- 安全性: Raft 保证已提交的日志条目不会被覆盖,Leader 必须拥有最新的已提交日志。
以下 SVG 图展示了 Raft 协议在 3 节点集群中的日志复制与提交流程:
2.2 键值存储模型
etcd 的键值存储采用分层目录结构(类似文件系统),所有数据以键值对形式存储在 BoltDB(etcd v3 后端存储引擎)中。键值存储模型的核心概念包括:
| 概念 | 说明 | 示例 |
|---|---|---|
| Key | 唯一标识符,支持前缀匹配和范围查询 | /cluster1/app/config |
| Value | 任意字节序列,最大 1.5 MiB(默认限制) | {"port": 8080, "mode": "prod"} |
| Revision | 全局单调递增的版本号,每次写入递增 | rev=1024 |
| Lease | 关联的租约 ID,用于自动过期 | lease=12345 |
etcd v3 的键值操作通过 gRPC API 暴露,核心操作包括 Put、Get、Delete、Txn(事务)。事务支持乐观锁(基于 Revision 比较),是实现分布式锁和配置更新的基础。
# 写入键值对
etcdctl put /app/config '{"port":8080}' --lease=12345
# 读取键值对(带版本号)
etcdctl get /app/config -w json
# 事务操作:比较 Revision 后更新
etcdctl txn --interactive
compares:
value("/app/config") = "{\"port\":8080}"
success requests:
put /app/config '{"port":9090}'
failure requests:
get /app/config
2.3 Watch 机制:事件驱动
Watch 机制是 etcd 实现分布式协调的核心能力。客户端可以对某个键或键前缀注册 Watch,当键值发生变化(创建、更新、删除)时,etcd 会实时推送事件通知。Watch 机制基于 MVCC(多版本并发控制) 实现,支持从指定 Revision 开始回溯历史事件。
- Key Watch: 监听单个键的变化。
- Prefix Watch: 监听某个前缀下的所有键变化(如
/cluster1/)。 - Range Watch: 监听指定键范围的变化。
- Progress Notification: 用于检测 Watch 连接是否健康。
Watch 事件流包含以下字段:
- Type:
PUT(创建/更新)或DELETE(删除)。 - Key: 发生变化的键。
- Value: 变化后的值(仅 PUT 事件)。
- Revision: 触发该事件的全局版本号。
以下 SVG 图展示了 Watch 机制的事件流与客户端交互:
2.4 租约(Lease)机制
租约是 etcd 实现键值自动过期和分布式心跳的核心机制。租约是一个带有 TTL(生存时间)的计时器,客户端需要定期续约(KeepAlive)以维持租约有效。租约可以关联多个键,当租约过期时,所有关联的键会被自动删除。
| 租约操作 | 说明 | gRPC 接口 |
|---|---|---|
| LeaseGrant | 创建租约,指定 TTL(秒) | LeaseGrant(TTL) |
| LeaseRevoke | 撤销租约,立即删除关联键 | LeaseRevoke(ID) |
| LeaseKeepAlive | 定期续约,保持租约有效 | LeaseKeepAlive(ID) |
| LeaseTimeToLive | 查询租约剩余 TTL | LeaseTimeToLive(ID) |
租约在分布式锁、服务注册与发现、配置自动过期等场景中广泛应用。例如,服务实例启动时创建租约并关联注册键,通过后台 goroutine 定期续约;实例宕机后租约过期,注册键自动删除,实现服务自动摘除。
# 创建租约,TTL=60 秒
etcdctl lease grant 60
# 输出:lease 694d7f2b4e5c8f00 granted with TTL(60s)
# 关联键到租约
etcdctl put /services/app1 '{"addr":"10.0.0.1:8080"}' --lease=694d7f2b4e5c8f00
# 续约(每 30 秒执行一次)
etcdctl lease keep-alive 694d7f2b4e5c8f00
2.5 鉴权模型:RBAC 与权限控制
etcd v3 的鉴权模型基于 RBAC(基于角色的访问控制),核心组件包括:
- 用户(User): 访问 etcd 的实体,可绑定角色。
- 角色(Role): 权限集合,可授予用户。
- 权限(Permission): 定义对键范围的操作类型(Read、Write、ReadWrite)。
权限通过 键范围(Key Range) 进行细粒度控制,支持前缀匹配和精确匹配。鉴权模型的关键特性:
| 特性 | 说明 | 示例 |
|---|---|---|
| 权限类型 | Read、Write、ReadWrite | Read 仅允许 Get/Watch |
| 键范围 | 支持前缀匹配(key 或 key, prefix) |
/cluster1/ 前缀 |
| Root 角色 | 内置超级管理员,拥有所有权限 | root 用户 |
| 鉴权开关 | 通过 --auth- 和 auth enable 启用 |
etcdctl auth enable |
以下 SVG 图展示了 RBAC 鉴权模型的完整架构:
2.6 基础回顾总结
etcd 的五大基础组件——Raft 协议、键值存储、Watch 机制、租约与鉴权模型——构成了分布式协调系统的完整技术栈。在后续的权限矩阵复核与风险控制课程中,我们将基于这些基础组件,深入分析多集群管理场景下的权限边界、鉴权性能瓶颈和潜在安全风险。
| 组件 | 核心作用 | 压测关注点 |
|---|---|---|
| Raft 协议 | 保证数据一致性与高可用 | 选举时间、日志复制延迟、脑裂恢复 |
| 键值存储 | 提供分层键值数据模型 | 写入吞吐、Revision 增长、BoltDB 压缩 |
| Watch 机制 | 实时事件通知与分布式协调 | 连接数上限、事件推送延迟、断连重试 |
| 租约机制 | 键值自动过期与心跳管理 | 续约频率、租约数量上限、过期清理 |
| 鉴权模型 | RBAC 细粒度权限控制 | 权限验证延迟、角色解析性能、越权测试 |