Prometheus05-Alertmanager

1、Alertmanager 概述

  • Alertmanager 是 Prometheus 的核心组件之一,专门用于处理由 Prometheus Server 等客户端发送的警报。它将警报的进行聚合、去重、分组、静默、抑制和路由分发等操作。确保用户能够收到有意义的警报通知,而不是被海量的、重复的警报信息淹没,从而帮助运维和开发人员快速定位和响应问题

2、Prometheus 告警流程概述

  • Prometheus 服务器中的告警规则(alter rule)会将告警发送给 Alertmanager。然后由 Alertmanager 负责管理这些告警,包括分组、去重、静默、抑制、以及通过电子邮件、值班通知系统和聊天平台等方式发送通知

3、altermanagre告警机制

  • Prometheus Server 根据配置的 alerting rules 定期评估表达式。当规则条件满足时(例如:up{job="node"} == 0),它会生成一个警报(Alert),但其状态为 Pending。在持续满足条件一段时间(for 子句)后,警报状态变为 Firing。
  • 警报发送:状态变为 Firing 的警报会被 Prometheus Server 通过 HTTP API 发送到配置的 Alertmanager 集群。
  • 警报处理:Alertmanager 接收到警报后,开始执行其核心逻辑:
    • 分组 (Group):将相似性质的警报合并为一个通知。例如,同一个集群、同一种故障类型(如所有节点的磁盘使用率超过90%)的警报会被分到同一组。这可以避免一次性收到大量重复的通知。
    • 抑制 (Inhibit):是一种特殊的静默逻辑,当某个更高级别的警报发生时,可以自动静音其他低级别的相关警报。例如,当整个集群不可用(severity: page)时,抑制所有与该集群节点、服务相关的低级警告(severity: warning),因为根本原因已经明确,无需再收到无关紧要的通知。
    • 静默 (Silence):允许用户在一定时间内手动屏蔽特定条件的警报。例如,在进行计划内维护时,可以提前创建静默规则来避免收到无关的警报通知。
    • 去重 (Deduplication):避免接收端因为同一个原因收到多个重复的警报通知。
    • 路由与通知:处理后的警报会根据配置的路由树 (Route Tree) 被发送到正确的接收器(Receiver),如 Slack、Email、PagerDuty、Webhook 等。

4、告警管理方式

  • Prometheus 判断是否是同一个告警,依据 alertname + labels
例如:以下是两个告警
InstanceDown{instance="node1"}
InstanceDown{instance="node2"}

告警分组

  • AlertManager将同类型的告警进行分组,合并多条告警到一个通知中。避免接收大量告警信息,阻碍故障定位
  • 告警分组、告警时间和告警接收器均是通过Alertmanager的配置文件来完成配置的
  • 示例:数据库集群中有100个实例,其中一个挂掉会触发100个警报。通过分组(按 alertname=DatabaseDown 和 cluster 标签),Alertmanager 只会发送一条通知:“集群A中有100个数据库实例宕机”,而不是100条单独的通知。

告警抑制

  • 防止不必要的低级警报干扰,突出核心问题。
  • 在alertmanager.yml中通过inhibit_rules配置
inhibit_rules:
  - source_match: # 源警报(高级别警报)
      severity: 'critical' # 匹配严重级别为 critical 的警报
    target_match: # 目标警报(低级别警报)
      severity: 'warning' # 匹配严重级别为 warning 的警报
    equal: ['cluster', 'alertname'] # 当源警报和目标警报的cluster和alertname标签值相同时,才会抑制目标告警

静默 (Silence):

  • 目的:临时关闭特定警报的通知。
  • 操作:通过 Alertmanager 的 Web UI 或 API 创建。静默是基于匹配器(Matcher)的,可以静默所有匹配特定标签(如 service="app1", environment="dev")的警报。
  • 特性:静默是临时性的,需要设置静默的结束时间。

路由 (Rout):

  • 目的:定义警报应该如何被分发,以及分发给谁。
  • 结构:一个树状结构。每个路由节点可以有自己的匹配器、接收器、分组规则等。
  • 默认路由:所有警报如果没有匹配到任何子路由,都会落到默认路由,并发送给默认的接收器(如一个公共的邮件组)。
  • 子路由:可以创建更具体的路由。例如,将所有 team=frontend 标签的警报路由到 frontend-team 的 Slack 频道;将所有 severity=critical 的警报路由到 PagerDuty,触发电话呼叫。

接收器 (Receiver):

  • 定义了警报通知的发送目的地和方式。Alertmanager 支持多种集成的接收器:
    • Email:通过 SMTP 发送邮件。
    • Slack:发送消息到 Slack 频道。
    • PagerDuty / OpsGenie:发送到运维调度和呼叫系统。
    • Webhook:一种通用方式,可以将警报信息以 HTTP POST 请求的形式发送给任何自定义系统(如钉钉、微信、飞书等机器人)。
    • Pushover、VictorOps 等。

5、实现告警和通知

5.1、安装altermanager

1.解压安装alertmanager

wget https://github.com/prometheus/alertmanager/releases/download/v0.31.1/alertmanager-0.31.1.linux-amd64.tar.gz
tar -zxf alertmanager-*.tar.gz -C /usr/local
cd /usr/local
chown -R root:root alertmanager-*
ln -sv alertmanager-0.31.1.linux-amd64 alertmanager
cd alertmanagre
./alertmanager --version

2.systemctl管理 altermanagre

cat <<EOF> /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=Prometheus Alertmanager Service
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/local/alertmanager/alertmanager \
--config.file="/usr/local/alertmanager/alertmanager.yml" \
--storage.path="/usr/local/alertmanager/data/" \
--data.retention=120h \
--web.external-url="http://192.168.40.52:9093" \
--web.listen-address="0.0.0.0:9093"
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start alertmanager

3.查看状态

http://192.168.40.51:9093

image

5.2、配置altermanager

配置文件结构

  • alertmanager.yaml配置文件包括global,templates,route,receivers等
    • global块,包含Alertmanager的全局配置
    • template块,用于指定保存警报模板的路径
    • route块,规定了将告警发送到receiver指定的目的地址的规则
    • 通过浏览器访问 “https://prometheus.io/webtools/alerting/routing-tree-editor/”,粘贴Alertmanager配置文件内容到编辑工具中,点击“Draw Routing Tree”按钮即可看到路由结构信息。
    • receivers块,指定警报目的地,每个receiver需要设置一个全局唯一名称,并且对应一个或者多个通知方式,包括邮箱、微信、PagerDuty、Webhook等
    • templates块,告警模板可以自定义告警通知的格式及其包含的对应告警数据,在templates路径下存放模板文件
    • inhibit_rules块,配置告警抑制

配置文件语法检查

  • 使用alertmanager自带的工具检查配置文件语法
cd /usr/local/alertmanager
./amtool check-config alertmanager.yml

配置文件示例

global:
  # 全局配置,可作为其他配置项的默认值
  smtp_smarthost: 'smtp.qq.com:465' # QQ邮箱SMTP服务器地址,465为非ssl端口
  smtp_from: '943720621@qq.com'     # 发件人
  smtp_auth_username: '943720621@qq.com'
  smtp_auth_password: 'horovhvzqfejbbjd'
  smtp_require_tls: false           # 禁用TLS
  resolve_timeout: 5m               # 告警超时时间:5分钟未解决,更新则标记为“已解决”

# 路由树根节点
route:
  # 按告警名称分组
  group_by: ['alertname']
  # 同一组警报等待多久才发送(以便更多警报被分组进来)
  group_wait: 30s
  # 同一组警报首次发送后,等待多久才发送新产生的同类警报
  group_interval: 5m
  # 如果一条警报已成功发送,等待多久才重新发送(即使没有变化)
  repeat_interval: 4h
  # 默认的接收器
  receiver: 'tset-email'

  # 子路由
  routes:
    # 子路由 1:将前端团队的路由到 Slack
    - receiver: 'frontend-slack'
      match:
        team: 'frontend'
      # 继续匹配其他路由? false 表示匹配到此为止
      continue: false

    # 子路由 2:将所有严重级别为 critical 的路由到 PagerDuty
    - receiver: 'team-pager'
      match_re:
        severity: ^(critical|page)$

# 抑制规则
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['cluster', 'alertname']

# 接收器列表
receivers:
  - name: 'test-email'
    email_configs:
      - to: 'xxx@163.com'  # 可写多个,逗号隔开
    send_resolved: true  # 发送“已解决”通知(告警恢复后,主动告知收件人)
	
	
  - name: 'team-default-email'
    email_configs:
      - to: 'team-alerts@example.com'

  - name: 'frontend-slack'
    slack_configs:
      - channel: '#frontend-alerts'
        send_resolved: true # 是否发送恢复通知

5.3、prometheus与alertmanager通信

配置prometheus.yaml

vim prometheus.yml
# 指定alertmanager地址
alerting:
  alertmanagers:
    - static_configs:
        - targets:
           - 192.168.40.52:9093

# 指定报警规则所用文件
rule_files:
  - "./alert_rules/*.yaml"

# 设置一个node_exporter
scrape_configs:
  - job_name: "node-exporter"
    static_configs:
      - targets: ["192.168.40.52:9100"]
        labels:
          app: "node"

创建报警规则模板文件

groups:
- name: AllInstances
  rules:
  - alert: 实例下线
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      title: Instance down
      description: 实例已下线超过1分钟

- name: node_alert
  rules:
  - alert: cpu警报
    expr: 100 - avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) * 100 > 20
    for: 10s
    labels:
      level: warning
    annotations:
      description: "实例: {{ $labels.instance }} ,cpu使用率过高! value: {{ $value }}"
      summary: cpu使用率过高
instance_down.yaml
cat <<EOF> /usr/local/prometheus/rule/instance_down.yaml
groups:
- name: AllInstances
  rules:
  - alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      title: Instance down
      description: Instance has been down for more than 1 minute.

- name: node_alert
  rules:
  - alert: cpu_alert
    expr: 100 - avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) * 100 > 80
    for: 5m
    labels:
      level: warning
    annotations:
      description: "instance: {{ $labels.instance }} ,cpu usage is too high ! value: {{ $value }}"
      summary: cpu usage is too high
EOF
- 在prometheus web ui 查看 ![image](https://img2024.cnblogs.com/blog/1624709/202603/1624709-20260305131245276-1416588005.png)

测试报警

  • 将node_expertor停止,模拟实例下线。收到报警后再启动node_exporter,模拟重新上线

  • 下线告警和恢复告警如图
    image
    image

  • 提高CPU使用率,模拟cpu异常

apt install stress-ng -y
stress-ng --cpu 1 --cpu-load 30 &
pkill stress-ng
  • 下线告警和恢复告警如图
    image
    image

6、使用告警模板自定义告警页面

配置alertmanager

  • 指定所使用的告警模板,自定义邮件主题和内容
vim alertmanager.yaml

receivers:
- name: email-alert
  email_configs:
  - to: "xxx@163.com"
    from: "xxx@qq.com"
    smarthost: "smtp.qq.com:465"
    headers:
      # 邮件主题为模板中指定
      Subject: '{{ template "email.default.subject" . }}'
    # 邮件内容为模板指定
    html: '{{ template "email.default.html" . }}'
# 指定引用的模板位置
templates:
  - '/usr/local/alertmanager/template/*.tmpl'

创建告警模板

  • 修改模板后需要重启alertmanager生效
mkdir /usr/local/alertmanager/template

cat <<EOF> /usr/local/alertmanager/template/email.tmpl
{{ define "email.default.subject" }}
[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}
{{ end }}

{{ define "email.default.html" }}
<h3>Prometheus Alert</h3>

<p><b>Status:</b> {{ .Status }}</p>
<p><b>Alert:</b> {{ .CommonLabels.alertname }}</p>
<p><b>Instance:</b> {{ .CommonLabels.instance }}</p>
<p><b>Severity:</b> {{ .CommonLabels.severity }}</p>

{{ range .Alerts }}
<p><b>Description:</b> {{ .Annotations.description }}</p>
<p><b>Value:</b> {{ .Annotations.Value }}</p>
{{ end }}

{{ end }}
EOF
  • 自定义告警页面
    image

7、告警状态

Inactive

  • 没有满足告警表达式条件,告警未激活

Pending

  • 已满足触发条件,但未满足告警持续时间,即未满足告警中for子句中指定的持续时间
  • Pending的作用是避免瞬时抖动导致误报
    image

Firing

  • 表达式满足且持续时间超过 for 指定时间

·带有for子句的告警将首先转换为Pending状态,然后转换为Firing状态,至少需要两个计算周期告警才被触发。
·从Pending状态到Firing状态的转换,确保了告警的有效性。
·没有for子句的告警会自动从Inactive状态转换为Firing状态,只需要一个计算周期即可被触发。

告警期间prometheus生成的指标

image

ALERTS指标

  • Prometheus 会自动生成一个内部指标:ALERTS
  • 用于表示当前告警状态,可以在 PromQL 查询,可以用于 Grafana 面板
# 格式
ALERTS{
  alertname="<alert name>",
  alertstate="pending|firing",
  <labels>
}

# 例如
ALERTS{
  alertname="InstanceDown",
  alertstate="firing",
  instance="192.168.40.52:9100",
  severity="critical"
}

ALERTS_FOR_STATE

  • Prometheus 还会生成另一个指标:ALERTS_FOR_STATE
  • 用于记录 Pending 持续时间
# 示例
ALERTS_FOR_STATE{
  alertname="InstanceDown",
  instance="192.168.40.52:9100"
}

8、告警路由

  • group_wait 新告警等待 30s 聚合
  • group_interval 控制同一告警组中新增告警后的发送间隔。
  • repeat_interval 用于控制告警持续 firing 且没有新告警加入时的重复通知间隔
route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h
  receiver: 'team1'    # 默认告警接收器,如果某个告警 没有匹配任何子 route,就会发送到这个默认 receiver。
  routes:
  - match:
      severity: critical
    receiver: team1
    continue: true     # 表示继续向下路由,否则下边的配置失效
  - match_re:          # 正则匹配
      severity: ^(warning|critical)$
    receiver: team2
receivers:
- name: 'team1'
  email_configs:
    - to: 'team1@example.com'
- name: 'team2'
  email_configs:
    - to: 'team2@example.com'
- name: 'team3'
  email_configs:
    - to: 'team3@example.com'
  • Alertmanager 默认匹配到第一条规则就停止,需要加上continue: true才会继续向下匹配

路由分支

  • 标签severity=critical,告警路由到pager接收器
  • 标签severity=critical,且标签service=app,告警路由到support_team接收器。因为子route继承父route的match条件
route:
  receiver: email
  routes:
    - match:
        severity: critical
      receiver: pager
      routes:
        - match:
            service: app
          receiver: support_team

9、silence(告警静音)

  • 告警静音的目的是让系统知道我们已经停止服务并开始维护,可以使用以下两种方法来设置silence
    • 通过Alertmanager Web控制台
    • 通过amtool命令行工具

通过Alertmanager Web控制台

  • 访问alertmanager Web UI。http://192.168.40.52:9093
  • 新建silence,指定时间和匹配条件。preview alerts可以预览silence的作用范围
    image

通过amtool命令行工具

  • amtool配置文件
    • 默认配置文件路径是$HOME/.config/amtool/config.yml或/etc/amtool/config.yml
alertmanager.url: "http://localhost:9093"
author: abc@example.com
comment_required: true
  • 创建一个 Silence
# 创建一个 Silence,标签为alertname=Instances,service=app的告警被静默
# 必须加comment,对此次静默进行说明
./amtool --alertmanager.url=http://localhost:9093 silence add alertname="Instance" service="app1" --comment="testing"

image

  • 使用amtool创建的silence被设置为1小时后自动过期,可以调整过期时间
  • 时间一定要加Z,表示UTC,不然会报错
# 设置持续时间,持续 2 小时
./amtool --alertmanager.url=http://localhost:9093 silence add alertname="Instance" service="app2" \
--comment="testing" \
--duration=2h

# 指定过期时间
./amtool --alertmanager.url=http://localhost:9093 silence add alertname="Instance" service="app2" \
--comment="testing" \
--end=2026-03-06T18:00:00Z

# 指定开始时间
./amtool --alertmanager.url=http://localhost:9093 silence add alertname=Instances \
--comment="testing" \
--start=2026-03-06T16:00:00Z \
--end=2026-03-06T18:00:00Z
  • 查询有哪些静默规则
./amtool --alertmanager.url=http://localhost:9093 silence query

image

  • 使一个静默过期
./amtool --alertmanager.url=http://localhost:9093 silence expire 7b0b1ef7-4893-4dac-beb7-acb4cfb23ccf

告警接收-企微报警

1.创建企业微信号,创建prometheus应用
2.利用小工具测试在企业微信新建的Prometheus应用是否可用

下载,安装

wget https://raw.githubusercontent.com/OneOaaS/weixin-alert/master/weixin_linux_amd64
chmod +x weixin_linux_amd64
./weixin_linux_amd64 --corpid=ww2f9229e0804f8faf \
--corpsecret=U_HKt5xV7ZPjXTm4aFfDCfAwKguXmyrYhxTJFVTfynU \
--msg="您好,告警测试,感谢工具提供者!" \
--user=LiuZhengWei \
--agentid=1000002

选项说明:
·--corpid:设置为企业微信中记录的“企业ID”。
·--corpsecret:设置为创建的Prometheus应用中记录的“Secret”内容。
·--msg:自定义的信息内容。
·--user:设置为企业微信中使用的成员账号。
·--agentid:设置为创建的Prometheus应用中记录的“AgentId”内容。

运行小工具后,显示结果:{"errcode":0,"errmsg":"ok","invaliduser":""},表示成功发送信息,
同时在企业微信的Prometheus应用也收到了“您好,告警测试,感谢工具提供者!”,
说明企业微信中新建Prometheus应用工作正常。

3.编辑配置alertmanager配置文件

vim alertmanager.yaml
global:
    resolve_timeout: 5m
    # 企业微信API地址
    wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
    # 企业微信中记录的“企业ID”
    wechat_api_corp_id: 'ww2f9229e0804f8faf'
    # 企业微信中创建的Prometheus应用中记录的“Secret”内容
    wechat_api_secret: 'U_HKt5xV7ZPjXTm4aFfDCfAwKguXmyrYhxTJFVTfynU'
route:
    group_by: ['alertname']
    group_wait: 10s
    group_interval: 10s
    repeat_interval: 1h
    receiver: 'wechat'
receivers:
    - name: 'wechat'
        wechat_configs:
            # 告警解除后是否发送通知,默认是false
            - send_resolved: true 
                # 设置为企业微信中的“部门ID”
                to_party: ‘1'
                # 设置为企业微信中创建的Prometheus应用中记录的“AgentId”内容
                agent_id: ‘1000002'
                # 设置为企业微信中记录的“企业ID”,默认为全局配置内容,但建议设置
                corp_id: ‘ww2f9229e0804f8faf'
                # 设置为企业微信中使用的账号
                to_user: ‘LiuZhengWei'
                # 企业微信API地址,建议设置
                api_url: 'https://qyapi.weixin.qq.com/cgi-bin/‘
                # 设置为企业微信中新建的Prometheus应用中记录的“Secret”内容,建议设置,不要使用默认的全局设置
                api_secret: 'U_HKt5xV7ZPjXTm4aFfDCfAwKguXmyrYhxTJFVTfynU'
inhibit_rules:
    - source_match:
            severity: 'critical'
        target_match:
            severity: 'warning'
        equal: ['alertname', 'dev', 'instance’]”
  • 检查配置文件
cd /data/alertmanager
./amtool check-config alertmanager.yml

告警接收-“基于Webhook的钉钉接收告警”

1.创建钉钉机器人
2.prometheus-webhook-dingtalk工具
用于生成DingTalk通知的工具

下载、安装

wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v0.3.0/prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz
tar zxvf prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz -C /data
cd /data/                # 安装路径可以自定义修订
ln -sv prometheus-webhook-dingtalk-0.3.0.linux-amd64 prometheus-webhook-dingtalk
cd /data/prometheus-webhook-dingtalk

前台启动

./prometheus-webhook-dingtalk \
--ding.profile="webhook1=https://oapi.dingtalk.com/robot/send?access_token=xxxxx" \
--ding.profile="webhook2=https://oapi.dingtalk.com/robot/send?access_token=yyyyy”

后台启动

nohup ./prometheus-webhook-dingtalk \
--ding.profile="ops_dingding=https://oapi.dingtalk.com/robot/send?access_token=ca001e3def5af95a5f294a34e3cc0b427ef4c0f139c09a414580b766c0767f8b"&

可以看到默认端口8060已经开启

netstat -antup |grep 8060

·使用./prometheus-webhook-dingtalk-h可以查看帮助
·多次使用--ding.profile可以在命令行中指定多个已经保存好的Webhook地址

3.编辑alertmanager配置文件

cat alertmanager.yml
global:
    resolve_timeout: 5m”
route:
    receiver: webhook
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 4h
    group_by: [alertname]
    routes:
    - receiver: webhook
        group_wait: 10s
        match:
            team: node
receivers:
    - name: webhook
        webhook_configs:
        # 发送HTTP POST请求的端点,也就是以上配置的工具地址
        - url: http://localhost:8060/dingtalk/ops_dingding/send
            send_resolved: true

可以为某些选项创建一个YAML配置文件, 而不必每次都指定--alertmanager.url参数

配置alertmanager集群

am1、am2、am3为三台主句。启动三个alertmanager。要求配置文件完全相同
am1$ alertmanager --config.file alertmanager.yml --cluster.listen-address 172.19.0.10:8001
am2$ alertmanager --config.file alertmanager.yml --cluster.listen-address 172.19.0.20:8001 --cluster.peer 172.19.0.10:8001
am3$ alertmanager --config.file alertmanager.yml --cluster.listen-address 172.19.0.30:8001 --cluster.peer 172.19.0.10:8001

posted @ 2024-05-10 10:15  立勋  阅读(221)  评论(0)    收藏  举报