支持 Cinder 卷多重挂载

https://blueprints.launchpad.net/nova/+spec/multi-attach-volume

目前,Nova 仅允许一个卷附加到一个实例。有时,用户可能希望能够将同一个卷附加到多个实例。

问题描述

目前 Nova 尚未准备好将单个 Cinder 卷附加到多个虚拟机实例,即使卷本身允许该操作。本文档描述了 Nova 中引入此新功能所需的更改,并列出了其限制。

用例

允许用户使用读写或只读附件在多个客户机之间共享卷。具有两个节点的集群应用程序,其中一个处于活动状态,一个处于被动状态。两者都需要访问相同的卷,尽管只有其中一个处于活动访问状态。当活动节点发生故障时,被动节点可以快速接管并访问数据。

提议的变更

Nova 中所需的更改与附加时间和分离时间相关。

只有当卷在创建时将其 ‘multiattach’ 标志设置为启用时,Cinder 才会允许该卷被附加多次。Nova 预计将依赖 Cinder 在 ‘reserve_volume’ 期间检查卷状态,遵循这些更改 [1] 这两个模块之间的交互。

在分离时,Nova 需要将 attachment_id 传递给 cinderclient,以告知 cinder 要分离哪个特定的附件。此更改是在 Mitaka 期间通过从 volume_api 获取卷信息并使用 instance_uuid 搜索附件来添加的。

除了上述更改之外,Nova 仍然需要知道何时可以安全地断开卷的连接。Cinder 计划向 Nova 提供此信息,更改将在新的 API 微版本中添加。当 Cinder 不具备所需的最低微版本时,Nova 将不支持多重附加。

默认情况下,libvirt 假定所有磁盘都由单个来宾机独占使用。如果您想在实例之间共享磁盘,则需要在配置来宾机 XML 时通过设置磁盘的 ‘shareable’ 标志来告知 libvirt。这意味着超visor 将不会尝试获取磁盘的独占锁,所有 I/O 缓存都将被禁用,并且任何 SELinux 标记都允许所有域使用。

Nova 需要为实例的多重附加磁盘设置此 ‘shareable’ 标志。只有 libvirt 驱动程序被修改以支持多重附加,对于所有其他 virt 驱动程序,此功能被禁用,信息存储在基础 ComputeDriver 的 virt 驱动程序功能字典中。如果超visor 不支持它,Nova 应该拒绝附加请求,但由于当前的 API 无法做到这一点。这可能稍后可以通过策略来解决,但作为第一步,我们将让计算节点在未运行 libvirt 的情况下失败。

由于需要将 ‘shareable’ 标志添加到来宾机 XML 以及计算节点分离的进一步可能更改,我们需要检查最小版本是否足够高以启用多重附加。

备选方案

对于上述用例,故障转移场景可以通过将卷挂载到被动/待机实例来处理。这意味着待机实例不再是热备用,因为卷挂载需要时间,这意味着在重新挂载期间,新的主实例将没有卷,这在标记主实例故障后释放卷的意义上会有所不同。

另一种选择是克隆卷并将其克隆挂载到第二个实例。缺点是原始卷的任何更改不会显示在挂载的克隆中,因此只有在卷是只读的情况下,这才是可行的选择。

数据模型影响

REST API 影响

Nova API 的某些功能需要谨慎处理或暂时禁用,以支持多重附加卷。

‘os-assisted-volume-snapshot’ API 中的创建调用会调用 ‘volume_snapshot_create’,我们无法在其中获取 instance_uuid 以检索正确的 BDM,因此我们需要为多重附加禁用此调用。此 API 格式不会更改,它只是在支持多重附加的 API 更改之前的一种保护措施。

另一个需要限制的功能是 ‘boot from volume’ (BFV)。在这种情况下,需要进一步调查两个方面。第一是 ‘delete_on_termination’ 标志,如果设置为 True,则表示在删除实例时删除附加的卷。此选项不会造成问题,因为 Cinder 会负责在仍然存在活动附件的情况下不删除卷。Nova 将从 Cinder 收到卷删除失败的错误,然后将其记录 [2],但不会影响实例终止过程。根据这一点,此标志可以与多重附加一起使用,当提供的卷具有 multiattach=True 并且传递了 delete_on_termination=True 标志用于 BFV 时,无需进行更改。

BFV 的第二个方面是启动过程。在这种情况下,唯一的问题来自可启动卷,这些卷在启动请求中指定为启动设备。为此,必须检查 ‘block_device_mapping’ 列表以过滤掉将多重附加卷指定为启动设备的情况。可以通过检查 BDM 的 ‘source_type’ 和 ‘destination_type’ 以及在 BDM 字典中搜索 ‘boot_index’: 0 项来完成。基于 BDM 信息中存储的 volume_id,可以从 Cinder 检索卷以检查 ‘multiattach’ 标志是否设置为 True,在这种情况下,请求将返回错误,表明此操作不支持多重附加卷。

对于 Nova 自身创建卷的情况,即 source_type 为 blank/image/snapshot,目前不应为该卷启用多重附加。

当我们在启动时附加卷 (BFV with source=volume,dest=volume) 时,如果选择不支持多重附加的计算节点,调度将重试。为了提高效率,稍后我们可以添加一个新的调度器过滤器来避免重复调度直到找到有效的宿主机。该过滤器将检查计算节点的功能。这被认为是一个未来的改进。

安全影响

在 libvirt 驱动程序中,磁盘被赋予共享的 SELinux 标签,因此该磁盘不再具有强大的 sVirt SELinux 隔离。

OpenStack 卷加密功能应该也适用于此用例,不应破坏加密器在集群文件系统下方的运作方式,通过为所有连接使用相同的密钥。在多个实例上附加加密卷应该在 Tempest 中进行测试,以查看是否存在任何意外问题。

通知影响

其他最终用户影响

性能影响

其他部署者影响

开发人员影响

任何时候向 Nova 添加需要调用分离卷的新代码时,开发人员必须获取实例的卷附件 UUID。此信息嵌入在 cinder 卷的 volume_attachments 列表中。

实现

基于 Walter Boring 和 Charlie Zhou 的工作。同意 Walter 重新开始工作。

负责人

主要负责人

ildiko-vancsa

工作项

  1. 更新 libvirt 驱动程序以生成具有多重挂载卷的实例的正确域 XML

  2. 在 Nova API 中提供必要的检查,以阻止上述情况中的操作

  3. 添加 Tempest 测试用例和文档

依赖项

测试

我们将需要添加新的 Tempest 测试来支持新的 Cinder 卷 multiattach 标志。新的 cinder multiattach 标志允许将卷挂载多次。例如,需要测试以下场景

  • 将同一个卷挂载到两个实例。

  • 从具有 multiattach 的卷启动

  • 具有 multiattach 的加密卷

  • 负面测试

  • 从具有 boot_index=0 的可多重挂载卷启动

  • 尝试将非 multiattach 卷挂载到多个实例

此外,Cinder 迁移需要在 gate 上进行测试,因为它会触发 Nova 中今天完全没有测试的 swap_volume。

文档影响

我们将需要更新文档以讨论将卷挂载到多个实例的新能力,如果 cinder multiattach 标志设置在卷上。还需要添加到文档中,由于 Nova 卷创建 API 的弃用,通过 API 不支持创建这些类型的卷。如果需要允许多个卷挂载,则必须在 Cinder 侧使用指定的必要属性创建卷。

还需要在文档中概述,以读写模式多次挂载卷可能会导致数据损坏,如果未正确处理。用户有责任添加某种类型的排除(在文件系统或网络文件系统层)以防止多个写入器损坏数据。如果可用,应提供示例来指导用户如何操作。

参考资料

历史

修订版

发布名称

描述

Kilo

引入

Liberty

重新批准

Mitaka-1

重新批准

Mitaka-2

已更新 API 限制和测试场景