文档版本 v3.7-DRAFT 处于 草稿 状态。如需获取最新的稳定版文档,请参阅 v3.6。
将 etcd 从 2.3 升级到 3.0
在一般情况下,从 etcd 2.3 升级到 3.0 可以实现零停机的滚动升级:
- 逐个停止 etcd v2.3 进程,并将其替换为 etcd v3.0 进程
- 在所有 v3.0 进程运行后,v3.0 中的新功能即可供集群使用
在开始升级之前,请通读本指南其余部分以做好准备。
升级检查清单
注意: 当从 v2 迁移且没有 v3 数据时,如果 etcd 从现有快照恢复但不存在 v3 的 ETCD_DATA_DIR/member/snap/db 文件,etcd 服务器 v3.2+ 将会 panic。这种情况发生在服务器已从 v2 迁移但之前没有 v3 数据时。这也防止了意外的 v3 数据丢失(例如 db 文件可能已被移动)。etcd 要求只有在存在 v3 数据的情况下才能进行后续的 v3 版本迁移。在 v3.0 服务器包含 v3 数据之前,请勿升级到更新的 v3 版本。
升级要求
要将现有的 etcd 部署升级到 3.0,运行中的集群版本必须为 2.3 或更高。如果低于 2.3,请先升级到 2.3,然后再升级到 3.0。
此外,为了确保滚动升级顺利进行,运行中的集群必须处于健康状态。在继续之前,请使用 etcdctl cluster-health 命令检查集群的健康状况。
准备工作
在升级 etcd 之前,务必先在预演环境中测试依赖 etcd 的服务,然后再将升级部署到生产环境。
在开始之前,备份 etcd 数据目录。如果升级过程中出现问题,可以使用此备份降级回现有的 etcd 版本。
混合版本
升级期间,etcd 集群支持不同版本的 etcd 成员共存,并以最低公共版本的协议运行。只有当所有成员都升级到 3.0 版本后,集群才被视为完成升级。内部而言,etcd 成员之间会相互协商以确定整体集群版本,该版本控制着报告的版本和所支持的功能。
限制
当总数据量大于 50MB 时,新升级的成员可能需要最多 2 分钟才能追上现有集群。可以通过检查最近快照的大小来估算总数据量。换句话说,在升级每个成员之间最好等待 2 分钟以确保安全。
对于更大的总数据量(100MB 或以上),这个一次性过程可能需要更长时间。对于如此大规模的大型 etcd 集群的管理员,可以在升级前联系etcd 团队,我们将很乐意提供升级流程建议。
Downgrade
如果所有成员都已升级到 v3.0,集群将升级到 v3.0,此时无法再降级。然而,如果仍有任意一个成员是 v2.3,则整个集群及其操作仍保持为“v2.3”状态,此时可以从这种混合状态恢复到在所有成员上使用 v2.3 的 etcd 二进制文件。
请备份所有 etcd 成员的数据目录,以便即使集群已完成升级后仍能进行降级。
升级流程
本示例详细说明了在本地机器上运行的三成员 v2.3 etcd 集群的升级过程。
1. 检查升级要求。
集群是否健康且运行的是 v2.3.x?
$ etcdctl cluster-health
member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379
member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379
member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379
cluster is healthy
$ curl http://localhost:2379/version
{"etcdserver":"2.3.x","etcdcluster":"2.3.8"}
2. 停止现有的 etcd 进程
每当一个 etcd 进程停止时,集群中的其他成员会记录预期的错误日志。这是正常现象,因为集群成员之间的连接已(临时)中断。
2016-06-27 15:21:48.624124 E | rafthttp: failed to dial 8211f1d0f64f3269 on stream Message (dial tcp 127.0.0.1:12380: getsockopt: connection refused)
2016-06-27 15:21:48.624175 I | rafthttp: the connection with 8211f1d0f64f3269 became inactive
此时最好备份 etcd 数据目录,以便在出现问题时提供降级路径:
$ etcdctl backup \
--data-dir /var/lib/etcd \
--backup-dir /tmp/etcd_backup
3. 替换为 etcd v3.0 二进制文件并启动新的 etcd 进程
新的 v3.0 etcd 将向集群发布其信息:
09:58:25.938673 I | etcdserver: published {Name:infra1 ClientURLs:[http://localhost:12379]} to cluster 524400597fb1d5f6
通过新的 v3.0 etcd 二进制文件验证每个成员以及整个集群是否变为健康状态:
$ etcdctl cluster-health
member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379
member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379
member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379
cluster is healthy
在所有成员完成升级前,已升级的成员会记录如下警告。这是正常现象,待所有 etcd 集群成员均升级至 v3.0 后,警告将消失:
2016-06-27 15:22:05.679644 W | etcdserver: the local etcd version 2.3.7 is not up-to-date
2016-06-27 15:22:05.679660 W | etcdserver: member 8211f1d0f64f3269 has a higher version 3.0.0
4. 对所有其他成员重复步骤 2 到步骤 3
5. 完成
当所有成员都升级完成后,集群将报告成功升级至 3.0:
2016-06-27 15:22:19.873751 N | membership: updated the cluster version from 2.3 to 3.0
2016-06-27 15:22:19.914574 I | api: enabled capabilities for version 3.0.0
$ ETCDCTL_API=3 etcdctl endpoint health
127.0.0.1:12379 is healthy: successfully committed proposal: took = 18.440155ms
127.0.0.1:32379 is healthy: successfully committed proposal: took = 13.651368ms
127.0.0.1:22379 is healthy: successfully committed proposal: took = 18.513301ms
进一步考虑
- etcdctl 环境变量已更新。如果
ETCDCTL_API=2 etcdctl cluster-health正常工作,但ETCDCTL_API=3 etcdctl endpoints health返回Error: grpc: timed out when dialing,请确保使用新的变量名。
已知问题
- 如果使用 Go > v1.7 构建,etcd < v3.1 将无法正常工作。更多信息请参见 Issue 6951。
- 如果在 etcd 服务器日志中出现类似
transport: http2Client.notifyError got notified that the client transport was broken unexpected EOF.的错误,请确保 etcd 是预构建版本,或使用(etcd v3.1+ 与 go v1.7+)或(etcd <v3.1 与 go v1.6.x)构建的版本。 - 升级期间不支持向 v2.3 集群添加 v3 节点,否则可能引发崩溃。更多信息请参见 问题 7249。etcd 成员的混合版本仅在 v3 迁移期间允许。请在完成升级后再进行任何成员变更。