警报

警报为在 OpenStack 上运行的资源提供面向用户的监控即服务。这种类型的监控确保您可以自动扩展或缩减实例组,通过 Orchestration 服务,但您也可以将警报用于云资源的健康状况的通用感知。

这些警报遵循三态模型

正常

控制警报的规则被评估为 False

警报

控制警报的规则被评估为 True

数据不足

在评估期间没有足够的数据点来有意义地确定警报状态。

警报定义

警报的定义提供了控制何时应发生状态转换的规则,以及随后要采取的措施。这些规则的性质取决于警报类型。

阈值规则警报

对于传统的基于阈值的警报,状态转换由以下内容控制

  • 一个静态阈值,以及一个比较运算符,例如大于或小于。

  • 用于聚合数据的统计选择。

  • 一个滑动时间窗口,指示您希望回顾多远的时间。

Ceilometer 和 Gnocchi 都支持作为阈值规则警报的数据源。有效的阈值警报是

  • threshold

  • gnocchi_resources_threshold

  • gnocchi_aggregation_by_metrics_threshold

  • gnocchi_aggregation_by_resources_threshold

复合规则警报

复合警报允许用户定义一个警报,该警报具有多个触发条件,使用 andor 关系的组合。

警报维度

一个相关的概念是维度的概念,它定义了馈入警报评估的匹配米表集合。回想一下,米表是按资源实例的,因此在最简单的情况下,警报可以定义在应用于特定用户可见的所有资源的特定米表上。然而,更有用的是显式选择您感兴趣的特定资源进行警报。

在极端情况下,您可能具有狭义维度的警报,其中此选择只有单个目标(由资源 ID 标识)。在另一个极端情况下,您可以具有宽泛维度的警报,其中此选择标识了许多资源,统计信息在其上进行聚合。例如,从特定镜像启动的所有实例或所有具有匹配用户元数据的实例(后者是 Orchestration 服务识别自动伸缩组的方式)。

警报评估

警报由 alarm-evaluator 服务定期评估,默认情况下为每分钟一次。

警报操作

单个警报的任何状态转换(到 okalarminsufficient data)都可能与其关联一个或多个操作。这些操作有效地向消费者发送一个信号,表明状态转换已发生,并提供一些额外的上下文。这包括新的和以前的状态,以及一些描述相对于阈值的处置原因数据、涉及的数据点数量以及这些数据点的最新数据。状态转换由 alarm-evaluator 检测,而 alarm-notifier 影响实际的通知操作。

HTTP/HTTPS 操作

这些是遥测警报使用的事实上的通知类型,只需向端点发送 HTTP(S) POST 请求,请求正文包含编码为 JSON 片段的状态转换的描述。

OpenStack 服务

用户可以定义一个警报,该警报只需通过直接指定服务 URL 来触发一些 OpenStack 服务,例如 trust+http://127.0.0.1:7070/v1/webhooks/ab91ef39-3e4a-4750-a8b8-0271518cd481/invokeaodh-notifier 将准备 X-Auth-Token 头部,并将包含警报信息的 HTTP(S) POST 请求发送到该 URL。

Heat 自动伸缩

此通知程序与 loadbalancer_member_health 评估程序一起工作。假设,最终用户定义了一个 Heat 模板,其中包含一个自动伸缩组,并且该组中的所有成员都加入到 Octavia 负载均衡器中,以便将高度可用的服务暴露给外部,以便当堆栈扩展或缩减时,Heat 确保新的成员自动加入负载均衡器,并删除旧的成员。但是,此通知程序处理成员失败时,Heat 堆栈可以自动恢复的情况。更多信息 此处

日志操作

这些是 webhook 的轻量级替代方案,其中状态转换只需由 alarm-notifier 记录,主要用于管理员用户的测试目的。

如果上述操作均不满足您的要求,您可以根据 aodh/notifier 文件夹中当前支持的操作来实现您自己的警报操作。

使用警报

警报创建

基于阈值的警报

创建基于 Gnocchi 阈值的警报的示例,基于特定实例的 CPU 利用率上限

$ aodh alarm create \
  --name cpu_hi \
  --type gnocchi_resources_threshold \
  --description 'instance running hot' \
  --metric cpu_util \
  --threshold 70.0 \
  --comparison-operator gt \
  --aggregation-method mean \
  --granularity 600 \
  --evaluation-periods 3 \
  --alarm-action 'log://' \
  --resource-id INSTANCE_ID \
  --resource-type instance

这将创建一个警报,当单个实例的平均 CPU 利用率超过 70% 持续三个 10 分钟周期时,该警报将被触发。在这种情况下,通知只是一个日志消息,但它也可以是 webhook URL。

注意

与单个项目关联的警报名称必须是唯一的。管理员可以限制三个不同状态下的最大操作数,并且禁用普通用户创建 log://test:// 通知程序的能力。这可以防止 Telemetry 服务无意中消耗磁盘和内存资源。

在此示例中,警报评估的滑动时间窗口为 30 分钟。此窗口未固定到墙面时边界,而是锚定在每个评估周期中的当前时间,并随着每个评估周期的滚动而不断前进(默认情况下,这每分钟发生一次)。

注意

警报粒度必须与 Gnocchi 中配置的指标的粒度匹配。

否则,警报将倾向于在 insufficient data 状态中进出,因为计量存储中实际的数据点频率与用于与警报阈值进行比较的统计查询之间存在不匹配。如果需要较短的警报周期,则应在 pipeline.yaml 文件中调整相应的间隔。

其他值得注意的警报属性,可以在创建或后续更新时设置,包括

state

初始警报状态(默认为 insufficient data)。

description

警报规则的自由文本描述(默认为警报规则的概要)。

enabled

如果启用此警报的评估和操作(默认为 True)。

repeat-actions

如果应在警报保持在目标状态时重复通知操作(默认为 False)。

ok-action

当警报状态转换为 ok 时要调用的操作。

insufficient-data-action

当警报状态转换为 insufficient data 时要调用的操作。

time-constraint

用于限制警报评估到一天中的特定时间或一周中的特定天数(表示为带有可选时区的 cron 表达式)。

复合警报

创建复合警报的示例,基于两个基本规则的复合

$ aodh alarm create \
  --name meta \
  --type composite \
  --composite-rule '{"or": [{"threshold": 0.8, "metric": "cpu_util", \
    "type": "gnocchi_resources_threshold", "resource_id": INSTANCE_ID1, \
    "resource_type": "instance", "aggregation_method": "last"}, \
    {"threshold": 0.8, "metric": "cpu_util", \
    "type": "gnocchi_resources_threshold", "resource_id": INSTANCE_ID2, \
    "resource_type": "instance", "aggregation_method": "last"}]}' \
  --alarm-action 'http://example.org/notify'

这将创建一个警报,当两个基本规则中的任何一个满足条件时,该警报将被触发。在这种情况下,通知是一个 webhook 调用。可以通过使用 andor 组合任意数量的基本规则来创建复合规则。此外,复合规则可以包含嵌套条件

注意

请注意复合规则中 resource_id & resource_type 中的下划线,与 CLI 参数 --resource-id & --resource-type 不同。

$ aodh alarm create \
  --name meta \
  --type composite \
  --composite-rule '{"or": [ALARM_1, {"and": [ALARM_2, ALARM_3]}]}' \
  --alarm-action 'http://example.org/notify'

基于事件的警报

创建基于实例电源状态的事件警报的示例

$ aodh alarm create \
  --type event \
  --name instance_off \
  --description 'Instance powered OFF' \
  --event-type "compute.instance.power_off.*" \
  --enable True \
  --query "traits.instance_id=string::INSTANCE_ID" \
  --alarm-action 'log://' \
  --ok-action 'log://' \
  --insufficient-data-action 'log://'

可以在 event_definitions.yaml 文件中找到有效的 event-typetraits 列表。 --query 也可以包含特征的混合,例如创建警报,当实例通电但进入错误状态时

$ aodh alarm create \
  --type event \
  --name instance_on_but_in_err_state \
  --description 'Instance powered ON but in error state' \
  --event-type "compute.instance.power_on.*" \
  --enable True \
  --query "traits.instance_id=string::INSTANCE_ID;traits.state=string::error" \
  --alarm-action 'log://' \
  --ok-action 'log://' \
  --insufficient-data-action 'log://'

警报类型 event 的示例输出

+---------------------------+---------------------------------------------------------------+
| Field                     | Value                                                         |
+---------------------------+---------------------------------------------------------------+
| alarm_actions             | ['log://']                                                    |
| alarm_id                  | 15c0da26-524d-40ad-8fba-3e55ee0ddc91                          |
| description               | Instance powered ON but in error state                        |
| enabled                   | True                                                          |
| event_type                | compute.instance.power_on.*                                   |
| insufficient_data_actions | ['log://']                                                    |
| name                      | instance_on_state_err                                         |
| ok_actions                | ['log://']                                                    |
| project_id                | 9ee200732f4c4d10a6530bac746f1b6e                              |
| query                     | traits.instance_id = bb912729-fa51-443b-bac6-bf4c795f081d AND |
|                           | traits.state = error                                          |
| repeat_actions            | False                                                         |
| severity                  | low                                                           |
| state                     | insufficient data                                             |
| state_timestamp           | 2017-07-15T02:28:31.114455                                    |
| time_constraints          | []                                                            |
| timestamp                 | 2017-07-15T02:28:31.114455                                    |
| type                      | event                                                         |
| user_id                   | 89b4e48bcbdb4816add7800502bd5122                              |
+---------------------------+---------------------------------------------------------------+

注意

要启用事件警报,请参阅 配置

警报检索

您可以通过以下方式显示所有警报(为简洁起见,省略了一些属性)

$ aodh alarm list
+----------+-----------+--------+-------------------+----------+---------+
| alarm_id | type      | name   | state             | severity | enabled |
+----------+-----------+--------+-------------------+----------+---------+
| ALARM_ID | threshold | cpu_hi | insufficient data | low      | True    |
+----------+-----------+--------+-------------------+----------+---------+

在这种情况下,状态报告为 insufficient data,这可能表明

  • 最近过去,尚未收集到有关此实例的米表,用于评估窗口(例如,一个全新的实例)

  • 或者,已识别的实例对拥有警报的用户/项目不可见

  • 或者,只是自警报创建以来,警报评估周期尚未启动(默认情况下,警报每分钟评估一次)。

注意

警报的可见性取决于发出查询的用户关联的角色和项目

  • 管理员可以看到所有警报,无论所有者如何

  • 非管理员用户只能看到与其项目关联的警报(如 OpenStack 中正常的项目隔离)。

警报更新

一旦警报状态稳定下来,我们可能会决定将该条设置为 70% 太低,在这种情况下,可以这样更新阈值(或任何其他警报属性)

$ aodh alarm update ALARM_ID --threshold 75

更改将在下一个评估周期生效,默认情况下,这每分钟发生一次。

可以以这种方式更改大多数警报属性,但还有一个方便的快捷方式来获取和设置警报状态

$ openstack alarm state get ALARM_ID
$ openstack alarm state set --state ok ALARM_ID

随着时间的推移,警报状态可能会经常变化,尤其是在阈值选择接近统计值的趋势时。您可以通过审核 API 跟踪警报在其生命周期中的历史记录

$ aodh alarm-history show ALARM_ID
+-----------+------------------+---------------------------------------------------+----------+
| timestamp | type             | detail                                            | event_id |
+-----------+------------------+---------------------------------------------------+----------+
| TIME_3    | rule change      | {"rule": {"evaluation_periods": 3, "metric":      | EVENT_ID |
|           |                  | "cpu_util", "resource_id": RESOURCE_ID,           |          |
|           |                  | "aggregation_method": "mean", "granularity":600,  |          |
|           |                  | "threshold": 75.0, "comparison_operator": "gt"    |          |
|           |                  | "resource_type": "instance"}}                     |          |
| TIME_2    | state transition | {"transition_reason": "Transition to alarm due 3  | EVENT_ID |
|           |                  | samples outside threshold, most recent:           |          |
|           |                  | 81.4108514719", "state": "alarm"}                 |          |
| TIME_1    | state transition | {"transition_reason": "Transition to ok due to 1  | EVENT_ID |
|           |                  | samples inside threshold, most recent:            |          |
|           |                  | 67.952938019089", "state": "ok"}                  |          |
| TIME_0    | creation         | {"alarm_actions": ["log://"], "user_id": USER_ID, | EVENT_ID |
|           |                  | "name": "cup_hi", "state": "insufficient data",   |          |
|           |                  | "timestamp": TIME_0, "description": "instance     |          |
|           |                  | running hot", "enabled": true, "state_timestamp": |          |
|           |                  | TIME_0, "rule": {"evaluation_periods": 3,         |          |
|           |                  | "metric": "cpu_util", "resource_id": RESOURCE_ID, |          |
|           |                  | "aggregation_method": "mean", "granularity": 600, |          |
|           |                  | "resource_type": "instance"}, "alarm_id":         |          |
|           |                  | ALARM_ID, "time_constraints": [],                 |          |
|           |                  | "insufficient_data_actions": [],                  |          |
|           |                  | "repeat_actions": false, "ok_actions": [],        |          |
|           |                  | "project_id": PROJECT_ID, "type":                 |          |
|           |                  | "gnocchi_resources_threshold", "severity": "low"} |          |
+-----------+------------------+---------------------------------------------------+----------+

警报删除

可以禁用不再需要的警报,以便不再主动评估它

$ aodh alarm update --enabled False ALARM_ID

甚至可以永久删除它(这是一个不可逆的步骤)

$ aodh alarm delete ALARM_ID

调试警报

一个好的起点是在创建或更新警报时添加 --debug 标志。例如

$ aodh --debug alarm create <OTHER_PARAMS>

/var/log/aodh/listener.log 文件中查找状态转换,当事件被触发时。

2017-07-15 07:03:20.149 2866 INFO aodh.evaluator [-] alarm 85a2942f-a2ec-4310-baea-d58f9db98654 transitioning to alarm because Event <id=abe437a3-b75b-40b4-a3cb-26022a919f5e,event_type=compute.instance.power_off.start> hits the query <query=[{"field": "traits.instance_id", "op": "eq", "type": "string", "value": "bb912729-fa51-443b-bac6-bf4c795f081d"}]>.

以下 /var/log/aodh/notifier.log 中的条目也确认事件 ID abe437a3-b75b-40b4-a3cb-26022a919f5e 触发了匹配实例 ID bb912729-fa51-443b-bac6-bf4c795f081d 的查询

2017-07-15 07:03:24.071 2863 INFO aodh.notifier.log [-] Notifying alarm instance_off 85a2942f-a2ec-4310-baea-d58f9db98654 of low priority from insufficient data to alarm with action log: because Event <id=abe437a3-b75b-40b4-a3cb-26022a919f5e,event_type=compute.instance.power_off.start> hits the query <query=[{"field": "traits.instance_id", "op": "eq", "type": "string", "value": "bb912729-fa51-443b-bac6-bf4c795f081d"}]>

aodh alarm-history 如前所述,也会显示转换

$ aodh alarm-history show 85a2942f-a2ec-4310-baea-d58f9db98654
+----------------------------+------------------+--------------------------------------------------------------------------------------------------------------------------+--------------------------------------+
| timestamp                  | type             | detail                                                                                                                   | event_id                             |
+----------------------------+------------------+--------------------------------------------------------------------------------------------------------------------------+--------------------------------------+
| 2017-07-15T01:33:20.390623 | state transition | {"transition_reason": "Event <id=abe437a3-b75b-40b4-a3cb-26022a919f5e,event_type=compute.instance.power_off.start> hits  | c5ca92ae-584b-4da6-a12c-b7a00dd39fef |
|                            |                  | the query <query=[{\"field\": \"traits.instance_id\", \"op\": \"eq\", \"type\": \"string\", \"value\": \"bb912729-fa51   |                                      |
|                            |                  | -443b-bac6-bf4c795f081d\"}]>.", "state": "alarm"}                                                                        |                                      |
| 2017-07-15T01:31:14.516188 | creation         | {"alarm_actions": ["log://"], "user_id": "89b4e48bcbdb4816add7800502bd5122", "name": "instance_off", "state":            | fb31f4c2-e357-44c3-9b6a-bd2aaaa4ae68 |
|                            |                  | "insufficient data", "timestamp": "2017-07-15T01:31:14.516188", "description": "event_instance_power_off", "enabled":    |                                      |
|                            |                  | true, "state_timestamp": "2017-07-15T01:31:14.516188", "rule": {"query": [{"field": "traits.instance_id", "type":        |                                      |
|                            |                  | "string", "value": "bb912729-fa51-443b-bac6-bf4c795f081d", "op": "eq"}], "event_type": "compute.instance.power_off.*"},  |                                      |
|                            |                  | "alarm_id": "85a2942f-a2ec-4310-baea-d58f9db98654", "time_constraints": [], "insufficient_data_actions": ["log://"],     |                                      |
|                            |                  | "repeat_actions": false, "ok_actions": ["log://"], "project_id": "9ee200732f4c4d10a6530bac746f1b6e", "type": "event",    |                                      |
|                            |                  | "severity": "low"}                                                                                                       |                                      |
+----------------------------+------------------+--------------------------------------------------------------------------------------------------------------------------+--------------------------------------+