让管理节点共享一致的集群状态
SwarmKit 的管理节点通过 Raft 复制状态,leader 负责将更新提案纳入一致日志。
相关概念
工程问题#
多个 manager 必须对服务、任务和集群配置保持一致;某个管理节点失效后,后续 leader 还要保留已提交更新。
实际实现#
SwarmKit 在 etcd Raft 上实现持久化、RPC 与成员变更。提交后的日志驱动状态存储,调度器等写入组件在 leader 上运行。
处理流程#
- 选举 leader 并维持任期
- leader 提交状态更新提案
- 复制日志并等待法定多数确认
- 提交后应用到状态机
源码片段#
固定版本 · 原文摘录manager/state/raft/raft.go1fd637ba5cc32ff30d1dd2bdb14997bd4f424b46 · L1890–L1905
1890func (n *Node) processCommitted(ctx context.Context, entry raftpb.Entry) error {1891 // Process a normal entry1892 if entry.Type == raftpb.EntryNormal && entry.Data != nil {1893 if err := n.processEntry(ctx, entry); err != nil {1894 return err1895 }1896 }18971898 // Process a configuration change (add/remove node)1899 if entry.Type == raftpb.EntryConfChange {1900 n.processConfChange(ctx, entry)1901 }19021903 n.appliedIndex = entry.Index1904 return nil1905}Node.processCommitted
已经提交的 Raft 日志按类型分发:普通条目进入 processEntry 应用状态,成员变更进入 processConfChange,随后推进 appliedIndex。多数派确认、任期与日志复制由上游 Raft 状态机处理,此片段是 SwarmKit 与应用状态衔接的边界。
收益与取舍#
工程分析带来的收益
- 已提交状态可以跨 leader 更替保留
- 把状态一致性与管理逻辑组合起来
付出的代价
- 工程分析:写入受复制通信和持久化影响
- 无法形成多数时不能继续提交正常更新
可比较的选择
单 manager 存储实现和通信更简单,但缺少多节点故障切换能力。
版本与适用范围#
对应 Docker Swarm 使用的 SwarmKit manager 控制面;普通单机 docker run 不经过此共识流程。
参考来源#
源码、官方文档与原始论文01
SwarmKit · Raft design
官方文档1fd637ba5cc32ff30d1dd2bdb14997bd4f424b46design/raft.md · Raft implementation / Role of the leader