Implement Cleaning States

https://blueprints.launchpad.net/ironic/+spec/implement-cleaning-states

当节点完成工作负载后,驱动程序接口应该有机会在拆卸后并在节点再次可用于调度之前运行一组任务。

问题描述

  • 当硬件从一个工作负载回收用于另一个工作负载时,应该对其进行一些处理,以确保它已准备好用于另一个工作负载。用户期望每个裸机节点都是相同的。应用这些基本任务将确保最终用户获得更流畅的体验。

  • 如果启用,这些步骤也可以对新注册的节点执行,这些节点从 MANAGED 状态移动到 AVAILABLE 状态。

  • 这些基本任务应该是任何 a) 准备节点以进行配置的任务,包括使其与其他节点保持一致,以及 b) 不会更改机器的明显配置的任务。

  • 至少,应该擦除硬盘驱动器(如果启用)。

  • 其他潜在的有用任务包括重置 BIOS、应用 BIOS 设置(所有节点的统一设置,而不是每个节点单独设置)、验证固件完整性和版本、验证硬件是否与 node.properties 匹配,以及启动长期运行的代理 [2]。

  • 有些用户可能需要采取某些安全措施,然后才能回收节点,例如安全擦除磁盘,这可以使用 Ironic Python Agent 中的自定义硬件管理器或支持它的带外系统来实现。

  • 当前的 PXE ramdisk 将支持有限的清理步骤子集,例如 erase_devices()。验证节点属性等步骤需要 BMC、Ironic Python Agent 或对当前 ramdisk 的添加的配合。

提议的变更

  • 清理功能将添加在配置选项之后,以确保操作员可以选择禁用该功能,如果其部署不需要该功能。例如,某些操作员可能希望禁用每次请求的清理,而仅偶尔通过 ZAPPING 进行清理。

  • 添加一个装饰器 @clean_step(priority) 来装饰应该作为 CLEANING 的一部分运行的步骤。priority 是步骤运行的顺序。优先级最高的函数将首先运行,然后是优先级第二高的函数,依此类推。如果将 priority 设置为 0,则将不会执行该步骤。该参数应该是一个配置选项,例如 priority=CONF.$interface.$stepname_priority,以便为操作员提供更多控制权,以控制步骤运行的顺序(如果 überhaupt)。

  • 在基本 Interface 类中添加一个新函数 get_clean_steps()。基本实现将获取用 @clean_step 装饰的函数列表,确定哪些已启用,然后返回一个表示每个步骤的字典列表,按优先级排序。

  • get_clean_steps() 的返回值将是一个包含 3 个键的字典列表:step、priority 和 interface,如下所述

    • ‘step’: ‘function_name’,

    • ‘priority’: ‘一个整数或浮点数,用于排序,如下所述’,

    • ‘interface’: ‘interface_name’

    只有 priority 大于 0(已启用步骤)的步骤才会被返回。

  • 在基本 Interfaces 中添加一个新函数 execute_clean_step(clean_step),它将 get_clean_steps() 返回的字典之一作为参数,并执行指定的步骤。

  • 在 conductor 中创建一个新函数:clean(task) 来运行所有启用的清理步骤。它将获取所有已启用步骤的列表,并按优先级执行它们。conductor 将跟踪节点上的一个新字段 clean_step 中的当前步骤。

  • 如果优先级存在平局,则平局打破者将是实现该函数的接口,顺序为 power、management、deploy 接口。因此,如果 power 和 deploy 接口都实现了一个优先级为 10 的步骤,则 power 的步骤将首先执行,然后是 deploy 接口的步骤。

  • 如果在单个接口内存在优先级平局(操作员无意中将两个步骤设置为相同的优先级),则 conductor 将在启动时无法加载该接口,并记录有关重叠优先级的错误。

  • 使用 CLEANING、CLEANED 和 CLEANFAIL,这些将在新的状态机规范 [1] 中添加。这些状态发生在 DELETED 和 AVAILABLE 之间。这将防止 Nova 删除命令花费数小时。

  • CLEANED 将像 DELETED 一样使用:通常作为目标配置状态。在 CLEANING 完成并且 conductor 有机会将其移动到 AVAILABLE 之前,节点将处于 CLEANED 状态。

  • 节点可以通过 API 调用(如下所述)从 MANAGED 或 CLEANFAIL 状态进入 CLEANING。MANAGED 允许操作员在节点可用于调度之前对其进行清理。这确保了新节点与已添加的其他节点具有相同的基本配置。

  • ZAPPING API 将允许节点从 MANAGED 状态经历单个或一系列 clean_steps。这些将由操作员通过 API 驱动的步骤,而不是此规范中描述的撕毁后自动 CLEANING。

  • 使 Nova Virt Driver 查找 CLEANING、CLEANED 和 CLEANFAIL 状态在 _wait_for_provision_state() 中,以便可以更快地将节点从用户的活动节点列表中删除。清理失败不应是用户的错误,需要由操作员解决。

  • 如果清理失败,节点将被置于 CLEANFAIL 状态,last_error 将被适当地设置,并进入维护状态。节点不会被关闭,因为电源循环可能会损坏节点。操作员可以修复节点,并通过 API 将节点的 target_provision_state 还原为 CLEANED 以重试清理或跳到 AVAILABLE。

  • CLEANING 不会在重建时执行。

备选方案

  • 接口可以在 tear_down 中仅实现这一点。从用户角度来看,这将更慢。

  • 这些操作中的大多数可以在部署期间进行。这将在某些情况下(尤其是使用旋转磁盘时)显著延长部署时间。

数据模型影响

  • node.clean_step 将添加为字典或 None 字段,以跟踪当前正在节点上执行的步骤。这将为操作员提供更多可见性,了解节点正在做什么,并允许在 CLEANING 期间的 conductor 故障转移更容易实现。

  • 如果清理步骤需要存储其他信息,它应该使用 node.driver_info。例如,agent 接口会将 IPA 硬件管理器版本存储在 driver_info 中,以便它可以检测更改并在清理周期期间部署新的硬件管理器时重新启动清理。

REST API 影响

  • API 将更改为防止在节点处于 CLEANING 状态时更改电源状态或配置状态。处于 CLEANFAIL 状态的节点可以通过 API 开启和关闭,因为操作员可能需要重新启动节点才能修复它。

  • API 将允许用户使用 POST 将节点直接置于清理 provision_state,就像在 Ironic 中的其他地方更改配置状态一样。这对于验证新添加的节点或如果操作员想要将一批非活动服务器置于已知状态非常有用。节点只能从 MANAGED 或 CLEANFAIL 状态进入 CLEANING 状态。

  • 处于 CLEANFAIL 状态的节点可以进入 CLEANING 或 AVAILABLE 状态,由操作员确定。

  • 应添加一个 API 端点,以允许操作员查看当前启用的清理步骤及其顺序。这将是在 /nodes/<uuid>/cleaning/steps 处的 GET 端点,并将以 JSON 文档的形式返回上述 get_clean_steps() 中注意的完全相同的数据,并按优先级排序。

  • 对节点的 API 的 GET 请求(/nodes/<uuid>)和节点详细信息 API(/nodes/details)应返回当前的 node.clean_step。

RPC API 影响

需要通过 RPC 提供节点的清理,以便 API 服务器可以将节点从 MANAGED 或 CLEANFAIL 状态置于 CLEANING 状态。

在撕毁结束时,conductor 将 RPC 调用() conductor 的 do_node_clean() 方法。

由于状态将首先作为无操作添加到新的状态机规范中,因此升级不会有问题。

驱动程序 API 影响

  • BaseDriver 将添加并实现 get_clean_steps()execute_clean_steps() 函数。

    def get_clean_steps(task)

    “””返回接口可以在节点上执行的清理步骤”””

    param task:

    来自 TaskManager 的任务。

    returns:

    如上所述的字典列表

    def execute_clean_steps(task, step)

    “””在 task.node 上执行给定的清理步骤”””

    param task:

    来自 TaskManager 的任务。

    param step:

    来自 get_clean_steps() 的步骤

    raises CleanStepFailed:

    如果步骤失败

  • 测试将类似于其他驱动程序接口,并且预计每个接口将彻底测试其实现。

  • 现有接口可以选择不实现新的 API,而不会产生任何影响,因为它们将添加到基本类中。

Nova 驱动程序影响

  • Nova 驱动程序将在确定取消配置是否成功时查找清理状态。

  • 如果 Nova 首先升级,则不会有任何变化。驱动程序将继续处于 tear_down 状态,直到节点进入 AVAILABLE。

安全影响

  • 通过添加磁盘擦除 [3] 将提高安全性。

  • 应该在文档中说明,如果将裸机节点提供给不受信任的用户或裸机节点受到破坏,仍然存在攻击向量。

  • 如果调用 API 将节点设置为清理状态,则该节点可能会被锁定数小时。如果由恶意行为者对集群中的足够多的节点执行此操作,集群可能会迅速耗尽容量。这些 API 默认需要管理员权限。但是,用户可以快速配置和取消配置节点,从而导致拒绝服务。配额可以缓解此问题。

其他最终用户影响

可扩展性影响

性能影响

  • 将需要对硬件进行额外的调用才能执行清理步骤。这些步骤可能需要数小时,这意味着回收时间可能会比以前高得多。

  • 在清理期间将锁定节点。

  • 数据库调用将增加,因为状态将在需要重新启动或长时间运行的进程的每个清理步骤之后保存,以及在开始执行步骤之前保存当前的 clean_step。

  • 在最坏的情况下,重新平衡将需要节点根据 cleaning_step 重新执行一个步骤。如果 conductor 在拥有正在执行长时间运行的进程的节点时发生故障,则可能会发生这种情况。clean_steps 应该实现为幂等操作,以避免此处出现问题。

其他部署者影响

  • 部署者需要检查正在执行的清理步骤,并根据默认设置不适用于其环境时调整每个步骤的执行方式和优先级。

  • 如果 Ironic 首先更新,则撕毁的节点可能需要额外的时间,并且很可能会在取消配置中超时。这只会发生在 Ironic 在 Nova 之前更新的情况下,并且启用了并使用了需要大量时间的清理接口。

开发人员影响

  • 驱动程序需要调用他们认为清理节点所必需的任何函数,并可能实现这些函数。他们可以添加配置选项以启用或禁用这些功能。

实现

负责人

主要负责人

JoshNang

其他贡献者

jroll JayF

工作项

  • 在 conductor 中添加 clean()

  • 在 BaseDriver 接口中添加 get_clean_steps() 和 execute_clean_step()

  • 添加 @clean_step() 装饰器

  • 添加 API 检查清理状态并允许将“CLEANED”作为配置目标状态

  • 添加 API 端点 /nodes/<uuid>/cleaning/steps

  • 在 PXE 接口中添加对 erase_disks 的支持

  • 为 IPA 添加清理支持

  • 添加 Nova 驱动程序支持

依赖项

  • Ironic 状态机:https://review.openstack.org/#/c/133828/。两者都在尝试添加 CLEANING/CLEANED/CLEANFAIL。如果未添加新的清理状态来实现此功能,用户将在 Nova 中看到一个处于“删除”状态的节点,可能需要数小时,从而消耗配额。

  • 不需要,但会有所帮助:Agent 部署接口(可能还有其他接口)的清理实现将受益于外部事件回调 API:https://review.openstack.org/#/c/99770/

测试

  • Tempest 将需要进行调整,以支持将其作为其正常的配置/取消配置测试的一部分来运行清理。

  • 实施清理的驱动程序预计将测试其添加的功能。

升级和向后兼容性

  • 对 REST API 的更改,以允许节点从 MANAGED 或 CLEANFAIL 状态进入 CLEANED 状态,将需要用户指定新状态:CLEANED。因此,它不应破坏向后兼容性。现有用户/工具可能看到的唯一变化是节点无法通过 API 关闭的扩展时间。

文档影响

  • 应该提供关于清理工作原理、步骤的排序方式、它们的作用以及操作员如何启用、禁用和重新确定其优先级以及如何进行操作的非常清晰的文档。这对于操作员了解是否要使用清理至关重要。清理接口之间的差异也需要详细说明。

  • Ironic 驱动程序接口的更改、Nova 驱动程序支持以及 Ironic API 的更改需要记录在案。

  • 我们应该记录即使启用了清理仍然存在的安全问题。

参考资料

1: https://specs.openstack.org/openstack/ironic-specs/specs/kilo/new-ironic-state-machine.html

2: https://review.openstack.org/#/c/102405/

3: https://bugs.launchpad.net/ironic/+bug/1174153