避免升级到 etcd v3.6 时出现僵尸集群成员

本文是对近期发布在官方 etcd 博客原文的镜像转载。

关键信息: 升级到 v3.6 之前,务必先升级到 etcd v3.5.26 或更高版本。这样能自动修复集群,避免僵尸成员问题。

问题概述

最近,etcd 社区解决了一个升级时可能出现的问题:当用户从 v3.5 升级到 v3.6 时,集群可能会出现“僵尸成员”。这些僵尸成员是之前从数据库集群中移除的 etcd 节点,却又重新出现并加入数据库共识。集群会因此无法正常工作,直到这些僵尸成员被再次移除。

在 etcd v3.5 及以前版本,尽管 v3store 已存在,但集群成员数据的权威来源仍是 v2store。作为 v2store 废弃计划的一部分,从 v3.6 开始,集群成员数据的权威来源变为 v3store。通过一次 bug 报告,我们发现部分老集群中 v2store 和 v3store 可能不一致。这种不一致在升级后会表现为旧的、已移除的“僵尸”成员重新出现在集群中。

解决方案和升级路径

etcd v3.5.26 已引入自动同步机制,会将 v2store 中的成员信息同步到 v3store,确保受影响的集群在升级到 3.6.x 之前得到修复。

为了支持大量正在升级到 3.6 的用户,我们建议采用以下安全升级路径:

  1. 先将集群升级到 v3.5.26 或更高版本。
  2. 等待并确认升级后所有成员状态健康。
  3. 再升级到 v3.6。

如果你由于某些限制无法升级到 v3.5.26,我们目前无法提供同等安全的替代路径。因此,如果你的包源或供应商尚未提供 v3.5.26,建议暂缓升级到 v3.6。

额外技术细节

以下信息仅供参考。即使不了解这些技术细节,也可以按前述安全路径完成升级。

该问题主要出现在长期运行 etcd v3.5.25 或更早版本的生产集群中。它是集群增删成员或故障恢复过程中的副作用。这意味着集群越老,出现问题的概率通常越高;但无论集群新旧,都不能完全排除风险。

etcd 维护者与问题报告者在分析症状、代码和日志后,总结了三个可能触发条件:

  1. etcdctl snapshot restore 的 bug(v3.4 及更早版本):使用 etcdctl snapshot restore 恢复快照时,etcdctl 本应先移除旧成员再添加新成员。v3.4 中由于 bug,旧成员未被移除,从而产生僵尸成员。详见 etcdctl 相关评论
  1. v3.5 及更早版本中使用 --force-new-cluster:在极少数情况下,强制创建新的单成员集群时未能彻底移除旧成员,导致僵尸成员残留。该问题已在 v3.5.22 修复。更多技术细节可参考 Raft 项目的 PR
  1. 启用 --unsafe-no-sync:启用该参数时,在极少数情况下 etcd 可能已将成员变更写入 v3store,但在写入 WAL 之前崩溃,从而导致 v2store 与 v3store 不一致。这对单成员集群影响更大;多成员集群若从崩溃节点数据强制创建单成员集群,也可能引入僵尸成员。

需要强调的是,除了以上三种情况外,可能还存在我们尚未发现的其他触发因素,导致 v2store 与 v3store 成员数据不一致。因此,不能因为“没有执行上述三种操作”就认为一定安全。升级到 etcd v3.6 后,v3store 成为成员数据唯一权威来源,这类不一致问题将不再发生。

想要验证 v2store 和 v3store 一致性的高级用户,可以参考这条评论中的步骤。该检测不是修复问题的必要条件,且无论检测结果如何,SIG etcd 都不建议跳过 v3.5.26 这一步升级。

关键要点

升级到 v3.6 之前,务必先升级到 v3.5.26 或更高版本。这样可以自动修复集群并避免僵尸成员问题。

致谢

感谢 Christian Baumann 报告了这一长期存在的升级问题。他的反馈和后续工作帮助我们及时定位并在上游完成修复。

参考资料

  1. 升级指南(v3.5 -> v3.6):https://etcd.io/docs/v3.6/upgrades/upgrade_3_6/
  2. v2store 废弃计划:https://github.com/etcd-io/etcd/issues/12913
  3. Bug 报告:https://github.com/etcd-io/etcd/issues/20967
  4. v3.5.26 自动同步机制:https://github.com/etcd-io/etcd/pull/20995
  5. v3.5.26 版本发布:https://github.com/etcd-io/etcd/releases/tag/v3.5.26
  6. etcdctl 相关评论:[1] https://github.com/etcd-io/etcd/issues/20967#issuecomment-3618010356
  7. Raft 项目 PR:[2] https://github.com/etcd-io/raft/pull/300
  8. 一致性检查评论:[3] https://github.com/etcd-io/etcd/issues/20967#issuecomment-3590609775
  9. Christian Baumann:https://github.com/thechristschn