支持 Cinder 卷多重挂载¶
https://blueprints.launchpad.net/nova/+spec/multi-attach-volume
当前,Nova 仅允许一个卷挂载到单个实例。有时用户可能希望能够将同一个卷挂载到多个实例。
问题描述¶
当前 Nova 尚未准备好将单个 Cinder 卷挂载到多个虚拟机实例,即使卷本身允许该操作。本文档描述了 Nova 中引入此新功能所需的更改,并列出了其限制。
用例¶
允许用户使用读写挂载在多个客户机之间共享卷,例如具有两个节点(一个活动节点和一个被动节点)的集群应用程序。两者都需要访问相同的卷,尽管只有其中一个节点主动访问。当活动节点发生故障时,被动节点可以快速接管并访问数据。
上述示例也适用于主动/主动场景,用户有责任选择合适的的文件系统。
提议的变更¶
新的“多重挂载”功能将通过使用 Cinder attach/detach API 的新版本启用,该版本在 API 微版本 3.44 中可用 [1]。
Cinder 仅在卷在创建时设置了“multiattach”标志后,才允许将卷挂载多次。Nova 预计会依赖 Cinder 在 API 级别通过调用 attachment_create 来检查卷状态。
目前,当多个卷挂载共享指向卷后端的单个目标时,存在问题 [2]。如果我们不注意,多重挂载会使这些问题变得更糟。最简单的解决方法是序列化涉及共享目标的所有挂载和卸载操作。为此,Cinder 将公开卷信息属性“shared_targets”,当为 True 时,将在所有 attachment_update 和 attachment_delete 调用以及相关的 os-brick 调用周围放置一个锁。
# The lock uses the volume.backend_uuid value.
with optional_host_local_lock(acquire=volume.shared_target):
connector = os_brick.get_connector()
conn_info = attachment.update(connector).conn_info
os_brick.connect_volume(conn_info)
attachment.attach_complete()
with optional_host_local_lock(acquire=volume.shared_target):
os_brick.disconnect_volume(conn_info)
attachment.delete()
注意
我们假设与 Cinder 相关的卸载和挂载调用是同步的,因此主机上的 os-brick 操作与后端上的 cinder 操作之间不会发生竞争。任何偏离此模式的驱动程序都将被视为错误。
默认情况下,libvirt 假定所有磁盘都由单个客户机独占使用。如果您想在实例之间共享磁盘,则需要在配置磁盘的客户机 XML 时通过设置磁盘的“shareable”标志来告诉 libvirt。这意味着超visor不会尝试获取磁盘的独占锁,所有 I/O 缓存都将被禁用,并且任何 SELinux 标记都允许所有域使用。
Nova 需要为所有挂载设置此“shareable”标志(其中“multattach”标志设置为 True)。此规范仅为 libvirt 启用此功能,所有其他驱动程序应拒绝对多重挂载卷的挂载调用,直到该驱动程序添加对此功能的的支持。该信息存储在基础 ComputeDriver 的 virt 驱动程序功能字典中,对于 Libvirt,支持 multi-attach 将为 True,对于所有其他 virt 驱动程序,此功能将被禁用。为了引入标志的使用,我们还需要提高最小计算版本。
以下策略规则将添加到 Cinder
启用/禁用 multiattach=True
启用/禁用 multiattach=True + bootable=True
如果超visor 不支持,Nova 应拒绝挂载请求,但使用当前的 API 无法做到这一点。可以通过上述策略规则部分解决此问题。例如,如果您正在运行一个包含不支持 multiattach 的计算的云,假设全部是 vmware,那么操作员可以配置策略以禁用 cinder 侧的 multiattach 卷。如果您拥有一个混合超visor 云,并且用户尝试将 multiattach 卷挂载到 virt 驱动程序不支持 multiattach 的计算上的实例,那么挂载请求将在计算上失败,nova-compute 调用 attachment_delete 以删除 nova-api 的 attach_volume 代码中创建的挂载。如果 nova-api 暴露了后端计算驱动程序功能,那么我们可以在 API 中尽早检查并失败,但 nova 目前还没有这个功能,所以我们只能依靠策略规则和后端检查。
备选方案¶
对于上述用例,故障转移场景可以通过将卷挂载到被动/待机实例来处理。这意味着待机实例不再是热备用,因为卷挂载需要时间,这意味着在重新挂载期间,新的主实例将没有卷,这在标记主实例故障后释放卷的意义上会有所不同。
另一种选择是克隆卷并将其克隆挂载到第二个实例。缺点是原始卷的任何更改不会显示在挂载的克隆中,因此只有在卷是只读的情况下,这才是可行的选择。
数据模型影响¶
无
REST API 影响¶
Nova API 的某些功能需要小心处理或暂时禁用,以支持 multi-attach 的卷。
“os-assisted-volume-snapshot”API 中的创建调用会调用“volume_snapshot_create”,我们没有 instance_uuid 来检索正确的 BDM,因此我们需要为 multi-attach 禁用此调用。此 API 格式不会更改,只是在支持 multi-attach 的情况下的一种保护措施,直到 API 更改支持此请求。
另一个需要进一步调查的功能是“从卷启动”(BFV)。该功能的第一个方面是“delete_on_termination”标志,它将允许与 multi-attach 一起使用,无需更改。当提供的卷具有 multiattach=True 并且传递了 delete_on_termination=True 标志时,BFV 就会发生这种情况。当此标志设置为 True 时,它旨在删除在删除实例时附加到实例的卷。此选项不会造成问题,因为 Cinder 会负责在仍然存在活动挂载的情况下不删除卷。Nova 将从 Cinder 收到卷删除失败的错误,该错误将在 API 的“_local_delete”中记录 [3] [4],但不会影响实例终止过程。
BFV 的第二个方面是启动过程。在这种情况下,Nova 仅检查“bootable”标志。策略检查发生在 Cinder 侧,以允许它与 multiattach 结合使用或不使用。
对于 Nova 本身创建卷的情况,即 source_type 为 blank/image/snapshot,它不应为卷启用 multi-attach,即现在无需更改现有代码。
当我们在启动时挂载卷(BFV with source=volume,dest=volume)时,如果选择不支持 multi-attach 的计算,则调度将失败。稍后我们可以添加一个新的调度程序过滤器来避免失败。过滤器将检查计算功能。此步骤被认为是未来的改进。
当启用该功能时,我们将拥有一个“multiattach”策略,以如上所述在 Cinder 侧完全启用或禁用该操作。只读策略是一项未来的工作项目,不在此规范的范围内。
将添加一个新的计算 API 微版本,因为用户需要某种方式来发现他们是否可以执行卷多重挂载。该微版本的语义将类似于 2.49 微版本,用于标记挂载。
安全影响¶
在 libvirt 驱动程序中,磁盘被赋予共享的 SELinux 标签,因此该磁盘不再具有强大的 sVirt SELinux 隔离。
OpenStack 卷加密功能应该也适用于此用例,不应破坏加密器在集群文件系统下方的运作方式,通过为所有连接使用相同的密钥。在多个实例上附加加密卷应该在 Tempest 中进行测试,以查看是否存在任何意外问题。
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
无
实现¶
基于 Walter Boring 和 Charlie Zhou 的工作。同意 Walter 重新开始工作。
负责人¶
- 主要负责人
ildiko-vancsa
工作项¶
更新 libvirt 驱动程序以生成具有多重挂载卷的实例的正确域 XML
在 Nova API 中提供必要的检查,以阻止上述列出的情况中的操作
添加 Tempest 测试用例和文档
依赖项¶
这需要 python-cinderclient 的 3.2.0 或更高版本。相应的蓝图:https://blueprints.launchpad.net/python-cinderclient/+spec/multi-attach-volume
Cinder 中实现的相应规范:https://blueprints.launchpad.net/cinder/+spec/multi-attach-volume
需要链接到 Cinder 规范,以解决当前在此处捕获的卸载问题:https://etherpad.openstack.org/p/cinder-nova-api-changes
测试¶
我们将需要添加新的 Tempest 测试来支持新的 Cinder 卷 multiattach 标志。新的 cinder multiattach 标志允许将卷挂载多次。例如,需要测试以下场景
将同一个卷挂载到两个实例。
从具有 multiattach 的卷启动
具有 multiattach 的加密卷
从具有 boot_index=0 的可多重挂载卷启动
负面测试
尝试将非 multiattach 卷挂载到多个实例
此外,Cinder 迁移需要在 gate 上进行测试,因为它会触发 Nova 中的 swap_volume。
文档影响¶
我们将需要更新文档以讨论将卷挂载到多个实例的新能力,如果 cinder multiattach 标志设置在卷上。还需要添加到文档中,由于 Nova 卷创建 API 的弃用,通过 API 不支持创建这些类型的卷。如果需要允许多个卷挂载,则必须在 Cinder 侧使用指定的必要属性创建卷。
还需要在文档中概述,以读写模式多次挂载卷可能会导致数据损坏,如果未正确处理。用户有责任添加某种类型的排除(在文件系统或网络文件系统层)以防止多个写入器损坏数据。如果可用,应提供示例来指导用户如何操作。
参考资料¶
这是 Cinder wiki 页面,讨论了 multi-attach 的方法 https://wiki.openstack.org/wiki/Cinder/blueprints/multi-attach-volume
Queens PTG etherpad:https://etherpad.openstack.org/p/cinder-ptg-queens-thursday-notes
历史¶
发布名称 |
描述 |
|---|---|
Kilo |
引入 |
Liberty |
重新批准 |
Mitaka-1 |
重新批准 |
Mitaka-2 |
已更新 API 限制和测试场景 |
Newton |
重新批准 |
Queens |
重新提出 |