为 ironic 添加通知支持¶
https://bugs.launchpad.net/ironic/+bug/1526408
在 OpenStack 中,近乎实时的服务间通知具有多种用例。在 Mitaka 设计峰会上,针对 ironic 讨论的一些用例包括与计费系统的集成、使用通知支持一个运维面板以跟踪潜在故障,以及与 TripleO 的集成。[1] Nova 自 Diablo 周期以来就支持某种形式的通知。[2] 本规范提出了一种通用通知模式的设计,该模式具有版本控制和结构化,但足以支持未来的需求。
问题描述¶
Ironic 当前不支持任何类型的外部服务可消费的通知。
这使得运维人员难以监控和跟踪 ironic 中的事件,例如节点状态更改、节点电源事件以及成功或失败的部署。发送包含有关节点在不同时间点相关信息的通知(例如状态转换)将使运维人员更容易使用外部工具来调试意外行为。
缺乏通知也使得外部服务难以识别 ironic 中的状态更改。Nova 和 inspector 必须重复轮询 ironic 才能查看是否已发生状态更改。为这些情况添加通知将允许 ironic 推送这些事件更改,而不是将大部分负担放在外部服务上。
如果 ironic 曾经被用于独立部署,而没有像 Nova 这样跟踪资源并发出自身通知的外部服务,这将尤其成问题,因为 ironic 的部署者将没有任何方法来跟踪除了定期查询 ironic API 或查看日志之外的任何状态更改。
提议的变更¶
将使用 oslo.messaging 中的 notifier 接口向 ironic 添加通知支持。[3] oslo.messaging 使用以下格式进行通知
{'message_id': six.text_type(uuid.uuid4()),
'publisher_id': 'compute.host1',
'timestamp': timeutils.utcnow(),
'priority': 'WARN',
'event_type': 'compute.create_instance',
'payload': {'instance_id': 12, ... }}
Ironic 通知将遵循该格式。
将创建基类来模拟通知格式。通知中未自动生成(除了 message_id 和 timestamp 之外的所有内容)的字段将按如下方式为 ironic 定义
publisher_id 将从发出通知的服务和主机名获取
priority 将是 DEBUG、WARN、INFO 或 ERROR 之一,具体取决于通知。通知使用的级别应遵循 OpenStack 日志记录标准。[4]
event_type 将是一个简短的字符串,描述通知。每个字符串将以“baremetal.” 开头,以区分 ironic 通知和消息总线上的其他通知。
之后将是正在操作的对象、正在执行的操作的描述以及操作的状态(“start”、“end”、“error”或“success”)。这些状态将具有以下语义
“start”将在非即时操作开始时使用。
“end”将在非即时操作成功完成时使用。
“error”将在操作失败时使用,无论操作是即时的还是非即时的。
“success”将在操作几乎立即成功完成时使用,并且无需报告中间资源状态。
event_type 将具有一个定义这些字段的基类,以及每个事件类型的子类。这些子类将是版本化的对象。这些字段中的每一个都将在通知中发送的 event_type 字符串中用句点分隔。
鉴于上述信息,event_type 将在消息总线上最终成为以下格式的字符串:
baremetal.<object>.<action>.<status>一些潜在 event_type 字符串的示例
“baremetal.node.power_set.start”
“baremetal.node.power_set.end”
“baremetal.node.provision_set.start”
“baremetal.node.provision_set.end”
“baremetal.conductor.init.success”
“baremetal.conductor.stop.success”
payload 将是与通知主题相关的版本化对象。这应包括有关正在通知的事件的相关信息。例如,对于关于节点的上述通知,我们将发送一个包含 Node 对象字段的有限子集的对象,删除敏感字段(如私有凭据)以及具有未知长度的字段,以及通知对象的版本。必须为每种类型的通知创建一个单独的版本化通知对象,以使通知版本与 ironic 中的其他对象版本分开。这样可以防止通知随着其他对象(如 Node 对象)中添加新字段而自动更改。
初始实现将包括建模通知格式和发出通知所需的基类,以及上述电源状态通知。
备选方案¶
另一种选择是修改 oslo.messaging 的 notifier 接口,以提供将通知作为版本化对象定义的基类。优点是,我们不必依赖 payload 进行版本控制。缺点是,它需要对 oslo.messaging 进行重大更改,这会影响其他项目并需要更改所有通知消费者以及围绕现有通知格式构建的任何下游工具。
我们也可以有一个全局通知版本,该版本会随着对任何通知的每次更改而递增。这似乎不可取,因为它可能会错过更改,如果 payload 中包含的单独 ironic 对象(如 Node 对象)发生更改,而通知本身的版本没有增加。
数据模型影响¶
此功能不需要任何数据库更改。
更改将引入用于通用通知模式和单个通知类型的新版本化基类对象。基类将类似于 nova 版本化通知规范中的那些。[5]
状态机影响¶
对状态或转换本身没有影响。
如果启用了通知,将在节点配置状态更改时发送通知。可以通过在每次 TaskManager 的 process_event 方法启动并成功执行时发送通知来实现。
有关节点先前、当前和新目标状态的所有信息都将包含在通知中。.start 通知将包含状态更改之前的当前 provision_state 和 target_provision_state。事件成功处理后,.end 通知将包含当前 provision_state(.start 通知的目标状态)和新的 target_provision_state。通知还将包括导致状态更改的事件的名称。这对于区分从一个状态到另一个状态的多个潜在转换的情况非常有用。
REST API 影响¶
无。
客户端 (CLI) 影响¶
无。
RPC API 影响¶
从 API 的角度没有影响。
需要对某些 conductor RPC API 方法的实现进行修改,才能发送在将 RPC 分派到 worker 时发送的通知,但是。有关这可能如何为电源通知完成的示例,请参阅驱动程序 API 影响。
驱动程序 API 影响¶
从 API 的角度没有影响。
将添加与电源状态更改相关的通知,但可以通过以下方式完成,而无需修改任何驱动程序类
在 ConductorManager 接收 change_node_power_state 调用作为 conductor 后台任务后,发送 baremetal.node.set_power_state.start 通知。
成功后,在分派到 node_power_action 的调用完成且未引发异常后,发送 baremetal.node.set_power_state.end 通知。
发生错误时,将在 conductor manager 中调用 power_state_error_handler 钩子。在此处发送 baremetal.node.set_power_state.error 通知。
Nova 驱动程序影响¶
无。
Ramdisk 影响¶
N/A
安全影响¶
无。
其他最终用户影响¶
没有,除非部署者想要使用通知系统,则必须使用消息总线。
可扩展性影响¶
启用后,通知将对发送通知的消息总线产生额外的负载。
性能影响¶
启用后,将调用发送通知的代码,每次发生触发通知的事件时。这对于 ironic 本身来说不应该成为问题,但应考虑所使用的消息总线的负载(参见可伸缩性影响)。
其他部署者影响¶
将添加以下配置选项
oslo.messaging 所需的 notification_transport_url 选项。[6] 默认为 None,表示将使用与 RPC 相同的配置。
将添加一个 notification_level 字符串参数,以指示将发送通知的最低优先级级别。可用选项将是 DEBUG、INFO、WARN、ERROR 或 None 以禁用通知。None 将是默认值。
notification_level 全局配置选项的替代方案是为每个通知类型创建一个特定的配置选项,以定义是否应发送该通知。Nova 这样做,但峰会讨论表明一致性更可取。
开发人员影响¶
开发人员应遵守适当的版本控制指南,并在创建新通知时使用通知基类。
实现¶
负责人¶
- 主要负责人
mariojv
- 其他贡献者
lucasagomes
工作项¶
创建通知基类和测试
编写文档,说明如何在所有 ironic 通知中一致地使用基类
实现节点电源状态更改时通知的示例
依赖项¶
无。
测试¶
将添加基类和节点电源状态通知的单元测试。
升级和向后兼容性¶
没有影响,但必须检查将来创建的通知是否具有向后兼容性。
文档影响¶
将添加开发人员文档,说明如何添加新通知或修改现有通知
记录发出的通知的外观示例
应为每个通知记录文档,指示何时预期发出该通知