etcd Learner成员接收快照后被意外移除的问题分析
概述
在etcd集群的运维与扩容中,使用learner(学习者)成员是一种安全实践,它允许新节点在不参与写入仲裁(Quorum)的情况下同步数据,待同步完成后再被提升为正式投票成员(voter)。然而,一个已报告的缺陷表明,在特定条件下,一个新添加的learner成员会在接收到leader的快照(snapshot)后,错误地执行了Raft配置变更逻辑,导致其自身从集群成员列表中永久移除,从而迫使该etcd进程退出。此问题直接影响集群的可靠扩容流程,需要SRE团队在规划etcd节点操作时予以高度关注,并采用正确的规避措施。
核心概念
etcd Learner 成员
Learner成员是etcd集群中的非投票成员。其主要作用是:
- 安全扩容:在不改变集群投票权重和写入仲裁的情况下,允许新节点加入并同步数据。
- 快速恢复:可作为备份节点,快速提升为投票成员以替换故障节点。
learner成员不参与
Raft协议中的投票过程,因此其故障或移除不会影响集群的写入可用性。
Raft 配置变更 (Configuration Change)
etcd使用Raft共识协议来保证集群状态的一致性。集群成员的变更(如添加、移除成员)本身也是一种需要达成共识的日志条目。Raft配置变更逻辑确保所有成员在新配置上达成一致后才正式生效。在这个问题中,关键点在于learner成员在应用从leader同步的快照时,触发的配置变更逻辑出现了异常。
实践
问题复现与现象
根据报告,问题可在以下步骤中复现:
- 在一个已有的三节点(
s1,s2,s3)etcd集群中,添加一个learner成员:etcdctl member add john7doe-learner --peer-urls=https://10.0.9.183:12380 --learner - 使用正确的配置(特别是
ETCD_INITIAL_CLUSTER_STATE=existing)启动这个新的etcd成员(john7doe-learner)。 - 新成员启动后,会从leader接收快照以同步数据。
- 异常现象:新成员在应用快照后不久,日志中会出现如下配置切换,其中
voters列表不包含该learner成员,随后进程将因“成员已被永久移除”错误而退出:
关键日志表明,在快照应用后,Raft配置被错误地更新,且未将当前learner节点自身视为集群成员。msg="57af20a01bb3d0e5 switched to configuration voters=(496505851308960826 11377229960475776118 14543006453357928869)" ... msg="the member has been permanently removed from the cluster"
根本原因与规避方法
根本原因在于etcd v3.6.8版本中,处理从leader同步过来的快照时,Raft配置变更逻辑存在缺陷。该缺陷导致快照中携带的集群配置(conf_state)被错误地应用,从而移除了learner成员自身。
有效的规避方法是在新成员启动并完全同步完成之前,立即将其提升为voter成员。报告中的操作者发现,在收到上述关键日志行之前执行etcdctl member promote,可以避免成员被移除。这改变了操作序列,使得成员在遇到有缺陷的快照应用逻辑时,其身份已经是voter,从而避免了错误路径。
# 1. 添加learner
etcdctl member add new-node --peer-urls=... --learner
# 2. 启动新etcd节点
# 3. 立即提升为voter,无需等待数据同步完成
etcdctl member promote <member-id>
SRE 要点
与可靠性、可观测性、事件响应的关联
- 可靠性:此bug直接破坏了etcd集群扩容的可靠性。一个旨在提高可用性的操作(添加learner)可能导致操作失败,甚至在自动化流程中引发连锁故障。
- 可观测性:SRE需要监控etcd集群的成员数量(
etcd_server_has_leader)和成员状态。此问题发生时,会观察到etcd_cluster_members_count指标短暂增加后立即减少,并伴随成员退出的错误日志。 - 事件响应:如果自动化扩容流程因该问题失败,事件响应应首先检查新成员的etcd日志,确认是否存在上述Raft配置切换错误。确认是此bug后,应采用规避方法(立即提升成员)重新执行操作。
最佳实践与常见反模式
- 最佳实践:
- 在升级或部署新版本的etcd(特别是3.6.x系列)前,应检查其已知问题。
- 在自动化添加learner成员的脚本中,加入短暂延迟后立即执行
member promote的步骤,作为针对此问题的防御性编程。 - 升级etcd到修复此问题的后续版本(若有)。
- 常见反模式:
- 添加learner成员后,长时间等待数据完全同步再提升。这种“等待完全同步”的理想操作模式在存在此bug的版本中会触发问题。
- 在未充分了解etcd内部机制的情况下,对错误日志(如“the member has been permanently removed from the cluster”)进行简单的重启操作,而不分析根本原因。
相关指标(SLI/SLO/SLA)
虽然此问题不直接影响SLI/SLO,但涉及集群管理操作的成功率,这可以作为SRE的运营指标。
- 相关SLI:
cluster_expansion_success_rate(集群扩容成功率)。 - 监控建议:在扩容流程中设置监控点,检查新成员是否在预期时间窗口内保持
started状态且未被移除。可以通过定期查询etcdctl member list并对比预期成员列表来实现。