提升复制目标 (Cheesecake)

https://blueprints.launchpad.net/cinder/+spec/replication-backend-promotion

问题描述

在后端 A 故障转移到后端 B 之后,Cinder 中没有机制可以将后端 B 提升为 master 后端,以便随后复制到后端 C。我们还缺乏一些管理命令来帮助在状态不同步的情况下灾难恢复。

当前工作流程

  1. 设置复制

  2. 发生故障

  3. 故障转移

  4. 提升辅助后端

    1. 冻结后端以防止管理操作

    2. 停止 cinder volume 服务

    3. 更新 cinder.conf 将后端 A 替换为 B,将 B 替换为 C

    4. 修改数据库以将后端设置为不再处于“故障转移”状态。 此步骤是本规范所关注的。例如

      update services set disabled=0,
                          disabled_reason=NULL,
                          replication_status='enabled',
                          active_backend_id=NULL
        where id=3;
      
    5. 启动 cinder volume 服务

    6. 解冻后端

用例

我的数据中心着火了,我的主后端 (A) 被摧毁了。幸运的是,我正在将该后端复制到后端 (B)。在故障转移到后端 B 并修复数据中心后,我们安装了后端 C 作为 B 的新复制目标。

还有一种情况是,由于某种原因,复制状态与实际情况不同步。在需要云管理员在从灾难中恢复时手动调整状态和活动后端 ID 的情况下。

提议的变更

为了处理 Cinder DB 只需要与现实世界同步的情况,我们将添加以下 cinder manage 命令来重置主机的活动后端。类似于卷的 reset-state,这将只执行数据库操作。假设 cinder.conf 已经更新,并且卷服务已停止、禁用并可能冻结。管理命令将验证服务是否已停止、禁用和冻结。

cinder-manage reset-active-backend replication_status=<status> \
    <active_backend_id> <backend-host>

等同于

update services set replication_status='<status>',
                    active_backend_id='<id>',
   where host='<backend-name>';

其中 status 的默认值将为 disabled,active_backend_id 将为 None。此目标也可以是 A-A 部署中的集群。

注意:重新启用服务将由管理员负责。

这使我们能够避免管理员手动运行数据库命令,但允许在“在线”恢复中执行此操作。为了安全起见,卷服务必须处于离线状态才能工作。

进行此更改将需要驱动程序对其复制状态进行调整,并在初始化时进行调整。目前,我们对 cinder.conf 中允许更改的内容以及驱动程序对复制目标等更改的支持程度没有太多定义。存在一种隐含的约定,即当调用 __init__do_setup 时,驱动程序应该使其当前的复制状态与配置中给定的状态匹配。但是,今天这有点有问题,因为它们没有机制来更新数据库条目,例如 replication_extended_statusreplication_driver_data。为了解决这个差距,并允许这种新的官方支持的在离线状态下修改复制状态的方法,我们将引入一个新的驱动程序 api 方法

update_host_replication(replication_status, active_backend_id, volumes, groups)

此方法将在 do_setup 之后立即调用,并将返回服务的模型更新以及如果驱动程序支持复制组,则卷和组的更新列表。如果未定义,group 参数将默认为 None。

驱动程序需要能够采取适当的步骤,以基于当前的数据库状态(理论上在启动前由新的 cinder-manage 命令修改)和当前的 cinder.conf 将系统置于所需的状态。

如果未实现,事情将继续像今天一样工作,并且可能需要管理员采取更严厉的措施来在执行故障转移后恢复。这里的目标不是破坏任何现有功能,而是添加足够的 инфраструктура 以便驱动程序能够更好地工作。

当我们这样做时,我们可能需要某种 fencing 机制来防止多个 A-A 驱动程序实例同时执行设置,因为这很可能会对某些后端造成问题,并且如果多个后端同时修改复制状态,可能会导致数据丢失。作为简单的解决方案,我们可以使用一个新的 replication_status,例如 updating,用于服务,并且仅允许它们在状态未设置为该状态时调用 setup_replication。如果更新过程通过驱动程序花费明显的时间,该状态对管理员来说也很有用。

以这种方式进行也应该允许以后进行“在线”更新,我们可以利用相同的驱动程序钩子来修改复制状态。本规范和初始实现不旨在涵盖该场景。

备选方案

我们可以添加管理 API 到 Cinder。这些 API 可以执行数据库更新并 ping 驱动程序。缺点是需要 API 和卷服务处于在线状态,这在从灾难中恢复的场景中可能存在问题。

稍后我们可以研究进行“在线”提升,在这种情况下,卷服务不需要处于离线状态。驱动程序中需要类似的代码,但尝试支持它会迅速增加复杂性。

还讨论了使用新的管理 API,这些 API 将修改跟踪复制信息的数据库状态。缺点是我们将进入运行配置和状态与配置状态不匹配的场景。

沿着跟踪数据库中复制状态的路径,我们可以走向极端,并将所有复制配置都通过 API 进行。然后我们可以跟踪状态,并向驱动程序提供状态更改的差异。从长远来看,这解决了运行时与配置状态的差异,但它将是工作流程和部署的重大变化。更不用说需要对实现复制的驱动程序进行一些重大更改。

数据模型影响

将为服务/集群添加一个新的状态。

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

卷服务启动可能需要付出性能代价,具体取决于后端以及需要修改和更新的已复制卷的数量。

其他部署者影响

开发人员影响

驱动程序维护者可能需要实现此新功能,并了解如何/何时可以调整复制配置和状态的影响。

实现

负责人

主要负责人

jbernard

工作项

  • 实现 cinder-manage reset-active-backend 命令

  • 实现卷管理器更改,以便在启动时允许驱动程序使用 update_host_replication

  • 针对每个支持复制并需要作为此更改结果进行更新的后端打开一个 bug。

依赖项

测试

文档影响

管理员指南中的文档,说明如何执行后端提升,以及更新 devref,向驱动程序开发人员解释实施复制的驱动程序的期望。

参考资料