Prometheus-alertmanager组件使用
警报管理
Alertmanager工作过程
Alertmanager处理从客户端(通常是Prometheus服务器或其它工具的警报)发来的警报,然后Alertmanager对警报进行去重、分组,然后路由到不同的接收器,如电子邮件、短信或SaaS服务(PagerDuty等)。还可以使用Alertmanager管理维护警报。
- 先在Prometheus服务器上编写警报规则,这些规则将使用(exporter)收集的指标并在指定的阈值或标准上触发警报。当指标达到阈值或标准时,生成一个警报并将其推送到alertmanger。告警在Alertmanger上的HTTP端点上接收。
- 收到警报后,alertmanager会处理警报并根据其标签进行路由。一旦路径确定,他们将由Alertmanager发送到外部目的地。如电子邮件、短信等工具。
alertmanager安装配置
配置alertmanager
Alertmanager配置也是基于YAML的配置文件,主要由global,route,receivers这三部分组成。
简单样例(alertmanager.yml)
通过电子邮件发送任何收到的警报到另一个邮箱地址。
global:
smtp_from: 'localhost:25'
smtp_smarthost: 'alertmanager@example.com'
smtp_require_tls: false
route:
receiver: 'email'
receivers:
-name: 'email'
email_configs:
- to: 'alerts@example.com'
templates:
- '/ups/app/monitor/alertmanager/template/*.tmpl'
- global: 全局配置,为其它块设置默认值
- template: 包含保存警报模板的目录列表。由于alertmanager可以发送到各种目的地,因此需要能够自定义警报的外观及其包含的数据
- route: 它告知alertmanager如何处理特定的传入警报。警报根据规则进行匹配然后采取相应的操作。
- receivers(接收器):指定警报的目的地。每个接收器都有一个名称和相关配置
在Prometheus中配置alertmanager
在Prometheus中配置,告诉Prometheus关于Alertmanager的信息。在alerting块中配置alertmanger相关信息。
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- progs:9093 # 对应启动的altermanager节点的9093端口
alerting块包含允许Prometheus识别一个或多个Alertmanager的配置。为此,Prometheus使用与查找抓取目标时相同的发现机制,在默认配置中是static_configs。与监控作业一样,它指定目标列表,此处是主机名progs加端口9093(Alertmanager默认端口)的形式。该列表假定你的Prometheus服务器可以解析progs主机名为IP地址,并且Alertmanager在该主机的端口9093上运行。
监控alertmanager
Alertmanager可以暴露了自身的相关指标作为被监控对象。创建一个作业来监控alertmanager
- job_name: 'alertmanager'
static_configs:
- targets: ['localhost:9093']
这将从http://localhost:9093/metrics收集指标并抓取一系列以alertmanager_为前缀的时间序列数据。这些数据包括按状态分类的警报计数、按接收器分类的成功和失败通知的计数、还可以包含Alertmanager集群状态指标。
添加警报规则
与记录规则一样,警报规则也是在Prometheus服务器中配置加载的规则文件(使用YAML语句定义)。现在rules目录中创建一个新文件node_alerts.yml,以保存节点警报规则为例子进行说明。
在prometheus.yml配置文件中的rule_files块配置加载的规则文件
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "rules/*_rules.yml"
- "rules/*_alerts.yml"
当前使用通配符加载该目录中以_rules.yml
或_alerts.yml
结尾的所有文件。
添加警报规则
vi rules/node_alerts.yml
groups:
- name: node_alerts
rules:
- alert: InstanceDown
expr: up{job="node_exporter"} == 0
for: 10s
labels:
severity: critical
annotations:
summary: Host {{ $labels.instance }} is down!
-
上面指定一个组名为node_alerts的警报规则,该组中的规则包含在rules的块中。
-
每个规则通过alert子句指定它的名称,并且每个警报组中的警报名称必须唯一。
-
触发警报表达式使用expr子句指定。
-
for子句控制在触发警报之前必须为true的时间长度。在这个示例中,指标up{job="node_exporter"}需要在触发警报之前的10秒中内等于0.这限制了警报误报或暂时状态的可能。
-
使用标签(labels)装饰警报,指定要附加到警报的其它标签,这里添加了一个值为critical的severity的标签。警报上的标签与警报的名称组合构成警报的标识
-
注解(annotations)装饰警报,用于展现更多的信息的标签,如描述、处理说明等。这里添加一个名为summary的标签来描述警报
重启Prometheus服务启用新的警报规则
打开web界面查看http://progs:9090/alerts
警报触发
Prometheus以固定时间间隔(由参数evaluation_interval控制)评估所有的规则。默认值1分钟。在每个评估周期内,Prometheus运行每个警报规则中定义的表达式并更新警报状态。
警报状态
- Inactive:警报未激活
- Pending:警报已满足测试表达式条件,但仍在等待for子句指定的持续时间
- Firing:警报已满足测试表达式条件,并且Pending的时间已超过for子句的持续时间
Pending到Firing的转换可以确保警报更有效,且不会来回浮动。没有for子句的警报会自动从Inactive转换为Firing,只需要一个评估周期(evaluation_interval)即可触发。带有for子句的警报将首先转换为Pending,然后转换为Firing,因此至少需要两个评估周期才能触发。
警报的生命周期
- 节点的可能不断变化,每隔一段由scrape_interval定义的时间被Prometheus抓取一次,对我们来说是15秒。
- 根据每个evaluation_interval的指标来评估警报规则,对我们来说还是15秒。
- 当警报表达式为true时(对于上面示例来说节点发生down),会创建一个警报并转换到Pending状态,执行for子句。
- 在下一个评估周期中,如果警报测试表达式仍然为true,则检查for的持续时间。如果超过了持续时间,则警报将转换为Firing,生成通知并将其推送到Alertmanager。
- 如果警报测试表达式不再为true,则Prometheus会将警报规则的状态从Pending更改为Inactive。
alertmanager的警报
通过http://progs:9090/alerts Web界面查看警报及其状态
处于Firing状态的警报已经推送到alertmanager,可以在alertmanager API(http://progs:9093/api/v1/alerts)查看
[root@progs config]# curl http://progs:9093/api/v1/alerts| python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1004 100 1004 0 0 172k 0 --:--:-- --:--:-- --:--:-- 196k
{
"data": [
{
"annotations": {
"summary": "Host 192.168.10.181:9100 is down!"
},
"endsAt": "2020-08-08T02:37:48.046283806Z",
"fingerprint": "2c28fee95b3f434c",
"generatorURL": "http://progs:9090/graph?g0.expr=up%7Bjob%3D%22node_exporter%22%7D+%3D%3D+0&g0.tab=1",
"labels": {
"alertname": "InstanceDown",
"hostname": "192.168.10.181",
"instance": "192.168.10.181:9100",
"job": "node_exporter",
"severity": "critical"
},
"receivers": [
"wechat"
],
"startsAt": "2020-08-08T02:28:48.046283806Z",
"status": {
"inhibitedBy": [],
"silencedBy": [],
"state": "active"
}
},
{
"annotations": {
"summary": "Host is down!"
},
"endsAt": "2020-08-08T02:37:48.046283806Z",
"fingerprint": "550e18fea3ef4d3d",
"generatorURL": "http://progs:9090/graph?g0.expr=avg+by%28job%29+%28up%7Bjob%3D%22node_exporter%22%7D%29+%3C+0.75&g0.tab=1",
"labels": {
"alertname": "InstancesDown",
"job": "node_exporter",
"severity": "critical"
},
"receivers": [
"wechat"
],
"startsAt": "2020-08-08T02:28:48.046283806Z",
"status": {
"inhibitedBy": [],
"silencedBy": [],
"state": "active"
}
}
],
"status": "success"
}
[root@progs config]#
Prometheus为Pending和Firing状态中的每个警报创建指标(ALERT),如下:
添加模板
模板(template)是一种在警报中使用时间序列数据的标签和值的方法,可用于注解和标签。模板使用标准的Go模板语法,并暴露一些包含时间序列的标签和值的变量。标签以变量$labels形式表示,指标的值则是变量$value。
引用时间序列的值
- summary注解中引用instance标签,使用{{$labels.instance}}
- 引用时间序列的值,使用{{$value}}
- 使用humanize函数,它使用指标前缀将数字转换为更易于阅读的形式
路由
将不同属性的警报路由到不同的目的地。默认使用后序遍历路由
下面在alertmanager.yml文件中添加一些路由配置
global:
smtp_from: 'localhost:25'
smtp_smarthost: 'alertmanager@example.com'
smtp_require_tls: false
route:
group_by: ['instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 3h
receiver: 'email'
routes:
- match:
severity: critical
receiver: pager
- match_re:
severity: ^(warning|critical)$
receiver: support_team
receivers:
- name: 'email'
email_configs:
- to: 'alerts@example.com'
- name: 'support_team'
email_configs:
- to: 'support@example.com'
- name: 'pager'
email_configs:
- to: 'pager@example.com'
templates:
- '/ups/app/monitor/alertmanager/template/*.tmpl'
- group_by: 控制Alertmanager分组警报的方式。默认所有警报分成一组
- 示例指定标签instance对警报分组,意味着来自特定实例的所有警报分在一起
- 分组会改变alertmanager的处理行为,当触发新警报时,等待group_wait中指定时间段,以便在触发警报之前是否收到改组的其它警报
- group_interval:在发出警报后,如果收到该分组的下一次评估新警报,alertmanager等待group_interval指定的时间段,再发送新警报。防止警报分组的警报泛滥
- repeat_interval:仅作用于单个警报,等待重新发送相同警报的时间段。不适用警报组
路由表
routes子句列出分支路由。通过标签匹配或正则表达式匹配将警报发送到指定的目的地。路由都是分支,可以继续设置分支路由。
标签匹配
- match:
severity: critical
receiver: pager
将所有severity标签与critical值匹配,并将它们发送到pager接收器。
路由分支
新routes块嵌套已有的routes块中。
routes:
- match:
severity: critical
receiver: pager
routes:
- match:
service: application
receiver: support_team
当新警报severity标签为critical且service标签application都成功匹配时,将警报发送到接收器support_team。
正则表达式匹配
- match_re:
severity: ^(warning|critical)$
receiver: support_team
它匹配severity标签中的warning或critical值。
路由遍历顺序
默认使用后序遍历路由,可以使用continue选项控制路由遍历顺序,该选项控制警报是否先序遍历路由,然后再返回已遍历路由树。continue默认选项为false,即后序遍历路由树。
延申知识点
- 前序遍历(先序):前序遍历可以记为根左右,若二叉树为空,则结束返回。
- 后序遍历:后序遍历可以记为左右根,也就是说在二叉树的遍历过程中,首先按照后序遍历的规则遍历左子树,接着按照后序遍历的规则遍历右子树,最后访问根节点。若二叉树为空,则结束返回。
routes:
- match:
severity: critical
receiver: pager
continue: true
continue: true时,则警报将在此路由中触发(如果匹配),并继续执行下一个相邻路由。
接收器
指定接收警报的目的地。
receivers:
- name: 'pager'
email_configs:
- to: 'pager@example.com'
slack_configs:
- api_url: https://hooks.slack.com/service/ABC123/ABC123/EXAMPLE
channel: '#monitoring'
添加Slack接收器,它会消息发送到Slack实例。示例中任何向pager接收器发送警报的路由都将被发送到Slack的#monitoring频道,并通过电子邮件发送到pager@example.com。
通知模板
使用Go template函数来引用外部模板,从而避免在配置文件中嵌入较长且复杂的字符串。
创建模板文件
cat > /ups/app/monitor/alertmanager/template/slack.tmpl <<-EOF
{{ define "slack.example.text" }}{{ .CommonAnnotations.summary }}{{ end}}
EOF
使用define函数定义了一个新模板,以end结尾,并取名为slack.example.text,然后在模板内的text中复制内容。
引用模板
slack_configs:
- api_url: https://hooks.slack.com/service/ABC123/ABC123/EXAMPLE
channel: '#monitoring'
text: '{{ template "slack.example.text" . }}'
使用了template选项来指定模板的名称。使用模板通知来填充text字段。
silence和维护
silence: 警报静音。当明确知道停止服务以进行维护作业时,并不希望触发警报。这种场景需要用到silence,设定特定时间段内屏蔽触发警报规则。
设置silence的方法
- alertmanager Web控制台
- amtool命令行工具
silence配置过程
alertmanager Web控制台设置silence
新建silence
配置相关属性
amtool工具设置silence
用法
usage: amtool [<flags>] <command> [<args> ...]
View and modify the current Alertmanager state.
Config File: The alertmanager tool will read a config file in YAML format from one of two default config locations:
$HOME/.config/amtool/config.yml or /etc/amtool/config.yml
All flags can be given in the config file, but the following are the suited for static configuration:
alertmanager.url
Set a default alertmanager url for each request
author
Set a default author value for new silences. If this argument is not
specified then the username will be used
require-comment
Bool, whether to require a comment on silence creation. Defaults to true
output
Set a default output type. Options are (simple, extended, json)
date.format
Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST"
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--date.format="2006-01-02 15:04:05 MST"
Format of date output
-v, --verbose Verbose running information
--alertmanager.url=ALERTMANAGER.URL
Alertmanager to talk to
-o, --output=simple Output formatter (simple, extended, json)
--timeout=30s Timeout for the executed command
--version Show application version.
Commands:
help [<command>...]
alert
query* [<flags>] [<matcher-groups>...]
add [<flags>] [<labels>...]
silence
add [<flags>] [<matcher-groups>...]
expire [<silence-ids>...]
import [<flags>] [<input-file>]
query* [<flags>] [<matcher-groups>...]
update [<flags>] [<update-ids>...]
check-config [<check-files>...]
cluster
show*
config
show*
routes [<flags>]
show*
test [<flags>] [<labels>...]
amtool配置文件
默认配置文件路径``$HOME/.config/amtool/config.ymlor
/etc/amtool/config.yml`
# Define the path that `amtool` can find your `alertmanager` instance
alertmanager.url: "http://progs:9093"
# Override the default author. (unset defaults to your username)
author: me@example.com
# Force amtool to give you an error if you don't include a comment on a silence
comment_required: true
comment: default
# Set a default output format. (unset defaults to simple)
output: extended
新建silence
将在Alertmanager的http://progs:9093上添加一个新silence,它将警报与两个标签匹配:自动填充包含警报名称的alertname标签和service标签。并返回一个silence ID
/ups/app/monitor/alertmanager/bin/amtool --comment=testing --alertmanager.url=http://progs:9093 silence add alertname=InstancesGone service=application
- 使用默认config.yml文件添加silence
/ups/app/monitor/alertmanager/bin/amtool silence add alertname=InstancesGone
查询当前的silence列表
/ups/app/monitor/alertmanager/bin/amtool --alertmanager.url=http://progs:9093 silence query