当今的互联网应用系统越来越复杂,其中涉及的组件和服务越来越多,需要进行高效、可靠的监控,以保证系统的稳定性和性能。Prometheus 是一款功能强大的开源监控系统,可以实时监控多个维度的指标数据,并支持强大的查询语言和告警机制,是目前广泛使用的云原生应用监控系统之一。
本文档合集《Prometheus 实战:从 0 构建高可用监控平台》将从零开始,手把手教您如何构建一套高可用的 Prometheus 监控平台,涵盖了以下内容:
Prometheus 集群搭建:实现高可用和可扩展的监控系统
动态监控指标:自动发现和注册要监控的目标
告警机制配置:灵活配置告警规则、分组、过滤、抑制,实时通知异常情况
Grafana 可视化展示:直观了解系统运行状态和趋势
本文档合集的目标读者是具有一定 Linux 系统和网络知识的系统管理员和 DevOps 工程师。通过本文档合集的学习,您将掌握 Prometheus 的核心概念和实践技巧,能够快速搭建一套高效、可靠的监控平台,帮助您更好地管理和维护复杂的互联网应用系统。
本文以下内容是基于 Alertmanager 灵活配置告警规则、分组、过滤、抑制。
Alertmanager
Alertmanager 是 Prometheus 生态系统中的一个组件,用于处理告警信息。Alertmanager 的主要作业包括以下几个方面:
接收告警信息:Alertmanager 从 Prometheus 或其他数据源接收告警信息,并对其进行处理。
分组和去重:Alertmanager 可以根据标签对告警信息进行分组,并去除重复的告警信息。
通知:Alertmanager 可以通过电子邮件、钉钉、飞书、Webhook 等方式发送告警通知。
告警静默:Alertmanager 允许用户对某些告警规则进行静默处理,以避免过多的告警信息干扰用户。
Alertmanager 是 Prometheus 监控系统中非常重要的一个组件。如果保证它的高可用有以下两种方式:
1 多实例部署
可以将多个 Alertmanager 实例部署在不同的节点上,并使用负载均衡器(例如 Nginx、HAProxy 等)将请求分发到这些实例上。多实例部署可以提高 Alertmanager 的可用性,当某个 Alertmanager 实例故障时,请求可以自动转发到其他正常工作的实例。
2 原生 HA 方案
从 Alertmanager v0.16.0 版本开始,Alertmanager 提供了一种原生的高可用方案,即使用 Raft 算法进行状态同步和故障转移。在原生 HA 方案中,多个 Alertmanager 实例会形成一个 Raft 集群,其中一个实例会被选举为 leader,负责处理请求和写入状态。其他实例则作为 follower,从 leader 同步状态,并在 leader 故障时自动切换为新的 leader。
安装之前的规划,我们这里使用多实例部署的方式完全都能够满足我们的需求。
部署 Alertmanager 服务
node2 和 node3 部署 Alertmanager 服务 操作一样,配置文件也一样。
cd /usr/local/src/
https://github.com/prometheus/alertmanager/releases/download/v0.24.0/alertmanager-0.24.0.linux-amd64.tar.gz
tar xf alertmanager-0.24.0.linux-amd64.tar.gz -C /usr/local/
ln -sv /usr/local/alertmanager-0.24.0.linux-amd64 /usr/local/alertmanager
chown -R prometheus. /usr/local/alertmanager-0.24.0.linux-amd64
mkdir /data/alertmanager
chown -R prometheus. /data/alertmanager
cat > /etc/systemd/system/alertmanager.service <<EOF
[Unit]
Description=alertmanager
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/alertmanager/alertmanager --storage.path=/data/alertmanager/data --config.file /usr/local/alertmanager/alertmanager.yml
Restart=on-failure
LimitNOFILE=655350
LimitNPROC=655350
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start alertmanager
systemctl enable alertmanager
复制代码
生产在用的配置文件
[root@Q-gz-common-prod-thanos-002 alertmanager]# cat alertmanager.yml | grep -v "^#"
route:
#group_by: ['instance']
group_by: ['alertname', 'severity']
group_wait: 10s
group_interval: 3m
# 重新发送相同告警的间隔。比如我主机宕机了,一直没处理,那么就一直有告警,发完第一次后以后每次都要等repeat_interval时间才会发送第二次。
repeat_interval: 5m
# 比如一个分组同时有A、B两个告警,A先到达进去group_wait里面等着,在group_wait期间,B也进来了,两个合并成一组,并发送一个告警消息出去;发完后A、B的问题还未解决,还持续触发告警,然后分组内又来了个新告警C,这就触发了group_interval,由于同组的状态发生了变化,A、B、C会在group_interval内被快速推送告警,不会等到group_interval后再发;如果发完后,A、B、C三者都持续无变化,那么就会在repeat_interval周期性发送告警信息。
receiver: 'web.hook.prometheusalert'
routes:
- receiver: txsms
continue: true
group_wait: 30s
matchers:
- severity="critical"
#- receiver: flashcat
# continue: true
# group_wait: 30s
# matchers:
# - severity="error"
# 配置其他级别的告警通知
- receiver: web.hook.prometheusalert
continue: true
group_wait: 10s
matchers:
- severity=~".*"
receivers:
- name: 'web.hook.prometheusalert'
webhook_configs:
- url: 'http://10.2.0.27:18080/prometheusalert?type=fs&tpl=prometheus-fs&fsurl=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx'
- name: 'txsms'
webhook_configs:
- url: 'http://10.2.0.27:18080/prometheusalert?type=txdx&tpl=prometheus-dx&phone=1xxxx1,1xxxx2'
send_resolved: true
- name: 'flashcat'
webhook_configs:
- url: 'https://api.flashcat.cloud/event/push/alert/prometheus?integration_key=11111'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'error|warning|info|notice'
equal: ['instance', 'alertname']
- source_match:
severity: 'error'
target_match:
severity: 'warning|info|notice'
equal: ['instance', 'alertname']
- source_match:
severity: 'warning'
target_match:
severity: 'info|notice'
equal: ['instance', 'alertname']
复制代码
下面要基于这个配置说明几个场景
告警级别规划
致命 critical
严重 error
警告 warning
提醒 notice
通知 info
复制代码
Alertmanager 主备模式配置
按照之前的规划, 使用 keepalived+haproxy 的方式,实现 Alertmanager 主备模式,在发生故障的时候进去主备切换。
frontend alertmanager-in
bind *:19093
maxconn 20000
default_backend alertmanager-out
backend alertmanager-out
server alertmanager-1 10.2.0.10:9093 maxconn 20480 weight 10 check inter 10s rise 1 fall 2
server alertmanager-2 10.2.0.41:9093 maxconn 20480 weight 10 check inter 10s rise 1 fall 2 backup
复制代码
配置告警静默规则
inhibit_rules 配置段用于配置告警静默规则,是 Alertmanager 中非常重要的一部分。通过合理配置 inhibit_rules 规则,可以避免向用户发送过多的告警信息,提高告警处理的效率。
上面定义了三个 inhibit_rules 规则,每个规则包含 source_match、target_match 和 equal 三个字段:
第一个规则:当源告警的 severity 为 'critical' 时,目标告警的 severity 为 'error|warning|info|notice',且 instance 和 alertname 相同。这个规则的作用是将严重级别为 'critical' 的告警静默处理,避免向用户发送过多的告警信息。
第二个规则:当源告警的 severity 为 'error' 时,目标告警的 severity 为 'warning|info|notice',且 instance 和 alertname 相同。这个规则的作用是将错误级别为 'error' 的告警静默处理,避免向用户发送过多的告警信息。
第三个规则:当源告警的 severity 为 'warning' 时,目标告警的 severity 为 'info|notice',且 instance 和 alertname 相同。这个规则的作用是将警告级别为 'warning' 的告警静默处理,避免向用户发送过多的告警信息。
基于标签的告警路由配置
路由配置是 Alertmanager 中非常重要的一部分,它定义了告警的路由规则,用于将告警发送到不同的接收者。通过合理配置路由规则,可以将不同级别、不同类型的告警发送到不同的接收者,实现更加灵活、高效的告警处理。
上面的配置定义了两个路由规则:
第一个路由规则将 severity 为 'critical' 的告警发送到接收者 'txsms'。其中 continue: true 表示如果告警被路由到这个接收者后,Alertmanager 会继续尝试将告警路由到其他接收者。group_wait: 30s 表示如果在 30 秒内有相同的告警被触发,则会将这些告警分组,一起发送到接收者。
第二个路由规则将所有级别的告警都发送到默认接收者 'web.hook.prometheusalert'。其中 severity=~".*" 表示匹配所有 severity 级别的告警。group_wait: 10s 表示将 10 秒内相同的告警分组发送到接收者。注意,这个路由规则的 continue: true 表示即使告警已经被路由到其他接收者,也会尝试再次发送到默认接收者。
基于业务需求,可以添加更多的通知渠道和基于不同的级别的告警选择。这里我使用了两个高级通知渠道,短信和飞书。
周期创建告警抑制
在 Alertmanager 中,可以使用 inhibit_rules 选项来创建周期性告警抑制规则。下面是一个示例配置,该配置可以在每个小时的 0 分和 30 分时,对同一个 alertname 和 job 的告警进行周期性抑制,抑制时间为 5 分钟。该配置还包括了一个默认的抑制规则,对于任何两个相同的告警,间隔小于 1 分钟的将被抑制,以避免瞬间重复触发告警。
inhibit_rules:
# 默认的抑制规则,对于任何两个相同的告警,间隔小于 1 分钟的将被抑制
- source_match:
severity: 'critical'
target_match:
severity: 'warning|info'
equal: ['alertname', 'job']
# 抑制时间为 1 分钟
duration: 1m
# 周期性抑制规则,对于同一个 alertname 和 job 的告警,在每个小时的 0 分和 30 分时,间隔小于 5 分钟的将被抑制
- source_match:
severity: 'critical'
target_match:
severity: 'warning|info'
equal: ['alertname', 'job']
# 在每个小时的 0 分和 30 分触发抑制
periods:
- start: 0m
end: 5m
- start: 30m
end: 35m
复制代码
在上面的配置中,inhibit_rules 选项包含了两个告警抑制规则。第一个规则是默认的抑制规则,它使用 duration 属性指定抑制时间为 1 分钟。第二个规则是周期性抑制规则,它使用 periods 属性指定在每个小时的 0 分和 30 分时触发抑制,抑制时间为 5 分钟。
在实际业务中我们可能需要基于标签选创建抑制,而不是每次都去修改配置文件。基于这个需要有两个方式实现。
使用 amtool
# cat amtool_mysql_silence_every_day.sh
#!/bin/bash
# 获取明天的日期并将其与固定时间组合成友好的日期和时间格式
tomorrow_date=$(date -d "+1 day" +%Y-%m-%d)
start_time='01:00:00'
end_time='06:00:00'
datetime_start="$tomorrow_date $start_time"
datetime_end="$tomorrow_date $end_time"
start_point=$(date -d "$datetime_start" +"%Y-%m-%dT%H:%M:%S%:z")
end_point=$(date -d "$datetime_end" +"%Y-%m-%dT%H:%M:%S%:z")
# 定义正则表达式模式,抑制创建者和抑制描述或注释
regex_pattern="module=~mysql.*"
author="admin"
comment="for test"
# 创建amtool命令
command="amtool silence add '$regex_pattern' --start='$start_point' --end='$end_point' -a '$author' -c '$comment'"
# 运行amtool命令
echo "Running command: $command"
eval "$command"
复制代码
使用 api 方式
#author len
#This script for create alertmanager silence every day api!
# shell 占位符, 每天凌晨1点到5点mysql告警静默
AlertmanagerUrl="http://10.2.0.10:9093/api/v2/silences"
SILEBCE_DATA_TEL='{"matchers":[{"name":"alertname","value":"UnusualDiskIOutil","isRegex":false,"isEqual":true}],"startsAt":"%sT17:00:00.000Z","endsAt":"%sT21:00:00.000Z","createdBy":"admin","comment":"mysql_silence","id":null}'
#SILEBCE_MYSQL_TEL='{"matchers":[{"name":"module","value":"mysql.*","isRegex":true}],"startsAt":"%sT17:00:00.000Z","endsAt":"%sT21:00:00.000Z","createdBy":"admin","comment":"mysql_silence","id":null}'
SILEBCE_MYSQL_TEL='{"matchers":[{"name":"module","value":"mysql.*","isRegex":true}],"startsAt":"%sT08:00:00.000Z","endsAt":"%sT09:00:00.000Z","createdBy":"admin","comment":"mysql_silence","id":null}'
TODAY=$(date +%Y-%m-%d)
SILEBCE_DATA=`printf ${SILEBCE_DATA_TEL} ${TODAY} ${TODAY}`
SILEBCE_MYSQL=`printf ${SILEBCE_MYSQL_TEL} ${TODAY} ${TODAY}`
echo ${SILEBCE_MYSQL}
function createSilence() {
curl "${AlertmanagerUrl}" -H "Content-Type: application/json" \
--data "${SILEBCE_DATA}" \
--compressed \
--insecure
}
function createMysqlSilence() {
curl "${AlertmanagerUrl}" -H "Content-Type: application/json" \
--data "${SILEBCE_MYSQL}" \
--compressed \
--insecure
}
createSilence
createMysqlSilence
复制代码
注意,这边使用的主备模式,故原则上两个 Alertmanager 节点都需要创建一样的周期告警抑制, 这样才能保证,主节点挂了后, 从节点没有对应的抑制规则造成大量的告警信息。
评论