Skip to content

AlertManager-告警

地址1:https://prometheus.io/download/

地址2:https://github.com/prometheus/alertmanager/releases

Alertmanager作为一个独立的组件,负责接收并处理来自Prometheus Server(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方。Alertmanager内置了对邮件,Slack等多种通知方式的支持,同时还支持通过Webhook的方式接入企业微信、钉钉等国内IM工具。

核心功能

  • 告警去重 (Deduplication):自动识别并合并因重复触发而产生的相同告警,避免接收过多的重复信息,减少干扰。
  • 告警分组 (Grouping):将同一时间段内发生的、相关或相似的告警(例如同一服务多个实例的故障)合并为一个通知发送,大幅降低告警通知的数量。
  • 告警路由 (Routing):允许你根据告警的标签(如 severityteamenv)等属性,配置精细化的路由规则,将不同类型的告警发送给不同的接收组或人员(如数据库告警发给 DBA,网络告警发给网络运维团队)。
  • 告警抑制 (Inhibition):允许设置规则,在特定条件下自动抑制某些次要告警。例如,当整个集群不可用(严重告警)时,可以抑制该集群内部所有具体服务的警告告警,避免告警风暴。
  • 静默 (Silencing):提供临时静默特定告警的功能,通常在计划内维护期间使用,避免收到不必要的告警通知。

核心组件流程

mermaid
flowchart TD
    A[Prometheus 生成告警] --> B[Alertmanager 接收告警<br>通过 HTTP API]
    B --> C[告警去重<br>基于标签和指纹识别重复告警]
    C --> D[告警分组<br>按alertname, instance等标签聚合]
    D --> E[告警路由<br>根据标签匹配路由规则]
    E --> F[抑制判断<br>检查抑制规则]
    F --> G{静默判断?}
    G -- 是 --> H[丢弃告警]
    G -- 否 --> I[通知发送]
    I --> J[邮件 Email]
    I --> K[Slack]
    I --> L[Webhook]
    I --> M[其他接收器]
  1. 告警生成与发送:Prometheus Server 根据配置的 alerting.rules 文件中的规则,持续评估指标数据。当规则条件持续满足(持续时长由 for 字段指定)后,Prometheus 会将告警状态变为 firing 并通过 HTTP API 将其发送给配置的 Alertmanager。
  2. 告警接收与处理:Alertmanager 接收到告警后,会依次进行去重、分组、路由和抑制判断等处理。
  3. 通知发送:处理后的告警会根据路由规则,发送给配置的接收器 (Receiver),接收器定义了告警的具体发送方式,如邮件、Slack、Webhook 等。

主要配置说明

Alertmanager 的核心配置文件是 alertmanager.yml,主要包含以下部分:

  • 全局配置 (global):设置一些全局参数,如 SMTP 服务器(用于邮件通知)、Slack Webhook URL、默认的告警解决超时时间 (resolve_timeout) 等。
    yaml
    global:
      smtp_smarthost: 'smtp.qq.com:465'
      smtp_from: 'your-email@qq.com'
      smtp_auth_username: 'your-email@qq.com'
      smtp_auth_password: 'your-auth-code' # 注意是授权码而非登录密码
      smtp_require_tls: false
      resolve_timeout: 5m
  • 路由配置 (route):定义告警的路由树,这是配置的核心。
    yaml
    route:
      receiver: 'default-receiver' # 默认接收器
      group_by: ['alertname', 'instance'] # 按告警名和实例分组
      group_wait: 30s # 初次等待时间,等待同一组的更多告警
      group_interval: 5m # 同一组告警发送新通知的间隔时间
      repeat_interval: 1h # 重复发送相同告警的间隔时间
      routes: # 子路由
      - match: # 简单匹配
          severity: critical
        receiver: 'critical-receiver'
      - match_re: # 正则匹配
          service: ^(db|redis).*
        receiver: 'database-team-receiver'
  • 接收器配置 (receivers):定义具体的告警通知方式和目标。
    yaml
    receivers:
    - name: 'default-receiver'
      email_configs:
      - to: 'ops-team@example.com'
        send_resolved: true # 是否发送恢复通知
    - name: 'critical-receiver'
      slack_configs:
      - api_url: 'https://hooks.slack.com/services/...'
        channel: '#critical-alerts'
        send_resolved: true
    - name: 'database-team-receiver'
      webhook_configs:
      - url: 'http://webhook-url/endpoint'
        send_resolved: false
  • 抑制规则 (inhibit_rules):用于配置告警抑制。
    yaml
    inhibit_rules:
    - source_match: # 当存在源告警...
        severity: 'critical'
      target_match: # 则抑制目标告警...
        severity: 'warning' # 例如抑制warning级别的告警
      equal: ['alertname', 'instance'] # 要求这些标签匹配才抑制

部署 alertmanager

安装插件

bash
wget https://github.com/prometheus/alertmanager/releases/download/v0.28.1/alertmanager-0.28.1.linux-amd64.tar.gz

tar -xvf alertmanager-0.28.1.linux-amd64.tar.gz
mv alertmanager-0.28.1.linux-amd64 /usr/local/alertmanager

# 创建程序用户
useradd -Ms /sbin/nologin prometheus
chown -R prometheus:prometheus /usr/local/alertmanager

# 创建service管理文件
cat > /usr/lib/systemd/system/alertmanager.service<< 'EOF'
[Unit]
Description=alertmanager
Documentation=https://github.com/prometheus/alertmanager
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable alertmanager --now

# 浏览器访问http://IP:9093/#/alerts

配置Prometheus与Alertmanager通信

Prometheus的配置文件中,alerting模块用于配置Alertmanager地址。当配置完成后,Prometheus会将触发告警规则的警报发送到Alertmanager。

yaml
alerting:
  alertmanagers:
  - static_configs:
    - targets: ['localhost:9093']

修改配置文件需要重启prometheus服务

Prometheus告警规则文件

bash
cd /usr/local/prometheus
mkdir rules

# 制度指定规则自动发现-prometheus.yaml
rule_files:
  - "rules/*.yaml"
  # - "first_rules.yml"
  # - "second_rules.yml"

修改配置文件需要重启prometheus服务

邮箱告警

安装支持程序

bash
dnf install mailx postfix dos2unix -y
dnf -y install openssl-devel libcurl-devel libevent-devel
dnf -y install net-snmp-devel

# 设置开机启动
systemctl enable postfix --now

获取163邮箱授权码

登录邮箱 —>设置 —> 开启POP3/SMTP服务 —> 点击新增授权码

配置alertmanager

yaml
cat > /usr/local/alertmanager/alertmanager.yml << 'EOF'
global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.163.com:25'
  smtp_from: 'alter@163.com'
  smtp_auth_username: 'alter@163.com'
  smtp_auth_password: 'UTQsptz46KGhjANy'
  smtp_require_tls: false
route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 5m
  repeat_interval: 1m
  receiver: 'email'
receivers:
  - name: 'email'
    email_configs:
    - to: 'alter@qq.com'
      send_resolved: true
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']
EOF
systemctl restart alertmanager

配置告警规则

bash
cat > /usr/local/prometheus/rules/gerneral.yaml << 'EOF'
groups:
  - name: general.rules
    rules:
  - alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      severity: error
    annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "instance: {{ $labels.instance }} of job {{ $labels.job }} has been down "
EOF

# 重启服务
systemctl restart prometheus

# 通过浏览器可以查看告警规则是否生效-prometheus主机
http://ip:9090/rules

# 通过浏览器可以查看是否出发告警
http://ip:9090/alerts

机器人WebHook告警

配置 alertmanager.yml

yaml
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'wechat_webhook' # 默认路由指向企业微信接收器
  # receiver: 'dingding_webhook' # 默认路由指向钉钉接收器

  # 可以在这里定义子路由,将不同严重程度的告警路由到不同的接收器
  # routes:
  # - match:
  #     severity: critical
  #   receiver: 'wechat_webhook_critical'

receivers:
- name: 'wechat_webhook'
  webhook_configs:
  - url: 'http://<your-wechat-webhook-service-ip>:<port>/wechat' # 替换为你的 webhook 服务地址
    send_resolved: true # 发送恢复通知

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'cluster', 'service']

配置告警规则

bash
cat > /usr/local/prometheus/rules/gerneral.yaml << 'EOF'
groups:
  - name: general.rules
    rules:
  - alert: InstanceDown
    expr: up == 0
    for: 1m
    labels:
      severity: error
    annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "instance: {{ $labels.instance }} of job {{ $labels.job }} has been down "
EOF

# 重启服务
systemctl restart prometheus

# 通过浏览器可以查看告警规则是否生效-prometheus主机
http://ip:9090/rules

# 通过浏览器可以查看是否出发告警
http://ip:9090/alerts

rule告警规则解析

基本结构

yaml
groups:
- name: example-group  # 告警规则组的名称
  rules:
  - alert: InstanceDown  # 告警名称
    expr: up{job="my-service"} == 0  # PromQL表达式,触发条件
    for: 5m  # 持续满足条件的时间
    labels:  # 自定义标签,用于路由、分组等
      severity: critical
    annotations:  # 告警详情注释,用于通知模板
      summary: "Instance {{ $labels.instance }} 宕机"
      description: "{{ $labels.instance }} 已经宕机超过 5 分钟。"

告警状态

  • Inactive:未触发告警条件。
  • Pending:已满足 expr条件,但未持续 for指定的时间。在此状态下不会通知。
  • Firing:满足 expr条件且持续时间已超过 for。告警会被发送到 Alertmanager 进行处理

PromQL 表达式

这是告警规则的核心,决定了何时触发告警。它基于 Prometheus 的指标和查询语言。

常见表达式示例

  • 实例宕机up{job="my-service"} == 0
  • CPU 使用率过高100 - (avg by(instance)(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
  • 内存不足node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10
  • 磁盘空间不足(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100) < 15
  • 服务实例丢失(基于特定指标)absent(container_last_seen{job="docker_containers", name=~"go-admin"}) == 1

规则组 (groups)

规则文件可以包含多个组(groups),每个组有多个规则(rules)。name字段有助于对规则进行逻辑上的管理

yaml
groups:
- name: host-status-alerts
  rules:
  - alert: HostOutOfDiskSpace
    expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100) < 10
    for: 10m
    labels:
      severity: critical
    annotations:
      summary: "主机磁盘空间不足 (instance {{ $labels.instance }})"
      description: "{{ $labels.instance }} 的根分区磁盘使用率已超过90%,且持续10分钟。当前可用空间仅为 {{ $value }}%。"

  - alert: HostMemoryUsageHigh
    expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 85
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "主机内存使用率过高 (instance {{ $labels.instance }})"
      description: "{{ $labels.instance }} 的内存使用率已超过85%,持续5分钟。当前使用率为 {{ $value }}%。"