etcd 3.7
运行时重配置设计
etcd 3.7 开发、运维、升级、API 与内部原理中文指南
运行时重配置是分布式系统中最为复杂且最容易出错的功能之一,尤其是在基于共识的系统(如 etcd)中。
继续阅读以了解 etcd 运行时重配置命令的设计原理,以及我们如何解决这些问题。
两阶段配置变更确保集群安全
在 etcd 中,每次运行时重配置都必须出于安全考虑,经过 两个阶段 。例如,添加成员时,需先通知集群新配置,再启动新成员。
1 - 通知集群新配置
要将成员添加到 etcd 集群,需通过 API 调用请求将新成员加入集群。这是向现有集群添加新成员的唯一方式。API 调用将在集群就配置变更达成一致后返回。
2 阶段 - 启动新成员
要将新的 etcd 成员加入现有集群,需指定正确的 initial-cluster,并将 initial-cluster-state 设置为 existing。成员启动时,会首先联系现有集群,并验证当前集群配置是否与 initial-cluster 中指定的预期配置一致。当新成员成功启动后,集群即达到预期配置。
通过将流程分为两个独立阶段,用户必须明确指定集群成员关系的变更。这实际上为用户提供了更大的灵活性,也使问题更容易理解。例如,若尝试向 etcd 集群添加一个 ID 与现有成员相同的成员,该操作将在第一阶段立即失败,且不会影响正在运行的集群。类似保护机制可防止因误操作而添加新成员。若新的 etcd 成员在集群尚未接受配置变更前尝试加入集群,该成员将不会被集群接受。
若未明确指定集群成员关系的管理流程,etcd 将面临意外的集群成员关系变更风险。例如,若 etcd 在 systemd 等初始化系统下运行,当通过成员关系 API 移除某个成员后,etcd 会被重启,并在启动时尝试重新加入集群。若 systemd 配置为在失败后重启 etcd,每当通过 API 移除成员时,此循环便会重复发生,这是不符合预期的行为。
我们预计运行时重配置应为低频操作。为确保配置安全并始终在明确控制下平稳运行,我们决定将其保持为显式且由用户驱动。
永久失去法定人数需要新建集群
如果集群永久性地丢失了多数成员,需从旧的数据目录启动新集群,以恢复之前的状态。
完全有可能强制从现有集群中移除故障成员以实现恢复。然而,我们决定不支持此方法,因为它绕过了正常的共识提交阶段,存在安全隐患。如果要移除的成员实际上并未宕机,或在同一个集群中通过不同成员强制移除,etcd 将导致集群出现分叉,且集群 ID 相同。这种情况非常危险,后续难以排查或修复。
在正确部署的情况下,永久性多数节点失联的可能性极低。但该问题严重程度足以引起特别关注。强烈建议阅读 灾难恢复文档 ,并在将 etcd 投入生产环境前,做好应对永久性多数节点失联的准备。
不要使用公共发现服务进行运行时重配置
公共发现服务仅可用于引导集群启动。如需将成员加入现有集群,请使用运行时重配置 API。
发现服务专为在云环境中引导启动 etcd 集群而设计,适用于所有成员的 IP 地址事先未知的情况。成功引导启动集群后,所有成员的 IP 地址均已被知晓。从技术上讲,此时发现服务便不再需要。
使用公共发现服务进行运行时重配置似乎是一种便捷的方式,毕竟发现服务已掌握集群的全部配置信息。然而,依赖公共发现服务会带来诸多问题:
-
它为集群的整个生命周期引入了外部依赖,而不仅仅是引导阶段。如果集群与公共发现服务之间存在网络问题,集群将受到影响。
-
公共发现服务必须在其生命周期内准确反映集群的运行时配置。该服务需提供安全机制以防止恶意行为,实现难度较高。
-
公共发现服务必须维护数以万计的集群配置。我们的公共发现服务后端尚未准备好应对此类工作负载。
要实现支持运行时重配置的发现服务,最佳选择是自行构建私有服务。
来源与许可
文档取自 pig.center · 上游文档
- 版本
- 3.7
- 许可
- CC-BY-4.0
- 来源修订
dba8dc7e1afd3f6eea300ebf9ecb67c731145f1ee7db1ca0d3ebc49508812609- 译文修订
dba8dc7e1afd3f6eea300ebf9ecb67c731145f1ee7db1ca0d3ebc49508812609