3. 高可用设计原则
Kubernetes 控制器管理器(kube-controller-manager)作为控制面的核心组件,其高可用设计遵循经典的 Active/Passive 主备模式。该模式通过 Leader Election(领导者选举) 机制实现多副本间的协调,确保在任何时刻只有一个活跃实例执行控制循环,其余实例处于热备状态。当活跃实例发生故障时,系统自动触发 故障转移,由备用实例接管领导权,从而保证控制面的持续可用。
3.1 Active/Passive 主备模式
Active/Passive 模式是 Kubernetes 控制面组件高可用的基础架构。与 Active/Active 模式不同,Active/Passive 模式在同一时间只允许一个实例(Leader)对外提供服务,其他实例(Follower)仅作为热备等待接管。
| 对比维度 | Active/Passive 模式 | Active/Active 模式 |
|---|---|---|
| 并发执行 | 仅 Leader 执行控制循环 | 所有实例均可执行 |
| 数据一致性 | 天然避免竞态条件 | 需额外分布式锁协调 |
| 资源利用率 | 备机处于待命状态,利用率较低 | 所有实例均参与工作,利用率高 |
| 故障切换复杂度 | 简单,仅需选举新 Leader | 复杂,需处理部分失败和脑裂 |
| Kubernetes 适用场景 | kube-controller-manager、kube-scheduler | kube-apiserver(通过 etcd 一致性协议) |
3.2 Leader Election 机制
Leader Election 是 Active/Passive 模式的核心实现机制。Kubernetes 控制器管理器利用 Endpoints 或 ConfigMap 资源 作为分布式锁的载体,通过 租约(Lease) 机制在多个副本之间选举出一个 Leader。
3.2.1 选举流程
- 启动阶段: 所有控制器管理器副本启动后,均尝试在指定的命名空间(默认为
kube-system)中创建或更新一个名为kube-controller-manager的 Lease 对象。 - 竞争阶段: 每个副本定期(默认每 2 秒)尝试更新 Lease 对象,写入自己的身份信息(
holderIdentity)和续约时间戳。 - 选举成功: 第一个成功更新 Lease 对象的副本成为 Leader,开始执行控制器循环。
- 续约阶段: Leader 持续定期(默认每 2 秒)续约 Lease,更新
renewTime字段。 - 退位阶段: 当 Leader 故障或网络分区导致无法续约时,Lease 在
leaseDurationSeconds(默认 15 秒)后过期,其他副本重新发起选举。
--leader-elect-lease-duration:租约有效期,默认 15 秒。Leader 在此时间内未续约则视为失效。--leader-elect-renew-deadline:续约截止时间,默认 10 秒。Leader 必须在此时间内完成续约。--leader-elect-retry-period:重试周期,默认 2 秒。非 Leader 副本的选举重试间隔。
3.2.2 Lease 对象结构
Lease 对象存储在 etcd 中,其核心字段如下:
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
name: kube-controller-manager
namespace: kube-system
spec:
holderIdentity: "node-1_xxxxx" # 当前 Leader 的身份标识
leaseDurationSeconds: 15 # 租约有效期(秒)
acquireTime: "2025-01-15T10:00:00Z" # 获取租约的时间
renewTime: "2025-01-15T10:00:12Z" # 最近一次续约时间
leaseTransitions: 3 # 租约转移次数(Leader 变更次数)
3.3 故障转移流程
故障转移是 Active/Passive 模式保障高可用的关键环节。当 Leader 实例发生故障时,系统通过以下流程自动完成切换:
3.3.1 故障转移详细步骤
| 步骤 | 触发条件 | 执行动作 | 预期结果 |
|---|---|---|---|
| 1. 故障检测 | Leader 进程崩溃、节点宕机或网络分区 | Leader 停止续约 Lease,renewTime 不再更新 |
其他副本等待 Lease 过期 |
| 2. 租约过期 | renewTime + leaseDurationSeconds < 当前时间 |
Lease 对象进入过期状态,holderIdentity 仍指向旧 Leader |
所有副本检测到 Leader 失效 |
| 3. 选举竞争 | 副本检测到 Lease 过期 | 每个副本尝试更新 Lease 的 holderIdentity 为自己的身份 |
只有一个副本成功更新(基于 etcd 原子操作) |
| 4. 新 Leader 就职 | 成功更新 Lease 的 holderIdentity |
新 Leader 开始执行所有控制器循环,重置 acquireTime |
控制面恢复正常工作 |
| 5. 旧 Leader 恢复 | 原 Leader 进程恢复或网络重连 | 旧 Leader 检测到 Lease 已被其他副本持有,自动降级为 Follower | 不会发生脑裂,系统保持稳定 |
holderIdentity 已被修改而失败,从而自动降级为 Follower,有效防止脑裂。
3.4 高可用配置示例
以下是一个典型的高可用控制器管理器部署配置,展示了如何通过命令行参数启用 Leader Election:
# kube-controller-manager 启动参数(高可用模式)
kube-controller-manager \
--leader-elect=true \ # 启用 Leader Election
--leader-elect-lease-duration=15s \ # 租约有效期
--leader-elect-renew-deadline=10s \ # 续约截止时间
--leader-elect-retry-period=2s \ # 重试周期
--leader-elect-resource-lock=leases \ # 锁资源类型(推荐使用 leases)
--controllers=*,bootstrapsigner,tokencleaner \ # 启用的控制器列表
--kubeconfig=/etc/kubernetes/controller-manager.conf
- 始终将
--leader-elect=true设置为显式参数,避免依赖默认值。 - 使用
leases作为锁资源类型(Kubernetes v1.14+ 默认),它比 Endpoints 更轻量且语义清晰。 - 部署至少 2 个副本(通常 2~3 个),在保证高可用的同时避免过多副本造成选举竞争开销。
- 将控制器管理器部署在不同的物理节点或可用区,防止单点故障。
3.5 故障转移时间分析
故障转移的总耗时直接影响控制面的不可用时间窗口。以下表格展示了不同参数配置下的理论故障转移时间:
| 参数配置 | leaseDurationSeconds | renewDeadline | retryPeriod | 理论故障转移时间 |
|---|---|---|---|---|
| 默认配置 | 15s | 10s | 2s | ~17s(15s + 2s) |
| 快速故障转移 | 5s | 3s | 1s | ~6s(5s + 1s) |
| 保守配置 | 30s | 20s | 5s | ~35s(30s + 5s) |
- 快速故障转移: 适用于对控制面可用性要求极高的场景(如金融、实时系统),但会增加 etcd 的写入压力。
- 保守配置: 适用于网络不稳定的环境,减少因瞬时抖动导致的频繁选举,但会延长故障恢复时间。
- 默认配置: 在大多数生产环境中表现良好,平衡了故障转移速度和系统稳定性。
通过深入理解 Active/Passive 模式、Leader Election 机制和故障转移流程,运维人员可以更有效地配置和调优 Kubernetes 控制器管理器的高可用性,确保控制面在面对各种故障场景时仍能保持稳定运行。