手动清理

https://bugs.launchpad.net/ironic/+bug/1526290

手动清理(与自动清理相对)包含操作员可能希望在工作负载之间或在首次将工作负载分配给节点之前执行的所有耗时、手动、破坏性任务。

此功能先前被称为 “Zapping”,此规范复制了大量的 zapping 规范。(感谢 Josh Gachnang!)

问题描述

自动清理 自 kilo 周期以来就在 ironic 中可用。它允许操作员选择在首次部署节点和每次释放节点后自动执行哪些清理步骤。

但是,操作员可能希望某些操作或任务仅按需运行,而不是在每个清理周期中。例如,固件更新、设置新的 RAID 级别或烧入节点通常需要在向用户提供服务器之前完成,但花费的时间太长,无法在部署时合理地完成。

上述许多任务一旦引入硬件功能,就可以为 nova 提供有用的调度提示。操作员可以使用这些调度提示来创建 flavor,例如需要具有 RAID 1 以获得额外持久性的 nova 计算 flavor。

提议的变更

为了区分手动清理和自动清理,我们不添加新的 ZAP* 状态到状态机中,而是将现有的 CLEAN* 状态和清理机制重用于自动清理和手动清理。主要区别在于

  • 手动清理只能在节点处于 MANAGEABLE 状态时启动。手动清理完成后,节点将再次进入 MANAGEABLE 状态。

  • 操作员可以通过修改后的 API 设置节点的置备状态来启动手动清理。详情请参见下文的 PUT …/states/provision 部分。

  • 手动清理步骤可能需要指定一些参数。(这对于未来的自动步骤也可能有用。)为了支持这一点,ironic.drivers.base.clean_step 装饰器将被修改为接受一个参数列表。(默认值为 None。)每个参数都是一个字典,包含

    • ‘name’: <参数名称>

    • ‘description’: <描述>。这应包括可能的值。

    • ‘required’: 布尔值。如果此参数是必需的,则必须在手动清理请求中指定;如果它是可选的,则为 false。

  • 将清理步骤添加到仅由手动清理使用的驱动程序。为此已经存在机制。驱动程序实现者只需要使用优先级为 0 的 @clean_step 装饰器。这将确保该步骤不会作为自动清理的一部分运行。实现者可以指定该步骤是否可以中止,还应包括可以传递给清理步骤的任何参数。

  • 操作员可以通过 API 获取可能的步骤列表。下文的 GET …/cleaning/steps 部分提供了更多信息。

  • 与执行自动清理步骤类似,当 conductor 尝试执行手动清理步骤时,它将在负责该清理步骤的驱动程序上调用 execute_clean_step()。

  • 为了避免混淆,‘clean_nodes’ 配置将被重命名为 ‘automated_clean_enable’,因为它仅与自动清理有关。‘clean_nodes’ 配置的弃用和删除将遵循 ironic 的正常弃用流程。

备选方案

  • 我们可以使用单独的 API 和术语和机制使手动清理步骤和自动清理步骤互斥,但从概念上讲,由于它们都是清理步骤,因此为两者提供类似的机制不太容易混淆。

  • 我们可以将“手动清理”称为其他名称,例如“zap”,以避免区分“手动”和“自动”清理,但描述“zap”和“清理”之间的差异似乎更令人困惑,并且在尝试以这种方式实现时,这种困惑和复杂性显而易见。

数据模型影响

无。

状态机影响

  • 提议的状态机 中删除了所有提及“zap”和 ZAP* 状态的内容

  • 添加了两个新的转换

    • MANAGEABLE -> CLEANING 通过 ‘clean’ 动词,开始手动清理

    • CLEANING -> MANAGEABLE 通过 ‘manage’ 动词,结束成功的手动清理

REST API 影响

PUT /v1/nodes/<node_ident>/states/provision

此 API 允许用户通过 ‘target’: ‘clean’ 将节点直接置于 CLEANING 置备状态,从 MANAGEABLE 状态开始。PUT 还需要指定 ‘clean_steps’ 参数。这是一个有序的清理步骤列表,清理步骤表示为 JSON 编码的字典。

例如

'clean_steps': [{
    'interface': 'raid'
    'step': 'create_configuration',
    'args': {'create_nonroot_volumes': False, // optional keyword argument
             ... }               // more keyword arguments (if applicable)
  },
  {
    'interface': 'deploy'
    'step': 'erase_devices'
  }
]

在上面的示例中,驱动程序的 RAID 接口将配置硬件 RAID 而不使用非 root 卷,然后擦除所有设备(按该顺序)。

清理步骤由字典(JSON)表示,形式如下

{
    'interface': <interface>,
    'step': <name of clean step>,
    'args': {<arg1>: <value1>, ..., <argn>: <valuen>}
}

‘interface’ 和 ‘step’ 键是所有步骤所必需的。如果一个步骤需要额外的关键字参数,则可以指定 ‘args’ 键。它是一个关键字参数的字典,每个关键字参数条目为 <name>: <value>。

如果任何步骤缺少必需的关键字参数,则不会执行任何手动清理,并且节点将置于 CLEANFAIL 置备状态,并显示适当的错误消息。

如果在清理过程中,清理步骤确定其关键字参数不正确,则将执行所有先前的步骤,然后节点将置于 CLEANFAIL 置备状态,并显示适当的错误消息。

需要一个新的 API 版本来支持这一点。

GET /nodes/<node_ident>/cleaning/steps

我们计划提供一个 API 端点,让操作员查看自动清理的清理步骤。该提议的 API 是 GET /nodes/<node_ident>/cleaning/clean_steps,但尚未实现。

随着手动清理的引入,代替 GET /nodes/<node_ident>/cleaning/clean_steps,此规范建议将其替换为 API 端点 GET /nodes/<node_ident>/cleaning/steps。默认情况下,它将返回所有可用的清理步骤(优先级为零和非零),用于手动清理和自动清理。

可以指定一个可选的字段 ‘min_priority’ 来过滤优先级等于或高于指定最小值的所有清理步骤。例如,仅获取自动清理步骤(非手动清理)

GET http://127.0.0.1:6385/v1/nodes/my-awesome-node/cleaning/steps?min_priority=1

对此请求的响应将是一个按降序优先级排序的清理步骤列表,格式如下

[{
  // 'interface': is one of 'power', 'management', 'deploy', 'raid'.
  // 'step': is an opaque identifier used by the driver. Could be a driver
  //         function name or some function in the agent.
  // 'priority': is the priority used for determining when to execute
  //             the step; larger values have higher priority.
  // 'abortable': True if cleaning can be aborted during execution of this
  //              step; False otherwise.
  'interface': 'interface',
  'step': 'step',
  'priority': Integer,
  'abortable': Boolean

  // 'args': a list of keyword arguments that may be included in the
  //         'PUT /v1/nodes/NNNN/states/provision' request when doing
  //         a manual clean. An argument is a dictionary with:
  //           - 'name': <name of argument>
  //           - 'description': <description>
  //           - 'required': Boolean. True if required; false if optional
  'args': []
 },
 ... more steps ...
]

一个包含单个步骤的示例

[{
  'interface': 'raid',
  'step': 'create_configuration',
  'args': [{'name':'create_root_volume',
            'description':'Set to True (the default) to create root volume
                           specified in the node's target_raid_config. False
                           prevents the root volume from being created.',
            'required':False},
           {'name':'create_nonroot_volumes',
            'description':'Set to True (the default) to create non-root
                           volumes that may be specified in the node's
                           target_raid_config. False prevents non-root
                           volumes from being created.',
            'required':False}]
  'priority': 0,
  'abortable': True
}]

如果驱动程序接口无法同步获取清理步骤列表,例如,因为使用远程代理来确定可用的清理步骤,那么驱动程序必须缓存来自所述代理的最新执行的清理步骤列表并返回该列表。如果没有此类数据,驱动程序可以引发错误,该错误应由 API 服务转换为

  • 一个 HTTP 202

  • 一个新的(我们创建了这个)HTTP 标头 ‘Retry-Request-After’,指示客户端应该等待多少秒才能重试。‘-1’ 表示不知道等待多长时间。例如,当在 ENROLL 状态下进行请求时,可能会发生这种情况。此时,不知道何时可以在节点上使用远程代理进行查询。

  • 一个包含消息的响应体,指示数据尚未可用。

如果驱动程序接口可以同步返回清理步骤,而无需依赖硬件或远程代理,则应该这样做,尽管它也可以依赖上述缓存机制。

需要一个新的 API 版本来支持这一点。

客户端 (CLI) 影响

ironic node-set-provision-state

将向 node-set-provision-state CLI 添加一个新的参数,称为 ‘clean-steps’。其值是一个 JSON 文件,该文件被读取,其内容传递给 API。因此,该文件具有与传递给 API 的清理步骤相同的格式。

如果指定输入文件为 ‘-’,则 CLI 将从 stdin 读取,以允许将清理步骤管道传输到其中。在 Unix 实用程序中,使用 ‘-’ 表示 stdin 很常见。

如果请求的置备状态目标/动词是“clean”,则 ‘clean-steps’ 参数是必需的。否则,指定它被认为是一个错误。

ironic node-get-clean-steps

将添加一个新的 node-get-clean-steps API,如下所示

ironic node-get-clean-steps [--min_priority <priority>] <node>

<node>: name or UUID of the node
--min-priority <priority>: optional minimum priority; default is 0 for all clean steps

如果成功,它将返回一个清理步骤列表。如果来自相应 REST API 请求的响应是 HTTP 202,它将返回该响应体中的消息(数据不可用)以及重试请求的建议。

RPC API 影响

将 do_node_clean()(作为调用)添加到 RPC API 并增加 RPC API 版本。

驱动程序 API 影响

Nova 驱动程序影响

Ramdisk 影响

N/A

安全影响

其他最终用户影响

可扩展性影响

性能影响

其他部署者影响

开发人员影响

实现

负责人

主要负责人

rloo(接替已离开 ironic 的 JoshNang)

其他贡献者

JoshNang(开始这项工作的人)

工作项

  • 进行上述描述的更改到状态机

  • 增加 API 微版本以允许手动清理并实现 PUT /v1/nodes/(node_ident)/states/provision API 的更改(如上所述)

  • 修改清理流程以允许手动清理

  • 更改任何异步驱动程序中的 execute_clean_steps 和 get_clean_steps,以缓存清理步骤并在可能的情况下返回缓存的清理步骤。

  • 允许 API 返回 Retry-Request-After HTTP 标头和空响应,以响应来自驱动程序的特定异常。

依赖项

测试

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

升级和向后兼容性

文档影响

将更新文档以描述或阐明自动清理和手动清理以及如何配置 ironic 来执行其中一个或两者

参考资料

自动清理规范:https://specs.openstack.org/openstack/ironic-specs/specs/kilo-implemented/implement-cleaning-states.html

状态机规范:https://specs.openstack.org/openstack/ironic-specs/specs/kilo-implemented/new-ironic-state-machine.html

Zapping 相关补丁