标记不健康资源

https://blueprints.launchpad.net/heat/+spec/mark-unhealthy

添加一个接口,允许用户通信有关资源健康状况的信息,这些信息是 Heat 无法自行确定的。

问题描述

Heat 评估资源健康状况的唯一机制是将资源属性与其相关的 OpenStack API 的输出进行比较。(这发生在当前架构中的 stack-check 命令中,但在 Convergence 架构的提议的 Phase 2 中将自动进行)。但是,可能存在用户(或应用程序)知道不健康的资源,而 Heat 无法确定这些资源。一个明显的例子是服务器,从 Nova 的角度来看正在运行,但实际上,从应用程序的角度来看,已经损坏了。

目前,用户(或应用程序)无法通过执行多次编排传递或重命名资源或两者兼而有之来替换此类资源。两者都是不可取的,这使得用户无法利用 Heat 在单个工作流程中正确替换资源的能力。

提议的变更

为资源端点添加 PATCH 处理程序

/stacks/<stack_name>/<stack_id>/resources/<resource_id>

PATCH 方法将接受以下形式的 JSON 主体

{
  'mark_unhealthy': <bool>,
  'resource_status_reason': <string>
}

对于遗留堆栈,如果无法获取堆栈锁,则此调用将失败。对于 Convergence(phase 1)堆栈,如果无法获取资源锁,则调用将失败。这种故障模式将通过在引擎中引发 ActionInProgress 异常来指示,该异常表现为 ReST API 请求的 409 Conflict 响应。

收到此调用后,如果 ‘mark_unhealthy’ 字段为 true,Heat 将把资源置于 CHECK_FAILED 状态。如果该字段为 false,Heat 将把资源置于 CHECK_COMPLETE 状态(如果它处于 CHECK_FAILED 状态);否则,它将不会进行任何更改。

存在任何其他字段或缺少 ‘mark_unhealthy’ 字段将触发无效请求错误。

status_reason 字段是可选的。如果存在,此字段的值将用作状态更改的 status_reason;否则,将记录适当的默认消息,以指示状态更改是由于资源被显式标记为不健康所致。

假设如果将来使用 PATCH 动词在资源上添加任何其他操作,则在同一次调用中与此操作同时发生将是无效的。因此,RPC 调用将具有特定的 mark_unhealthy_resource 调用,而不是通用的 patch_resource 调用。

更改 StackResource 和 RemoteStack 资源类型的 _needs_update() 方法,以便在更新时如果资源处于 CHECK_FAILED 状态,则替换该资源。希望手动强制替换嵌套堆栈的成员(而不是嵌套堆栈本身)的用户应将成员标记为不健康,而不是堆栈本身。处于 FAILED 状态的任何其他类型的资源在后续堆栈更新时都将被替换,无论操作(CHECK 或其他)如何,这同样适用于遗留堆栈和 convergence 堆栈。

修改 InstanceGroup(以及通过扩展,Heat 和 AWS AutoscalingGroup)类型,以便在缩减或在滚动更新中更新时,将处于 FAILED 状态的成员赋予最高优先级以被删除。目前,在构建缩放组的新模板时,会省略 FAILED 资源,因此任何此类资源都不会被具有相同名称的资源替换。此更改将允许在由于缩减而不会永久删除资源的情况下保持名称的连续性。

一旦修复了 bug 1508736,就不再需要对 ResourceGroup 进行任何更改。但是,请注意,ResourceGroup 和 InstanceGroup 都使用相同的 grouputils.get_members() 函数,该函数会过滤掉失败的成员,因此上述修改可能需要对 ResourceGroup 进行更改以保持相同的行为。

备选方案

可能希望有一个调用来同时将资源标记为不健康并使用现有模板和环境启动堆栈更新。但是,最好保持 API 调用正交,因为用户可能希望同时对堆栈进行其他更改。它也大大简化了实现和测试。

我们可以添加一个单独的 healthy=False 列到数据库,而不是重用 CHECK_FAILED,但鉴于这实际上是一种手动提供 stack-check 不可用的信息的方式,因此重用相同状态是有意义的。它还简化了引擎中的逻辑,因为我们已经在许多地方检查 FAILED 状态,因此重用此状态应该会导致 Heat 只是做正确的事情,而无需添加对另一个字段的多个检查。

此提案的早期版本建议使用 SOAP 样式的 POST 请求到“mark_unhealthy”操作端点,而不是对资源进行 PATCH 请求。这与当今许多 OpenStack API 的操作方式一致,但被广泛认为是违反 ReSTful 规范的。目前 建议的指南 API 工作组建议为这种类型的 POST 请求使用单个“actions”端点,其中主体将采用以下形式

{
  "name": "mark_unhealthy",
  "args": {
    "unhealthy": <bool>,
    "resource_status_reason": <string>
  }
}

但是,此提案仍然存在争议(并且在评论中被不准确地描述为“SOAP 在 ReST 服装中”)。其主要驱动力似乎是相信项目将不愿意实现像此处建议的完全 ReSTful 接口。

我们可以重用现有的信号 API,而不是添加新的端点。但是,这将意味着在处理信号方面,资源插件(目前负责)和 Heat(因为这个新提案独立于资源类型)之间存在责任混合。它与当前建议的 API 指南更加一致;这是否是一件好事,值得商榷,因为这些建议仍然极有可能发生变化。

或者,我们可以将此作为对堆栈(而不是单个资源)的调用,以便用户可以使用单个调用将多个资源标记为不健康。这一个缺点是需要在请求主体中包含资源标识符,而不是 URL,因此可能比需要的更难包含在例如 Mistral 工作流中。从 ReST 的角度来看,这不太合逻辑,并且使错误处理和报告变得复杂。如果确实需要,我们可以稍后添加此功能。

与其定义特定的状态转换,我们可以允许用户设置任意资源状态。这是一个巨大的麻烦。

此提案是 https://review.openstack.org/#/c/212205/ 中提出的提案的替代方案,该提案涉及将各种类型缩放组的成员 ID 置于用户控制之下。与那个相比,这个提案更通用,并且与未来的 convergence 计划更相关。

实现

负责人

主要负责人

ahmed-h-elkhouly <ahmed.h.elkhouly@gmail.com>

里程碑

完成目标里程碑

mitaka-3

工作项

  • 修改 StackResource 和 RemoteStack,以便在处于 CHECK_FAILED 状态时在更新时被替换。

  • 在 heat-engine 中实现 RPC API,以在遗留和 convergence 架构中将资源标记为 CHECK_FAILED

  • 在 heat-api 中实现 RPC API 调用的 ReST 前端

  • 实现对 API 调用的客户端支持

  • 修改 InstanceGroup 以使 FAILED 资源保留在模板中(以便它们被具有相同名称的另一个资源替换)

依赖项

在完成 blueprint scaling-group-common 后,对 InstanceGroup 的更改可能会大大简化。

在修复 bug 1508736 之前,FAILED ResourceGroup 成员的替换在滚动更新的情况下将无法正常工作。