为 Ironic 和 IPA 添加可插拔指标后端

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

本文档提出为 Ironic 和 Ironic Python Agent (IPA) 添加指标数据报告功能。最初,这将包括一个 statsd 参考实现,但将足够通用,以允许创建替代后端。

问题描述

软件指标对于操作员识别和诊断运行软件中的问题非常有帮助,并且可以用于监控 Ironic 和 IPA 在生产环境中的实时和历史性能。

指标可用于确定系统的哪些部分运行速度快(或慢),错误(例如 API 错误响应或 BMC 故障)发生的频率,或者给定更改的性能影响。

目前,Ironic 和 IPA 都未报告任何应用程序指标。

提议的变更

  • 设计一个共享的可插拔指标报告系统。

  • 实现一个通用的 MetricsLogger,其中包括

    • 量规 (generic numerical data)。

    • 计数器 (increment/decrement a counter)。

    • 计时器 (time something)。

    • 装饰器和上下文管理器。

  • 实现 StatsdMetricsLogger 作为参考后端 [1]。

  • 为 Ironic 增加指标报告,包括

    • API 请求的计数和计时。这可以通过挂钩 Pecan 来实现。

    • RPC 的计数和计时。

    • ConductorManager 中大多数工作函数的计数和计时。

    • 重要驱动函数计数和计时。

    • 计数和计时节点状态更改。通过在状态更改期间检查 provision_updated_at,可以计算节点在该状态下花费的时间。

  • 为 IPA 增加指标报告,包括但不限于

    • 镜像下载/写入计数和时间。

    • 部署/清理计数和时间。

以下是示例代码(基于 Python logging 模块命名约定)

METRICS = metrics.getLogger(__name__)

class Foo(object):
  def func1(self):
    # Emit gauge metric with value 1
    METRICS.send_gauge("one.fish", 1)

    # Increment counter metric by two
    METRICS.send_counter("two.fish", 2)

    # Decrement counter metric by one
    METRICS.send_counter("red.fish", -1)

    # Randomly sample the data (emit metric 10% of the time)
    METRICS.send_counter("blue.fish", 42, sample_rate=0.1)

    # Emit a timer metric with value of 125 (milliseconds)
    METRICS.send_timer("black.fish", 125)

    # Randomly sample the data (emit metric 1% of the time)
    METRICS.send_timer("blue.fish", 125, sample_rate=0.01)

  @METRICS.counter("func2.count")
  @METRICS.timer("func2.time", sample_rate=0.1)
  def func2(self):
    pass

  # Context managers for counting and timing code blocks
  def func3(self):

    with METRICS.counter("func3.thing_one.count", sample_rate=0.25):
      thing_one()

    with METRICS.timer("func3.thing_two.time"):
      thing_two()

指标名称遵循此约定(可选部分用 [] 表示)

[global_prefix.][host_name.]prefix.metric_name

如果设置了 --metrics-agent-prepend-host-reverse,则 host.example.com 将变为 com.example.host,以协助分层数据表示。

例如,使用 Statsd 后端和相关的配置选项,METRICS.send_timer("blue.fish", 125, sample_rate=0.25) 将被发送到 statsd,格式为 globalprefix.com.example.host.moduleprefix.blue.fish:1|ms@0.25

备选方案

或者,我们可以实现一个 Ceilometer 后端。虽然 Ironic 已经向 Ceilometer 报告了一些测量值(例如 IPMI 传感器数据),但本文档中提出的指标不符合 Ceilometer 项目的任务,即“...收集部署云中物理和虚拟资源的利用率测量值...” [2]

相反,本文档提出我们应该对 Ironic/IPA 代码库的某些部分进行工具化,以报告指标和统计信息,关于代码如何/何时运行以及代码的性能。这些数据与“构成已部署云的物理和虚拟资源”没有直接关系。因此,我们不建议添加 Ceilometer 后端,也不建议将现有的 Ceilometer 测量值转换为此系统,因为它们代表了根本不同类型的数据。

数据模型影响

状态机影响

无。

REST API 影响

为了支持 agent 驱动程序,将在 Ironic API 中 /drivers/<drivername>/vendor_passthru/lookup 端点的响应中添加一个配置字段。

该字段将包含 agent 相关的配置选项,agent 可以使用这些选项来配置自身以报告指标数据。例如:statsd 主机和 statsd 端口。

客户端 (CLI) 影响

无。

RPC API 影响

无。

驱动程序 API 影响

无。

Nova 驱动程序影响

无。

Ramdisk 影响

N/A

安全影响

statsd 守护进程 [3] 没有身份验证,因此任何能够向守护进程发送 UDP 数据报的人都可以发送任意指标数据。但是,statsd 守护进程通常配置为仅侦听本地接口,这在一定程度上缓解了安全问题。

其他最终用户影响

无。

可扩展性影响

部署者必须确保他们的 statsd 基础设施相对于其部署规模正确扩展。但是,即使 statsd 守护进程过载,Ironic 也不会受到负面影响(statsd UDP 数据报是非阻塞的,并且将不会被处理)。

性能影响

默认情况下,指标报告将被禁用,从而减少但不完全消除对不希望收集指标的用户造成的性能影响。至少,必须在可以报告指标的每个地方检查一个条件。此外,取决于条件检查发生的具体方式和位置,即使实际上未发送指标数据,也可能会评估参数。

通过 statsd 报告指标对性能的影响很小。发送单个指标数据的开销非常小——特别是,statsd 指标通过 UDP(非阻塞)发送到守护进程 [2],该守护进程会在将其转发到其支持的后端之一之前聚合指标。如果此后端变得无响应或过载,则指标数据将丢失,但不会产生其他性能影响。

在本地 statsd 守护进程聚合指标数据后,它们会定期刷新到 statsd 配置的后端之一,通常是 Graphite [4]。

其他部署者影响

将添加两组不同的配置选项

这些选项将在 ironic-lib 指标库中设置,并将由任何实现指标的 ironic 服务使用

[metrics]

# Backend options are "statsd" and "noop"
backend="noop"
statsd_host="localhost"
statsd_port=8125

# See proposed changes section for detailed description of how these are used
prepend_host=false
prepend_host_reverse=false
global_prefix=""

此外,以下选项将添加到 ironic-conductor 中,并用于配置用于指标查找的 ironic-python-agent

# Backend options are "statsd" and "noop"
agent_backend="noop"
agent_statsd_host="localhost"
agent_statsd_port=8125

# See proposed changes section for detailed description of how these are used
agent_prepend_host=false
agent_prepend_host_reverse=false
agent_prepend_uuid=false
agent_global_prefix=""

如果启用了 statsd 指标后端,则部署者必须安装和配置 statsd,以及他们希望使用的任何其他指标软件(例如 Graphite [3])。此外,如果部署者希望从 ironic-python-agent 发出指标,则 statsd 后端必须可以从 agent 运行的网络访问。

开发人员影响

无。

实现

负责人

主要负责人

alineb

其他贡献者

JayF

工作项

  • 设计/实现 ironic-lib 中的指标报告。

  • 实现 statsd 后端。

  • 为 Ironic 代码增加指标报告。

  • 为 IPA 代码增加指标报告。

依赖项

无。

测试

可能需要额外的注意来测试 statsd 网络代码。

升级和向后兼容性

无。

文档影响

必须编写适当的文档。

参考资料

有关为什么指标对操作员有用以及为什么 statsd 项目开始的原因,请参阅:https://codeascraft.com/2011/02/15/measure-anything-measure-everything/

[1] https://github.com/etsy/statsd/blob/master/docs/metric_types.md

[2] https://wiki.openstack.org/wiki/Ceilometer

[3] https://github.com/etsy/statsd/

[4] https://graphite.readthedocs.org/en/latest/faq.html