最小停机时间升级
- Launchpad 条目: NovaSpec:upgrade-with-minimal-downtime
- 创建:
- 贡献者:
总结
云预计始终可用,并且涉及大量的服务器。在这里,我们考虑如何执行升级,以最大限度地减少中断。
升级的目标是
- 在可能的情况下,对云用户透明
- 最小的实例停机时间或实例连接丢失
- 如果出现故障,能够回滚到升级前的状态
- 能够从 v2 升级到 v4,而无需先升级到 v3
- * 需要确定我们对版本的含义
- * 目前将是 2012.1 -> 2012.2
- * 对于 sprint 版本或对主要版本的 bug 修复如何处理 (http://summit.openstack.org/sessions/view/106)
发布说明
TODO
用户故事
考虑执行升级的不同可能方式…
大爆炸升级
要执行升级,您可以尝试这种方法
- 在新的云旁边构建一个更新的云
- 配置好它
- 使旧云变为只读
- 将状态复制到新的云
- 迁移到使用新的云
这种方法会导致过多的停机时间
滚动升级
这种方法涉及逐步升级系统的每个组件,最终为您提供一个运行在新版本上的云。
虽然这更复杂,但我们应该能够使每个组件的停机时间最小化,并利用 OpenStack 中内置的依赖性,我们应该能够实现零停机时间,但某些操作可能比平时稍长。
执行这种升级的关键方法有两种
- 每个组件的原地升级
- 每个组件的替换/并排升级
原地升级
原地升级需要每个服务在升级期间停止运行。这可能会使回滚更加困难。
因此,目前我将忽略这种方法,除非是在升级 hypervisor 的情况下。在进行 hypervisor 升级时,可以在实时迁移实例后将节点从云中移除,而不会影响云的整体可用性。在节点不可用期间,您只会看到容量略有减少。
并排升级
并排升级涉及对每个服务执行以下过程
- 配置新的工作节点
- 关闭旧的工作节点
- * 允许消息队列或负载均衡器隐藏此停机时间
- 快照/备份旧的工作节点以进行回滚
- 将任何状态复制/移动到新的工作节点
- 启动新的工作节点
- 对所有其他工作节点重复此操作,顺序适当
这种方法的优点似乎是
- 潜在的更轻松的回滚
- 潜在的组件停机时间更短
- 在 VM 中部署 nova 时效果很好
- 更容易测试,因为系统处于已知状态(或 VM 镜像)
前提条件
如果我们采用并排滚动升级,以下是我们对 OpenStack 的假设。
向后兼容的 Schema
为了实现 nova 组件的滚动升级,我们需要确保 OpenStack 的所有组件之间的通信在不同版本之间有效(至少,两个版本向后兼容)。
需要考虑的是
- 数据库 schema
- 消息队列消息
- 通知消息
- OpenStack API 兼容性(当不同区域处于不同版本时)
例如,为了避免需要新版本的代码来处理旧版本的数据库,我们应该假设数据库将首先升级。但是,如果所有新版本都可以使用旧数据库,我们可以在最后升级数据库(以非向后兼容的方式)。
使用主机标志中的 GUID 和 IP 别名在主机之间迁移服务
考虑使用 GUID 而不是主机名来标识数据库和消息队列名称中的服务。这可以通过在主机标志中指定 GUID 来实现当前系统。
使用与关联 IP 别名一起的 GUID,应该允许 Compute(以及类似组件)在两个不同主机之间平滑迁移(尤其是在并排升级期间)。
由于可以关闭旧主机并启动具有与旧主机相同身份的新主机,因此可以最大限度地减少停机时间(无需等待 rpm 升级完成)。它还使您能够根据需要更轻松地按需扩展云,因为您可以更轻松地将工作节点迁移到不同的主机。
实时迁移
在升级 hypervisor 时,理想情况下,实例应该实时迁移到另一个主机,以便可以升级主机,而运行在该主机上的实例不会出现停机时间。
如果没有实时迁移支持,实例将丢失(终止),或在 hypervisor 升级期间暂停。
设计
为了确保平稳升级,我们需要能够支持服务的优雅关闭
服务的优雅关闭
我们需要确保在停止服务时,我们可以让服务停止从消息队列获取新消息,并完成尚未完成的任何当前请求。
这将在关闭旧服务执行升级或出于维护原因重新启动主机时有所帮助。消息队列应确保系统在短时间停机期间不会丢失任何请求。
可能的升级流程
我们专注于 nova 组件的并排滚动升级。
假设数据库始终向后兼容,我们可能应该按以下顺序升级组件
- 更新到最新的数据库 Schema
- 升级 MessageQueue 或数据库(如果需要)
- 升级:Scheduler、Glance、Keystone
- 升级:Volume、Network
- 升级:Compute
- 升级:Nova API
现在我们可以查看每个 nova 组件,以最大限度地减少升级期间的停机时间。请注意,这尚未经过测试。
nova-compute
- 创建新的 compute 工作节点
- 配置新的 compute 工作节点以替换旧的工作节点
- * 这是通过使用与旧工作节点相同的 GUID 在主机标志中完成的
- 优雅地停止旧的 compute 服务
- * 停止从队列获取
- * 允许所有操作完成
- 启动新的 compute 服务
- 关闭旧机器,现在新的服务正在运行
nova-scheduler
- 创建新的 scheduler 工作节点主机
- 优雅地停止旧服务
- * 停止从队列获取
- * 允许所有操作完成
- 启动新的 scheduler 服务
- 清理 Message Queue 中的旧队列
- * 我们可以使用 GUID 主机标志来避免这种情况
- * 但是看起来旧队列反正没有被使用?
nova-api
与 scheduler 类似的方法
- 启动新的 api 主机
- 配置新的 api 服务并启动新的 api 服务
- * 注意:我们假设不需要对 keystone 进行更改(只需要外部端点列出吗?)
- 重新配置负载均衡器,或将 IP 别名移动到新机器
- 等待请求开始由新的 API 提供服务,并且上述更改得到正确应用
- 优雅地停止旧服务(完成所有当前请求)
- * 停止从队列获取
- * 允许所有操作完成
- 关闭旧主机
dashboard
前提条件
- 数据库不重要(只是存储会话?),可以在新主机上重新创建
- 在切换期间会丢失会话,除非通过负载均衡器缓解(使用 Citrix NetScalar 的优雅关闭,或类似方式)
方式
- 遵循与 nova-api 相同的步骤
nova-volume
这取决于您使用的存储类型。
TODO - 尚未完成此操作。
iSCSI
有几种方法
- 终止使用 iSCSI 的实例
- * 只是将 iSCSI 目标重新映射到新主机
- * 卷被标记为分离,并可供新实例再次使用
- 保持 iSCSI 目标静态
- * 确保它保持不变,使用 IP 别名和 GUID 样式的hostname。
- * 在旧服务优雅关闭后,将卷磁盘从旧 VM 复制到新 VM
- * 问题:hypervisors 在 iSCSI 短时间不可用时是否可以正常工作,我们是否可以轻松恢复?
XenServer 存储管理器
问题
- 所有状态都是外部的,不需要在旧主机和新主机之间移动磁盘
- 使用 guid hostname,以便旧主机和新主机具有相同的身份,停机时间很短,因为新的实例被启动
- 或者以混乱的方式重新映射数据库中的条目
总体方法应与 compute 类似。
nova-network
这取决于网络模型
Flat 模型
方式
- 使用与 nova-scheduler 相同的方法
- 在主机标志上使用 GUID
VLAN 模型
想法
- 在可能的情况下,每个 compute 应该有自己的网络,以限制任何停机时间的影响(新的网络 HA 样式)
- 查看使用 Network HA 主/被动对来限制连接停机时间(使用网关的虚拟 IP,以便实例不会注意到)
glance-api
方式
- 与 nova-api 类似
glance-registry
前提条件
- 在每个 glance-api 节点上部署一个吗?
- 通常的数据库问题
方式
- 新的 api 节点与新的 registry 通信
- 旧的 api 节点与旧的 registry 通信
- 可能每个 api 都有自己的,与中央 DB 通信
实现
TODO
UI 变更
代码变更
迁移
测试/演示计划
我们需要一个持续集成系统来检查 trunk 是否可以从以前发布的版本升级。
未解决的问题
我们需要解决的一些事情
- 就新旧数据库 schema 和消息队列消息之间的向后兼容性达成决定。
- 确定将升级哪些版本(仅次要版本,任何里程碑版本,任何修订版,对主要版本的 bug 修复)