启用 cell0 中实例的重建

https://blueprints.launchpad.net/nova/+spec/enable-rebuild-for-instances-in-cell0

本文档总结了启用由于资源不足而无法调度的实例重建所需的更改。

问题描述

目前,只要服务器之前已成功启动,就可以重建处于 ERROR 状态的服务器。但是,如果用户尝试重建从未启动过的实例,因为调度器由于可用资源不足而找不到有效的宿主机,则请求将以 `InstanceInvalidState` 类型的异常失败 [1]。我们目前不处理服务器由于超过最大重试次数而从未启动的情况。

用例

  1. 作为操作员,我希望能够在服务器由于资源不足而无法调度(即实例最终处于 PENDING 状态,如果已配置)后执行纠正操作。这些操作可以包括添加更多容量或释放已用资源。在执行这些操作后,我希望能够重建失败的服务器。

注意

将 PENDING 状态以及将实例设置为该状态超出了本文档的范围,因为它们正在由另一个更改处理 [2]

提议的变更

由于资源不足导致的调度失败,映射到 cell0 中的实例的重建过程将如下所示

  1. nova-api 在识别出实例位于 cell0 后,应创建一个新的 BuildRequest 并更新实例映射(cell_id=None)。

  2. 此时,api 还应从 cell0 DB 中删除实例记录。如果这是软删除 [3],那么在操作成功完成后,我们将最终在新的 cell 的 DB 中获得一条实例记录,以及 cell0 中的一条相同实例记录(deleted=True)。更好的方法是硬删除 [4] cell0 中的实例信息。

  3. 然后 nova-api 应该向 conductor 的新方法 `rebuild_instance_in_cell0` 发出 RPC API 调用。这个新方法的用途几乎(如果不是完全)与现有的 `schedule_and_build_instances` 相同。因此,我们可以选择在内部调用它,或者提取其部分功能并重用它们。这样做主要是为了避免直接从 API 中的重建代码调用调度和构建代码到超级 conductor 中。

  4. 最后,需要从 conductor 到所选 cell 的计算服务的 RPC API 调用。`rebuild_instance` 方法尝试销毁现有实例然后重新创建它。在这种情况下,由于实例位于 cell0 中,因此无需销毁和重新创建。因此,似乎调用现有的 `build_and_run_instance` 方法是合适的。

用户在初始请求中提供的信息,例如 keypair、trusted_image_certificates、BDMs、tags 和 config_drive 可以从埋在 cell0 中的实例中检索到。目前,在尝试重建实例时无法恢复请求的网络。

  1. 一个合理的更改是扩展 RequestSpec 对象以添加一个 requested_networks 字段,请求的网络将存储在该字段中。

  2. 当调度器找不到实例的有效宿主机并将 VM 放入 cell0 时,请求的网络列表将存储在 RequestSpec 中。

  3. 一旦重建过程开始并检索到请求的网络,新的字段将被设置为 None。

同样适用于个性化文件,这些文件可以在初始创建请求期间提供,并且从 microversion 2.57 开始,它已被重建 API 弃用 [5]。由于该字段未持久化,因此我们无法在从 cell0 重建时检索它们。为此,我们有几种替代方案

  1. 像处理请求的网络一样处理个性化文件,并将它们持久化在 RequestSpec 中。

  2. 将此记录为该功能的限制,如果人们希望使用新的重建功能,他们不应该使用个性化文件。

  3. 另一种选择是在实例的 `system_metadata` 中跟踪实例是否使用个性化文件创建。然后在从 cell0 重建期间,我们可以检查并拒绝使用个性化文件创建的实例的请求。

邮件列表中正在讨论如何处理个性化文件 [6]

配额检查

在正常的构建流程中,API 级别 [7] 和 conductor 级别 [8] 都有配额检查。考虑用户有足够的 RAM 配额来创建一个新实例的情况。一旦创建实例,由于调度失败,它就进入了 cell0。

在检查核心和 RAM 的配额时,有两种不同的情况

  1. 从 Nova DB 检查配额

    在这种情况下,实例的资源,即使在 cell0 中,也将被聚合,因为实例记录将位于 DB 中。但是,在硬删除实例时,存在一个轻微的竞争条件窗口。

  2. 从 Placement 检查配额 [9]

    当实例位于 cell0 时,对于此消费者没有 Placement 中的分配。这意味着实例的资源在后续检查期间不会被聚合,并且在重建时 API 级别没有检查。

在 conductor 级别重新检查配额将确保在继续构建过程之前用户的配额足够。

在初始构建和从 cell0 重建之间,端口使用情况可能会发生变化。在这种情况下,由于在从 cell0 重建时不会检查端口配额,因此我们可能会在计算服务中尝试创建端口时失败。虽然用户不会从 API 获得快速失败,但这可以接受,因为此时使用量已经超过限制,服务器将无法成功启动。

备选方案

用户可以删除失败的实例并创建一个具有相同特征但 ID 不同的新实例。所提出的功能是支持抢占式实例的依赖项,其中外部服务在采取纠正措施后自动重建失败的服务器。在上述功能中,保持实例的 ID 至关重要。这就是为什么不能将其视为可接受的替代解决方案的原因。

数据模型影响

在 RequestSpec 对象中添加一个 `requested_networks` 字段,该字段将包含 NetworkRequestList 对象。由于 RequestSpec 作为 blob(mediumtext)存储在数据库中,因此不需要模式修改。

REST API 影响

需要一个新的 API microversion。对于较旧的 microversion,重建映射到 cell0 的实例将继续失败。

安全影响

无。

通知影响

无。

其他最终用户影响

用户将被允许重建由于资源不足而失败的实例。

性能影响

无。

其他部署者影响

无。

开发人员影响

无。

升级影响

无。

实现

负责人

主要负责人

<ttsiouts>

其他贡献者

<johnthetubaguy> <strigazi> <belmoreira>

工作项

参见 提议的变更

依赖项

无。

测试

为了验证功能的有效性

  1. 必须实现新的单元测试,并且应调整现有的单元测试。

  2. 必须实现新的功能测试,以验证 cell0 中实例的重建以及实例标签、keypairs、trusted_image_certificates 等的处理。

  3. 新的测试应考虑 BFV 实例和 BDMs 的处理。

文档影响

我们应该更新文档,说明允许重建从未启动过的实例。

参考资料

在都柏林 PTG 上讨论:* https://etherpad.openstack.org/p/nova-ptg-rocky (#L459)

历史

修订

发布名称

描述

Rocky

引入

Stein

重新提出

Train

重新提出