如果大家还没搞定AlertManager与Prometheus的对接,要么看看其他公开教程,要么参考我之前写的部署文档——先把基础环境搭好,后面的配置才好推进。另外,要是这篇文章帮到你了,麻烦点个赞、转个发,多谢老铁们支持!
1 配置Prometheus监控告警规则
要让Prometheus能识别并触发告警,首先得创建监控规则文件,再把规则接入Prometheus,最后验证规则是否生效。
1.1 新建规则存放目录
首先得给告警规则找个专门的存放地方,我习惯在Prometheus挂载到本地磁盘的目录里建个rules
文件夹,这样后续管理规则文件更方便。操作命令如下:

程序员导航
优网导航旗下整合全网优质开发资源,一站式IT编程学习与工具大全网站
# 在Prometheus挂载到本地磁盘的目录中创建rule文件夹,用于存放所有告警规则文件
root@ubuntu2204-98:/usr/local/prometheus_monitor/prometheus# mkdir /usr/local/prometheus_monitor/prometheus/rules
# 给rules目录设置777权限,确保Prometheus服务能正常读写规则文件,避免权限不足导致规则加载失败
root@ubuntu2204-98:/usr/local/prometheus_monitor/prometheus# chmod -R 777 rules
1.2 配置Prometheus加载规则文件
规则目录建好了,Prometheus还不知道这个目录的存在,所以得修改它的主配置文件prometheus.yml
,添加规则文件的路径配置,让Prometheus能加载里面的规则。
root@ubuntu2204-98:/usr/local/prometheus_monitor/prometheus# vi prometheus.yml
# 规则文件配置:指定规则文件的路径,这里匹配/etc/prometheus/rules/目录下所有.rules后缀的文件
rule_files:
- /etc/prometheus/rules/*.rules
1.3 编写主机监控规则
接下来是核心的监控规则配置,我整理了主机常见的8个监控场景,包括内存、CPU、服务器存活、磁盘IO、网络带宽、TCP连接、磁盘分区等,每个规则都定义了触发条件、持续时间、告警级别和提示信息,直接复制到.rules
文件里就能用。
# 主机监控规则组:所有主机相关的告警规则都放在这个组里,组名是hostStatusAlert
groups:
- name: hostStatusAlert
rules:
# 内存使用率告警:计算可用内存占总内存的比例,若使用率超过85%且持续3分钟,触发warning级告警
- alert: MemUsageAlert
expr: 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 85
for: 3m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 内存使用率过高, 请尽快处理!"
description: "{{ $labels.instance }}内存使用率超过85%,当前使用率{{ $value }}%."
btn: "点击查看详情"
link: "grafana.test.com"
# 服务器存活告警:若up指标为0(表示Prometheus无法连接目标主机)且持续1秒,触发warning级告警
- alert: ServUpStatus
expr: up == 0
for: 1s
labels:
severity: warning
annotations:
summary: "{{$labels.instance}} 服务器宕机, 请尽快处理!"
description: "{{$labels.instance}} 服务器延时超过3分钟,当前状态{{ $value }}. "
btn: "点击查看详情"
link: "grafana.test.com"
# CPU使用率告警:计算非空闲CPU占比(100减去空闲CPU比例),超过90%且持续5分钟,触发warning级告警
- alert: CPUUsageAlert
expr: 100 - (avg by (instance,job)(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 5m
labels:
severity: warning
annotations:
summary: "{{$labels.instance}} CPU使用率过高,请尽快处理!"
description: "{{$labels.instance}} CPU使用大于90%,当前使用率{{ $value }}%. "
btn: "点击查看详情"
link: "grafana.test.com"
# 磁盘IO告警:计算磁盘IO时间占比,平均超过90%且持续5分钟,触发warning级告警
- alert: DiskIO
expr: avg(irate(node_disk_io_time_seconds_total[1m])) by(instance,job)* 100 > 90
for: 5m
labels:
severity: warning
annotations:
summary: "{{$labels.instance}} 流入磁盘IO使用率过高,请尽快处理!"
description: "{{$labels.instance}} 流入磁盘IO大于90%,当前使用率{{ $value }}%."
btn: "点击查看详情"
link: "grafana.test.com"
# 流入网络带宽告警:统计非虚拟网卡的接收字节速率,换算后超过100M(102400单位)且持续5分钟,触发warning级告警
- alert: NetworkIN
expr: ((sum(rate (node_network_receive_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance,job)) / 100) > 102400
for: 5m
labels:
severity: warning
annotations:
summary: "{{$labels.instance}} 流入网络带宽过高,请尽快处理!"
description: "{{$labels.instance}} 流入网络带宽持续5分钟高于100M. RX带宽使用量{{$value}}."
btn: "点击查看详情"
link: "grafana.test.com"
# 流出网络带宽告警:统计非虚拟网卡的发送字节速率,换算后超过100M且持续5分钟,触发warning级告警
- alert: NetworkOUT
expr: ((sum(rate (node_network_transmit_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance,job)) / 100) > 102400
for: 5m
labels:
severity: warning
annotations:
summary: "{{$labels.instance}} 流出网络带宽过高,请尽快处理!"
description: "{{$labels.instance}} 流出网络带宽持续5分钟高于100M. RX带宽使用量{$value}}."
btn: "点击查看详情"
link: "grafana.test.com"
# TCP连接数告警:若ESTABLISHED状态的TCP连接数超过10000且持续2分钟,触发warning级告警
- alert: TcpESTABLISHED
expr: node_netstat_Tcp_CurrEstab > 10000
for: 2m
labels:
severity: warning
annotations:
summary: " TCP_ESTABLISHED过高!"
description: "{{$labels.instance}} TCP_ESTABLISHED大于100%,当前使用率{{ $value }}%."
btn: "点击查看详情"
link: "grafana.test.com"
# 磁盘分区使用率告警:计算ext4/xfs格式分区的已用比例,超过90%且持续1分钟,触发warning级告警
- alert: DiskUse
expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 90
for: 1m
labels:
severity: warning
annotations:
summary: "{{$labels.mountpoint}} 磁盘分区使用率过高,请尽快处理!"
description: "{{$labels.instance}} 磁盘分区使用大于90%,当前使用率{{ $value }}%."
btn: "点击查看详情"
link: "grafana.test.com"
1.4 查看Prometheus规则加载情况
配置完规则后,咱们可以通过Prometheus的Web界面验证规则是否加载成功。打开浏览器,访问Prometheus的告警页面(比如我这里是http://192.168.1.98:9220/alerts?search=
),就能看到刚才配置的hostStatusAlert
规则组,下面包含所有子规则(MemUsageAlert、ServUpStatus、CPUUsageAlert等)。
此时所有规则的状态都是Inactive
(未触发),Pending
(待触发)和Firing
(已触发)数量都是0,这说明规则已经成功加载,只是还没满足告警条件。

AI 工具导航
优网导航旗下AI工具导航,精选全球千款优质 AI 工具集
1.5 测试Prometheus告警触发逻辑
为了确认告警机制能正常工作,咱们可以临时修改内存告警的规则,降低触发阈值,让它更容易满足条件。比如把内存使用率阈值从85%改成1%,持续时间从3分钟改成1分钟,具体修改如下:
# 临时修改内存告警规则,降低阈值以快速触发告警,验证机制有效性
groups:
- name: hostStatusAlert
rules:
- alert: MemUsageAlert
expr: 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 1 # 阈值从85%改为1%,极易满足
for: 1m # 持续时间从3m改为1m,缩短等待时间
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} 内存使用率过高, 请尽快处理!"
description: "{{ $labels.instance }}内存使用率超过85%,当前使用率{{ $value }}%."
btn: "点击查看详情"
link: "grafana.test.com"
修改后刷新Prometheus的Web页面,会发现MemUsageAlert
规则先进入Pending
状态——这是因为还没达到1分钟的持续时间,Prometheus在持续检测指标。等1分钟过去后,状态会变成Firing
,说明告警已经触发,这一步就验证了规则配置和触发逻辑都是正常的。
2 配置AlertManager实现邮件告警
Prometheus触发告警后,需要AlertManager来接收告警并发送通知。这里咱们配置AlertManager通过邮件发送告警,步骤包括配置AlertManager主文件和编写邮件模板。
2.1 配置AlertManager主文件
首先进入AlertManager的安装目录,我这里是/usr/local/prometheus_monitor/alertmanager
,先新建一个template
文件夹存邮件模板,再修改主配置文件alertmanager.yml
。
2.1.1 准备目录和文件
# 进入AlertManager安装目录
root@ubuntu2204-98:~# cd /usr/local/prometheus_monitor/alertmanager
# 查看目录下的配置文件,默认应该有alertmanager.yml
root@ubuntu2204-98:/usr/local/prometheus_monitor/alertmanager# ls
alertmanager.yml
# 新建template文件夹,用于存放邮件模板文件
root@ubuntu2204-98:/usr/local/prometheus_monitor/alertmanager# mkdir template
2.1.2 编写AlertManager配置
修改alertmanager.yml
,主要配置3部分:全局参数(邮件服务器信息)、路由规则(告警如何分发)、接收者(谁接收告警)。我这里用163邮箱作为发件方,大家要替换成自己的邮箱信息。
# 修改AlertManager主配置文件,定义邮件告警相关规则
root@ubuntu2204-98:/usr/local/prometheus_monitor/alertmanager# vi alertmanager.yml
global:
resolve_timeout: 5m # 告警解决后,等待5分钟再发送恢复通知,避免频繁变动
# 邮件服务器配置:使用163的SMTP服务,端口465(SSL协议)
smtp_smarthost: 'smtp.163.com:465'
smtp_from: 'xxxx@163.com' # 发件人邮箱(必须是163邮箱,和SMTP服务器匹配)
smtp_auth_username: 'xxxxxx@163.com' # 发件人邮箱账号
smtp_auth_password: 'xxxxxxxxxx' # 邮箱授权密码(不是登录密码,需要在163邮箱设置里开启SMTP并获取)
smtp_require_tls: false # 关闭TLS验证(根据邮箱服务器情况调整,163这里可以关)
# 模板路径配置:指定邮件模板在容器内的路径(我用容器启动AlertManager,所以填容器内路径)
templates:
- '/etc/alertmanager/template/*.tmpl'
# 路由规则:控制告警如何分发
route:
group_by: ['alertname', 'instance', 'severity'] # 按告警名称、目标实例、级别分组,同组告警一起发送
group_wait: 10s # 收到同组告警后,等待10秒再发送,避免一次性发太多
group_interval: 1m # 同组告警再次触发时,间隔1分钟发送
repeat_interval: 360m # 同一告警重复发送的间隔,6小时一次,避免骚扰
receiver: 'mail' # 默认接收者是mail(下面定义的邮件接收)
# 子路由:针对特定级别告警的单独配置,这里匹配warning级告警,用mail接收
routes:
- match:
severity: warning
receiver: mail
# 接收者配置:定义谁接收告警,这里是邮件接收
receivers:
- name: 'mail' # 接收者名称,和上面的路由配置对应
email_configs:
- to: '101536363@qq.com' # 收件人邮箱(可以填多个,用逗号分隔)
html: '{{ template "mail.html" . }}' # 邮件内容使用mail.html模板
headers:
# 邮件主题:根据告警状态动态生成(触发时是WARN,恢复时是INFO)
Subject: '{{ if gt (len .Alerts.Firing) 0 }}[WARN] 报警邮件{{ else if gt (len .Alerts.Resolved) 0 }}[INFO] 恢复邮件{{ else }}[INFO] 无告警状态{{ end }}'
send_resolved: true # 开启恢复通知,告警解决后发送恢复邮件
# 抑制规则:避免重复告警,比如critical级告警触发时,抑制同实例的warning级告警
inhibit_rules:
- source_match:
severity: 'critical' # 源告警级别(高优先级)
target_match:
severity: 'warning' # 目标告警级别(低优先级)
equal: ['alertname','instance', 'severity'] # 只有当这三个标签相同时,才会抑制
2.2 编写邮件模板
邮件模板决定了告警邮件的格式,需要区分“告警触发”和“告警恢复”两种场景,把关键信息(告警名称、级别、机器、时间等)清晰展示出来。模板文件放在之前新建的template
文件夹里,命名为mail.tmpl
。

免费在线工具导航
优网导航旗下整合全网优质免费、免注册的在线工具导航大全
# 编辑邮件模板文件,定义邮件的HTML格式
root@ubuntu2204-98:/usr/local/prometheus_monitor/alertmanager# vi template/mail.tmpl
{{ define "mail.html" }}
# 动态生成邮件标题:根据告警状态显示“告警通知”或“恢复通知”,并标注数量
{{- if gt (len .Alerts.Firing) 0 -}}
标题:告警通知 - {{ .Alerts.Firing | len }} 条告警<br>
{{- else if gt (len .Alerts.Resolved) 0 -}}
标题:告警恢复通知 - {{ .Alerts.Resolved | len }} 条告警已恢复<br>
{{- end }}
# 处理“告警触发”场景:遍历所有Firing状态的告警,输出详细信息
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
========= ERROR =========<br>
告警名称:{{ .Labels.alertname }}<br>
告警级别:{{ .Labels.severity }}<br>
告警机器:{{ .Labels.instance }} {{ .Labels.device }}<br>
告警详情:{{ .Annotations.summary }}<br>
# 时间转换:将UTC时间加8小时(28800秒,单位e9是纳秒),转为北京时间
告警时间:{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
========= 状态 =========<br>
系统状态告警!<br>
========= END =========<br>
{{- end }}
{{- end }}
# 处理“告警恢复”场景:遍历所有Resolved状态的告警,输出详细信息(多了恢复时间)
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
========= INFO =========<br>
告警名称:{{ .Labels.alertname }}<br>
告警级别:{{ .Labels.severity }}<br>
告警机器:{{ .Labels.instance }}<br>
告警详情:{{ .Annotations.summary }}<br>
告警时间:{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
恢复时间:{{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
========= 状态 =========<br>
系统状态告警已恢复!<br>
========= END =========<br>
{{- end }}
{{- end }}
{{- end }}
3 测试邮件告警功能
配置完AlertManager后,咱们手动制造负载触发告警,验证邮件是否能正常发送和恢复。
3.1 手动增加CPU负载
我用的是4核机器,所以创建4个死循环进程来跑计算任务(用bc
命令计算圆周率,比较耗CPU),这样能快速把CPU使用率拉到90%以上,触发CPUUsageAlert
告警。大家根据自己机器的核数调整进程数量。
# 循环创建4个进程,每个进程执行死循环计算(bc -l计算圆周率,耗CPU)
root@ubuntu2204-98:/usr/local/prometheus_monitor# for i in {1..4}; do (while true; do echo "scale=5000; 4*a(1)" | bc -l > /dev/null; done) & done
[1] 1361096 # 进程ID1
[2] 1361097 # 进程ID2
[3] 1361100 # 进程ID3
[4] 1361103 # 进程ID4
# 测试完成后,用kill -9命令杀掉这些进程,避免一直占用CPU
root@ubuntu2204-98:/usr/local/prometheus_monitor# kill -9 1361096 1361097 1361100 1361103
执行完上面的命令后,用top
命令查看CPU使用率,会发现4个bc
进程的CPU占用率都接近100%,系统负载也上来了,满足之前配置的“CPU使用率超过90%且持续5分钟”的告警条件。
3.2 查看告警和恢复邮件
等待5分钟(CPU告警的持续时间)后,先看Prometheus的Web页面,CPUUsageAlert
规则会从Inactive
变成Pending
,再变成Firing
——这说明Prometheus已经把告警发给AlertManager了。
接着查看收件邮箱,会收到一封主题为[WARN]报警邮件
的通知,内容包含告警名称(CPUUsageAlert)、级别(warning)、机器(192.168.1.98:9100)、详情和触发时间,格式和咱们定义的模板一致。
等咱们用kill
命令杀掉bc
进程后,CPU使用率会快速下降。过一会儿,邮箱会收到一封主题为[INFO]恢复邮件
的通知,里面多了恢复时间,说明AlertManager能正常发送恢复通知——到这里,整个邮件告警流程就验证通过了。
结尾
这篇把Prometheus接入AlertManager实现邮件告警的流程讲完了,后面有空的话,我再写一篇把告警接入钉钉、飞书、企业微信的教程——毕竟工作里用这些办公软件接收告警更方便。
说实话,这篇是抽工作间隙和下班时间写的,可能有些地方格式没弄太规整,大家多担待。好在关键的配置步骤和模板都贴出来了,照着做基本没问题,有疑问的话评论区交流~