使用扩展卷完成操作¶
https://blueprints.launchpad.net/nova/+spec/assisted-volume-extend
该蓝图建议使用 Cinder 中提出的 os-extend_volume_completion 卷操作 [3],以便在处理 volume-extended 外部服务器事件时提供成功或失败的反馈。
问题描述¶
Cinder 中的许多基于 remotefs 的卷驱动程序使用 qemu-img resize 命令来扩展卷文件。但是,当卷附加到客户机时,QEMU 将锁定该文件,并且 qemu-img 将无法调整其大小。
在这种情况下,只有持有锁定的 QEMU 进程才能调整卷的大小,这可以通过 QEMU 监视器命令 block-resize 触发。
目前,Cinder 没有足够的方法来使用此功能,因此 NFS、NetApp NFS、Powerstore NFS 和 Quobyte 卷驱动程序都禁用了扩展已挂载卷的功能。
用例¶
作为用户,我希望在卷附加到实例时扩展 NFS/NetApp NFS/Powerstore NFS/Quobyte 卷,并且希望卷的大小和状态反映操作的成功或失败。
提议的变更¶
Nova 的 libvirt 驱动程序在处理 volume-extended 外部服务器事件时使用 block-resize 命令,以告知 QEMU 附加卷的大小已更改。原则上,它也可以扩展卷文件,但目前无法向 Cinder 提供操作成功的反馈。
目前,Cinder 仅在完成扩展操作并重置卷状态从 extending 回到 in-use 后,才会向 Nova 发送 volume-extended 外部服务器事件。
借助 [3],Cinder 将允许卷驱动程序延迟完成扩展操作,并将卷状态保留为 extending,直到它发送了 volume-extended 事件并从 Nova 接收到反馈,即 os-extend_volume_completion 卷操作,其中包含一个 error 参数,指示是完成还是回滚操作。
目前,这只会影响上述提及的卷驱动程序,所有这些驱动程序之前都不支持在线扩展。所有其他驱动程序将继续在完成操作并重置为 in-use 状态后发送 volume-extended 事件,并且不会期望 os-extend_volume_completion 卷操作。
计算代理¶
Nova 的计算代理将在处理 volume-extended 事件时,使用卷状态来区分这两种行为
如果卷状态为
extending,则它将尝试从卷的元数据中读取extend_new_size,并使用此值作为卷的新大小,而不是卷大小字段。在成功扩展卷后,它将使用
"error": false调用卷的扩展卷完成操作。如果出现任何问题,包括
extend_new_size缺失于元数据中,或者小于卷的当前大小,它将记录错误并调用os-extend_volume_completion操作,其中"error": true,以便 Cinder 可以回滚操作。对于任何其他卷状态,包括
in-use,事件的处理方式将与之前相同。
API¶
Nova 的 API 将引入一个新的微版本,以便 Cinder 可以在未完成扩展操作之前,确保新的行为可用。
为了在滚动升级期间处理旧的计算代理,API 还会检查接收到具有新微版本的 volume-extended 事件的目标代理的计算服务版本。如果目标计算代理太旧而无法支持该功能,API 将丢弃该事件并调用 os-extend_volume_completion 操作,其中 "error": true。
备选方案¶
之前的更改尝试使用
volume-extended外部服务器事件来支持 NFS 驱动程序的在线扩展 [1],但完全没有依赖 Nova 到 Cinder 的反馈。相反,它只会设置卷的新大小,将状态改回in-use,通知 Nova,并寄希望于一切顺利。如果 Nova 侧出现任何问题,这仍然会导致卷状态指示操作已成功,这是不可接受的。
此规范的早期版本提出在 Nova 中一个新的同步 API [2],它将直接调用管理附加了卷的客户机的 nova-compute 实例的
CompVirtAPI.extend_image,以触发调整大小操作,将新大小传递给 virt 驱动程序的extend_volume方法,并获得操作成功与否的反馈。同步 API 的问题是,RPC 和 API 超时限制了扩展操作可以花费的最大时间。对于 QEMU,这似乎是可以接受的,因为为
block-resize命令禁用存储预分配,并且因为所有合理的的文件系统都支持稀疏文件操作。但是,这可能不适用于将来可能需要此 API 的其他卷或 virt 驱动程序。它也会打破 Nova 和 Cinder 之间已建立的异步协调模式,其中包括辅助快照和卷迁移功能。
遵循此模式,我们可以使提出的 API 异步,并使用类似于 Nova 的
os-assisted-volume-snapshotsAPI 的新回调,该 API 使用os-update_snapshot_status快照操作向 Cinder 提供反馈。新的 Nova API 的功能将只是触发操作并通信新的大小。问题在于,是否值得为 Nova 添加一个新的 API,因为已经存在可以用于这两者的机制。
在 Nova 中触发扩展操作的现有机制当然是
volume-extended外部服务器事件。正如本规范建议的那样,将其用于此目的,需要单独传输目标大小,因为外部服务器事件只有一个可自由使用的文本字段,对于volume-extended已经用于卷 ID。除了像 [3] 和本规范建议的那样将其存储在管理元数据中之外,还有更新卷大小字段的选项,就像 [1] 本质上所做的那样。
如果 Nova 的错误响应丢失,卷将继续保持新的大小。我们需要扩展
os-reset_status以允许大小重置,或者类似的东西来清理像这样的卷。这是可行的,但仅在卷成功扩展后才更新大小字段似乎是一个更干净的解决方案。我们还可以扩展外部服务器事件 API 以接受事件的附加数据,并使用它将新的大小通信给 Nova。
此选项受到此规范早期版本审查人员的青睐 [2],但它将是对 Nova API 的更复杂更改。
但是,如果外部服务器事件 API 的未来版本中可用额外的字段,那么使用它而不是卷元数据将是一个相对较小的更改。
数据模型影响¶
无
REST API 影响¶
外部服务器事件 API 的行为将发生变化。
如果 Nova 收到
volume-extended事件,并且引用的卷状态为extending,Nova 将查找卷元数据中的extend_new_size键,并将其用作目标大小来更新块设备映射并传递给 virt 驱动程序的extend_volume方法,而不是使用卷大小字段。Nova 还会尝试调用 Cinder 的新
os-extend_volume_completion卷操作,该操作在 [3] 中提出,以让 Cinder 知道操作是否成功。否则,API 的行为将与之前相同。
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
无
升级影响¶
检查目标计算服务版本允许 API 优雅地处理滚动升级。
实现¶
负责人¶
- 主要负责人
kgube
- 其他贡献者
无
功能联络人¶
- 功能联络人
目前还没有
工作项¶
更新外部服务器事件 API,以检查
volume-extended事件的目标计算服务版本。更新
ComputeVirtAPI.extend_volume方法,以遵循 计算代理 中概述的行为。添加单元测试。
调整 Nova gate 中的 NFS 作业以验证在线扩展。
依赖项¶
扩展卷完成操作 [3]
测试¶
我们应该测试在所有可能的错误或成功条件下,如果卷状态为 extending,是否正确调用了 os-extend_volume_completion。
我们应该测试调用 os-extend_volume_completion 失败的情况。
我们还需要测试 volume-extended 是否继续正确处理非 extending 状态的卷。
文档影响¶
外部服务器事件 API 的新行为应添加到文档中。
参考资料¶
历史¶
发布名称 |
描述 |
|---|---|
2023.1 Antelope |
引入 |