volume-backed server rebuild

https://blueprints.launchpad.net/nova/+spec/volume-backed-server-rebuild

目前,计算 API 会失败,如果用户尝试使用新镜像重建 volume-backed 服务器。本规范建议添加支持使用新镜像重建 volume-backed 服务器的功能。

问题描述

目前 Nova rebuild(使用新镜像)仅支持从镜像启动的实例。当提供新镜像时,volume-backed 实例无法重建。尝试重建 volume-backed 实例会引发 HTTPBadRequest 异常。

用例

  • 作为用户,我希望能够使用新镜像重建我的 volume-backed 服务器。

  • 作为 Nova 开发人员,我希望计算 API 对于 volume-backed 和 image-backed 服务器具有功能对等性。

提议的变更

首先,更改现有用于重建 volume-backed 服务器的 API。然后 API 流程将是

  1. 将一个新的请求参数 reimage_boot_volume(布尔值)添加到现有的 reimage API 调用中,如果 True,则表示用户希望重新镜像一个 volume backed 实例。默认情况下,它将为 False

  2. 如果将 reimage_boot_volume 作为 True 传递,并且实例不是从 volume 启动的,则拒绝该请求。

  3. 是否请求了新的 API 微版本。如果是旧的 API 微版本请求,则应返回 400。

  4. 提供一个 COMPUTE_REBUILD_BFV 特征,用于确定计算节点是否支持 volume-backed 服务器重建。如果不支持,将引发 RebuildVolumeBackedServerNotSupport 异常。

  5. 如果 cinder 微版本足够新,可以支持重新镜像启动 volume。如果不支持,将引发 CinderAPIVersionNotAvailable 异常。

  6. 对于 multiattach volumes,n-api 将拒绝该请求,因为重建 multiattach volumes 需要复杂的附件处理,并且工作量将超过收益。

然后 nova-compute 管理器将执行以下步骤

  1. 为 volume 和服务器创建一个空的(没有 connector)volume 附件。这确保了 volume 在下一步中保持 reserved 状态。

  2. 删除现有的 volume 附件(旧的那个)。

  3. 将新的附件 UUID 保存到 BDM。

  4. 以上两个步骤是为了使 volume 保持在 reserved 状态,作为 cinder 执行其重新镜像操作所需的管理状态。

  5. 调用新的 os-reimage cinder API。

  6. 添加一个新的 ‘volume-reimaged’ 外部事件,以等待 cinder 完成重新镜像。就像我们用于 volume-extend 一样。有关详细信息,请参见 perform_resize_volume_online

  7. 在重新镜像操作成功完成后,cinder 将通过外部事件 API 通知 Nova 重新镜像操作已完成。

  8. 调用 cinder 以通过传递 connector 信息来更新空的 volume 附件,cinder 将把连接信息返回给 Nova。

  9. 在 Nova 完成与 brick 的连接后,完成附件,将 volume 标记为 in-use

在此过程中,我们可能会遇到一些条件

  • 如果重新镜像 volume 失败并且 volume 处于 ‘error’ 状态,则我们应该将实例状态设置为“error”。由于用户可以重建处于 error 状态的实例,因此用户有一种方法可以在解决 cinder 端故障原因后重试重建。

  • 如果 cinder API 本身返回 >=400 错误,则根 volume 没有更改,在这种情况下,实例操作应为“failed”,并且实例状态应恢复到原来的状态(我们可以看到 _error_out_instance_on_exception 的用法)。

备选方案

主要的替代方案是 nova 将执行像从 volume 初始启动一样的重建,nova-compute 将从新镜像创建一个新的 volume,然后在重建期间替换实例上的根 volume。

然而,这存在一些问题,例如如何处理旧的 volume

  • 关于 BDM 中的 ‘delete_on_termination’ 标志,delete_on_termination=True 表示:在终止实例时删除 volume。Rebuild 表示:在原位重新初始化此实例。重建流程必须确定如果旧的根 volume BDM 被标记为 delete_on_termination=True 该怎么做。如果 delete_on_termination 为 True,则删除旧的根 volume,否则,保留它。

  • 我们可以将一个新的标志传递给 rebuild API,告诉 nova 如何处理旧的 volume(删除它或不删除它)。如果标志为 true 以删除旧的 volume,但旧的 volume 具有快照,Nova 将不会删除 volume 快照,只是为了在重建期间删除 volume。

但正如上面提到的,存在一些问题,例如配额以及 nova 应该如何处理旧的 volume,您可以在 References 中找到更多详细信息。

数据模型影响

REST API 影响

将一个新的参数 reimage_boot_volume(布尔值)添加到现有的 rebuild API 中。

POST /servers/{server_id}/action
{
    "rebuild": {
        "reimage_boot_volume": "True"
    }
}

如果满足 Proposed change 部分中描述的条件,则将 rebuild 请求响应代码从 400 更改为 202。API 微版本和 compute RPC 版本也将递增,以指示新的支持。

安全影响

通知影响

其他最终用户影响

python-novaclient、python-openstackclient 和 SDK 将更新以支持新的微版本。

性能影响

由于涉及外部依赖项以及 cinder 中需要进行的工作,该操作将花费更长时间。

其他部署者影响

如果 cinder volume reimage API 操作失败并且 volume 变为 error 状态,管理员可能需要调查并解决 cinder 中的问题,然后将 volume 状态重置为 reserved

开发人员影响

升级影响

API 微版本和 compute 服务版本也将递增,以指示新的支持,因此用户将无法利用该功能,直到托管 volume-backed 实例的 nova-compute 服务升级为止。

实现

负责人

主要负责人

Rajat Dhasmana <rajatdhasmana@gmail.com> (whoami-rajat)

工作项

  • 将一个新的请求参数 reimage_boot_volume 添加到 rebuild API

  • 更改现有的 rebuild API。

  • 为根 volume 创建一个空的附件,以便在重建期间 volume 保持 in-use 状态(我们今天已经这样做了)。

  • 删除旧的 volume 附件。

  • 调用 cinder API 以重新镜像 volume。

  • 重新镜像后更新并完成 volume 附件。

  • 采用新的 compute 版本。

  • 在 python-novaclient 中采用新的微版本。

  • 在 python-openstackclient 中采用新的微版本。

依赖项

依赖于 cinder 重新镜像 volume 的蓝图,有关更多详细信息,请参见 References。

测试

添加了以下测试

  • Nova 单元测试用于负面场景

  • Nova 功能测试用于“happy path” 测试

  • Tempest 集成测试,以确保 nova/cinder 集成正常工作

文档影响

我们将替换 API 参考 中的注释,添加一个关于使用新镜像重建 volume-backed 服务器所需的最低微版本的注释。

将更新以下文档

  • API 参考

  • 我们还需要在文档中说明,当卷被重新镜像时,卷上的所有当前内容都将被销毁。这一点很重要,因为 cinder 卷被认为是持久的,而此操作并非如此。

参考资料

历史

修订 :header-rows: 1

发布名称

描述

Stein

已批准。

瑜伽

重新提出。