2. etcd 基础回顾:Raft 一致性协议、集群节点角色与数据存储结构
etcd 是云原生架构中事实上的元数据存储标准,也是 Kubernetes 控制平面的“大脑”。在多租户集群升级场景下,etcd 的稳定性直接决定了租户故障域的边界。本节从 Raft 协议、节点角色和数据存储三个维度,建立后续故障注入与隔离测试所需的基础认知。
2.1 Raft 一致性协议
Raft 是一种易于理解的一致性算法,通过 Leader 选举、日志复制 和 安全性 三个核心机制,保证分布式系统在部分节点故障时仍能对外提供强一致性的读写服务。etcd 使用 Raft 作为其共识引擎。
Raft 协议将时间划分为任意长度的 任期(Term),每个任期最多只有一个 Leader。节点之间通过 RequestVote 和 AppendEntries 两种 RPC 消息进行通信。
| Raft 核心机制 | 描述 | 对多租户的影响 |
|---|---|---|
| Leader 选举 | Follower 在选举超时内未收到 Leader 心跳,转为 Candidate 并发起选举 | 选举期间集群不可写入,影响所有租户的 API 请求 |
| 日志复制 | Leader 将客户端请求封装为日志条目,并行复制到多数节点后才提交 | 网络分区或慢节点可能导致租户请求延迟飙升 |
| 安全性 | 只有拥有最新已提交日志的节点才能成为 Leader | 故障恢复后,租户数据不会回滚到旧版本 |
2.2 etcd 集群节点角色
etcd 集群中的每个节点在 Raft 协议层面承担三种角色之一,但在实际运维中,节点角色与 API 暴露方式存在更细致的划分。
| 角色 | 职责 | 可读 | 可写 | 故障影响范围 |
|---|---|---|---|---|
| Leader | 处理所有客户端写入请求,管理日志复制与心跳 | 是 | 是 | Leader 故障触发选举,集群短暂不可写 |
| Follower | 被动复制日志,处理只读请求(可配置) | 是(默认) | 否 | 单个 Follower 故障不影响集群可用性 |
| Candidate | 选举过程中的临时角色,向其他节点拉票 | 否 | 否 | 选举期间集群不可写 |
2.3 数据存储结构:key-value 与 watch 机制
etcd 的数据模型是一个扁平的 key-value 存储,但在此基础上实现了 多版本并发控制(MVCC) 和 事件监听(Watch),使其成为 Kubernetes 控制平面的理想后端。
2.3.1 键值存储与版本管理
每个 key 对应多个历史版本,etcd 通过 revision(全局递增版本号)和 mod_revision(key 的修改版本号)来管理数据变更。Kubernetes 利用这一机制实现乐观锁和资源更新冲突检测。
# 写入 key
etcdctl put /registry/namespaces/default "namespace: default"
# 输出:OK
# 带版本读取
etcdctl get /registry/namespaces/default --rev=100
# 输出:/registry/namespaces/default
# namespace: default
# 监听 key 变化
etcdctl watch /registry/namespaces/default
# 等待变更...
2.3.2 Watch 机制:事件驱动的数据同步
Watch 是 etcd 最核心的机制之一,它允许客户端在 key 或目录范围上注册监听器,当数据发生变化时,etcd 会推送事件给客户端。Kubernetes 的 Informer 机制 正是基于 etcd Watch 实现的。
2.4 多租户视角下的 etcd 关键指标
在后续的故障域测试中,我们需要重点关注以下 etcd 指标,它们直接反映租户隔离的稳定性:
- Leader 变更次数:频繁的 Leader 选举会导致租户请求超时和重试风暴。
- DB 总大小:单个租户的异常写入可能撑爆 etcd 存储,影响所有租户。
- Watch 连接数:每个租户的控制器都会建立 Watch 连接,连接数过多会消耗 etcd 内存。
- 请求延迟(P99):租户间的资源竞争可能导致延迟上升,触发客户端重试。
--quota-backend-bytes 为 2GB,一旦超过该限制,集群将进入只读模式,所有租户的写入操作都会失败。在多租户场景下,必须为每个租户设置资源配额上限。