Bare Metal Service Upgrade Guide

本文档概述了运营商在从 OpenStack 早期版本升级 ironic 驱动的云环境时需要考虑的各种步骤和注意事项。

Bare Metal (ironic) 服务与 Compute (nova) 服务中提供的 ironic 驱动程序紧密耦合。在升级云环境时,必须考虑一些特殊事项。

支持离线升级和滚动升级。

规划您的升级

  • 从 Pike 版本开始,支持滚动升级;也就是说,从 Ocata 升级时。这意味着可以进行升级,Bare Metal API 的停机时间最少或没有停机时间。

  • 仅支持两个连续命名版本之间的升级。这意味着您不能直接从 Ocata 升级到 Queens;您需要先升级到 Pike。

  • 在升级 Bare Metal 服务时,应始终仔细阅读 发行说明。其中记录了具体的升级步骤和注意事项。

  • 应始终先升级 Bare Metal 服务,然后再升级 Compute 服务。

    注意

    nova 中的 ironic virt 驱动程序始终使用 ironic REST API 的特定版本。此 API 版本可能是与同一开发周期中引入的版本,因此首先升级 nova 可能会导致 nova 无法使用 Bare Metal API。

  • 备份您的数据库。Ironic 不支持数据库降级。因此,如果升级失败,从备份恢复数据库是唯一的选择。

  • 在开始升级之前,最好确保所有节点都已达到或处于稳定的 provision_state。处于具有长时间运行进程的状态(例如部署或清理)的节点可能会失败,并且可能需要手动干预才能将其返回到可用的硬件池。在发生超时或服务异常终止的情况下,这种情况最有可能发生。有关详细说明状态和可能状态转换的示意图,请参阅 Bare Metal State Machine

离线升级

在离线(或冷)升级中,由于所有服务都需要关闭,因此升级期间 Bare Metal 服务不可用。

在升级 Bare Metal 服务时,应始终按以下步骤执行

  1. 升级 ironic-python-agent 镜像

  2. 更新 ironic 代码,无需重启服务

  3. 通过 ironic-dbsync upgrade 运行数据库模式迁移

  4. 重启 ironic-conductor 和 ironic-api 服务

完成以上操作后,执行以下操作

  • 更新任何适用的配置选项,以停止使用任何已弃用的功能或选项,并执行过渡到替代方案所需的任何工作。所有已弃用的功能和选项将在一个发布周期内得到支持,因此应在执行下一次升级之前将其删除。

  • 升级 python-ironicclient 以及任何将 Bare Metal 服务作为客户端连接的其他服务,例如 nova-compute

  • 运行 ironic-dbsync online_data_migrations 命令,以确保应用数据迁移。该命令允许您使用 --max-count 选项限制数据迁移的影响,该选项限制每次运行执行的迁移数量。您应在升级后尽快完成所有迁移。

    警告

    在完成当前版本的迁移之前,您将无法启动到下一个版本的升级。例如,在从 Ocata 升级到 Pike 的过程中,您需要完成 Pike 的数据迁移。如果未完成此操作,您将无法升级到 Queens——将无法执行 Queens 的数据库模式更新。

滚动升级

为了减少停机时间,可以以滚动方式升级服务,这意味着一次升级一个或几个服务,以最大限度地减少影响。

从 Pike 版本开始,支持滚动升级。此功能使得在发布之间进行升级(例如从 Ocata 到 Pike)成为可能,Bare Metal API 的停机时间最少或没有停机时间。

需求

为了促进滚动升级,您需要具有高可用性部署,包括至少两个 ironic-api 服务和两个 ironic-conductor 服务。建议使用负载均衡器在 ironic-api 服务之间平衡请求,因为它允许对最终用户产生最小的影响。

概念

在滚动升级过程中,需要注意四个方面

  • API 和 RPC 版本固定,以及版本化的对象回溯

  • 在线数据迁移

  • 优雅的服务关闭

  • API 负载均衡器排空

API 和 RPC 版本固定以及版本化的对象回溯

通过仔细的 RPC 版本控制,较新的服务能够与旧的服务进行通信(反之亦然)。为此使用 [DEFAULT]/pin_release_version 配置选项。应将其设置为旧服务正在使用的发布版本。较新的服务将回溯 RPC 调用和对象到从固定发布版本中的相应版本。如果发生 IncompatibleObjectVersion 异常,很可能是由于不正确或未指定的 [DEFAULT]/pin_release_version 配置值造成的。例如,当 [DEFAULT]/pin_release_version 未设置为旧版本时,升级期间不会发生任何转换。

对于 ironic-api 服务,API 版本通过与上述相同的 [DEFAULT]/pin_release_version 配置选项固定。固定后,新的 ironic-api 服务将不会服务任何高于旧 ironic-api 服务支持的 Bare Metal API 版本的 API 请求。对于此类请求,将返回 HTTP 状态码 406。这可以防止在升级完成之前使用新功能(在新的 API 版本中可用)。例如,如果您正在从 Ocata 升级到 Pike,请将此值设置为 ocata

在线数据迁移

为了使数据库模式迁移执行起来不那么痛苦,我们实施了流程更改以促进升级。

  • 所有数据迁移都禁止在模式迁移脚本中进行。

  • 模式迁移脚本仅更新数据库模式。

  • 数据迁移必须在滚动升级过程结束时完成,在模式迁移之后以及服务升级到最新版本之后。

所有数据迁移都使用 ironic-dbsync online_data_migrations 命令执行。它可以作为后台进程运行,因此不会中断正在运行的服务;但是,必须完成它才能进行冷升级,如果目的是立即使用新功能。

(如果您正在执行冷升级,您也会在关闭服务时执行相同的命令)。

必须完成此数据迁移。否则,您将无法升级到未来的版本。例如,如果您已从 Ocata 升级到 Pike 但未执行数据迁移,则将无法从 Pike 升级到 Queens。(更准确地说,您将无法应用 Queens 的模式迁移)。

优雅的 Conductor 服务关闭

ironic-conductor 服务是一个 Python 进程,监听消息队列上的消息。当操作员向该进程发送 SIGTERM 信号时,该服务停止从队列中消费消息,因此不会获取任何其他工作。它完成任何未完成的工作,然后终止。在此过程中,消息可能会留在队列中,并在 Python 进程重新启动后进行处理。这使我们能够使用较旧的代码关闭服务,并使用较新的代码启动服务,从而最大限度地减少影响。

注意

这使用 RabbitMQ 消息传递后端进行了测试,可能因其他后端而异。

正在被 ironic-conductor 进程处理的节点(未处于稳定状态)将在达到 conductor.graceful_shutdown_timeout 时进入失败状态。升级期间发生的节点故障可能是由于超时造成的,这是由于涉及在长时间运行的多步骤过程(例如部署或清理)期间处理和处理消息的延迟造成的。

Conductor 服务关闭排空

排空关闭类似于优雅关闭,不同之处在于:

DEFAULT.drain_shutdown_timeout 设置足够长,以便任何处于不稳定状态的节点都有时间达到稳定状态(完成或失败)后,ironic-conductor 进程才会终止。

API 负载均衡器排空

如果您正在为 ironic-api 服务使用负载均衡器,我们建议您将请求重定向到新的 API 服务,并从尚未升级的 ironic-api 服务中排空。

滚动升级过程

维护窗口之前

  • 升级 ironic-python-agent 镜像

  • 使用新版本(ironic 代码),通过运行数据库升级命令执行所需的数据库模式更新:ironic-dbsync upgrade。这些模式更改操作应对性能影响最小或没有影响,并且不应导致任何操作失败(但请检查发行说明)。您可以

    • 在现有系统上安装新版本

    • 在新 virtualenv 或容器中安装新版本

    此时,数据库中可能存在新的列和表。这些数据库模式更改以一种方式完成,即旧版本和新版本(N 和 N+1)可以对相同的模式执行操作。

注意

Ironic 基于 [DEFAULT]/pin_release_version 配置选项来确定其 API、RPC 和对象存储格式版本。建议自动部署配置文件的更改,以减少错误并使流程可重复。

维护窗口期间

  1. 应首先升级所有 ironic-conductor 服务。确保始终至少运行一个 ironic-conductor 服务。对于每个 ironic-conductor,一次一个或几个

    • 关闭该服务。来自 ironic-api 服务到 conductor 的消息由消息队列和哈希环进行负载均衡,因此您需要担心的是以优雅的方式关闭服务(使用 SIGTERM 信号)以确保在关闭之前完成正在处理的所有请求。

    • 升级 ironic 及其依赖项的版本

    • [DEFAULT]/pin_release_version 配置选项的值设置为您正在升级的版本(即旧版本)。基于此设置,新的 ironic-conductor 服务将降级任何 RPC 通信和数据对象以符合旧服务。例如,如果您正在从 Ocata 升级到 Pike,请将此值设置为 ocata

    • 启动该服务

  2. 下一个要升级的服务是 ironic-api。确保始终至少运行一个 ironic-api 服务。您可能希望启动旧的 ironic-api 的另一个临时实例来处理负载,同时升级原始 ironic-api 服务。对于每个 ironic-api 服务,一次一个或几个

    • 在 HA 部署中,它们通常在负载均衡器(例如 HAProxy)后面运行,因此您需要将服务实例从负载均衡器中移除

    • 关闭它

    • 升级 ironic 及其依赖项的版本

    • [DEFAULT]/pin_release_version 配置选项的值设置为您正在升级的版本(即旧版本)。基于此设置,新的 ironic-api 服务将降级任何 RPC 通信和数据对象以符合旧服务。此外,新的服务将为任何具有新 API 版本(旧服务不支持)的请求返回 HTTP 状态码 406。这可以防止在升级完成之前使用新功能(在新的 API 版本中可用)。例如,如果您正在从 Ocata 升级到 Pike,请将此值设置为 ocata

    • 重启服务

    • 将其重新添加到负载均衡器

    在升级所有 ironic-api 服务后,Bare Metal 服务将以新版本运行,但 RPC 通信和数据库对象存储格式将被降级。 新功能(在新 API 版本中)不受支持,因为当对象处于降级对象格式时,它们可能会失败,并且一些内部 RPC API 函数可能仍然不可用。

  3. 对于所有 ironic-conductor 服务,一次一个

    • 移除 [DEFAULT]/pin_release_version 配置选项设置

    • 重启 ironic-conductor 服务

  4. 对于所有 ironic-api 服务,一次一个

    • 移除 [DEFAULT]/pin_release_version 配置选项设置

    • 重启 ironic-api 服务

维护窗口之后

现在所有服务都已升级,系统能够使用最新版本的 RPC 协议,并能够访问新版本的所有功能。

  • 更新任何适用的配置选项,以停止使用任何已弃用的功能或选项,并执行任何必要的工作以过渡到替代方案。 所有已弃用的功能和选项将在一个发布周期内得到支持,因此应在执行下一次升级之前将其删除。

  • 升级 python-ironicclient 以及其他连接到 Bare Metal 服务的客户端服务,例如 nova-compute

    警告

    一个 nova-compute 实例在启动时尝试将 VIF 附加到所有活动实例。 确保对于所有活动节点,至少有一个正在运行的 ironic-conductor 进程来管理它们。 否则,在 nova-compute 启动时,实例将被移动到 ERROR 状态。

  • 运行 ironic-dbsync online_data_migrations 命令,以确保应用了数据迁移。 该命令允许您使用 --max-count 选项限制数据迁移的影响,该选项限制每次运行中执行的迁移数量。 您应在升级后尽快完成所有迁移。

    警告

    请注意,在完成当前版本的迁移之前,您将无法启动到下一个版本的升级。 例如,作为从 Ocata 到 Pike 的升级的一部分,您需要完成 Pike 的数据迁移。 如果未完成此操作,您将无法升级到 Queens – 将无法执行 Queens 的数据库模式更新。