文章目录
告警消息转发平台PrometheusAlter
官方站点:https://github.com/feiyu563/PrometheusAlert
手册:https://feiyu563.gitbook.io/prometheusalert
为什么选用PrometheusAlter
- 所有的的配置都是通过configmap维护的,尤其是告警媒介这里需要做很多的配置才能保证告警发送到正确的媒介上,如果需要增加告警媒介可能还需要增加第三方插件(如钉钉)做消息的转发,且每种插件仅支持单个媒介的转发,如果涉及的媒介比较多就需要安装多个插件并配置,不是很灵活。
- AlterManager web UI比较简单,仅支持查看部分内容和信息,不能展示更多的数据信息
PrometheusAlter架构
Exporter > Prometheus > Prometheus Rules > AlterManager > Wehook > PrometheusAlter > Routes > 钉钉、微信、飞书…
优势:
- 配置灵活:通过web UI界面配置操作,相较于configmap较灵活。
- 功能强大::①支持在线修改告警模版,告警路由,告警记录,测试等。②针对Prometheus增加了告警级别,并且支持按照不同级别发送消息到不同目标对象。③简化Prometheus分组配置,支持按照具体消息发送到单个或多个接收方。④增加Dashboard,提供配置测试,告警消息模版自定义,告警模版测试等功能。
- 自定义强度高:①通过路由匹配规则触发更多的告警媒介(企微,钉钉,飞书,公有云电话/短消息接口)。②增加手机号码配置项和号码自动轮询配置,可固定发送给单一个人告警信息,也可以通过自动轮询的方式发送到多个人员且支持按照不同日期发送到不同人员。
- 开源免费:PrometheusAlert 是一款完全开源的软件,可以免费使用和定制,而且有广泛的社区支持。
PrometheusAlter部署
kubernetes中运行
#Kubernetes中运行可以直接执行以下命令行即可(注意默认的部署模版中未挂载模版数据库文件 db/PrometheusAlertDB.db,为防止模版数据丢失,请自行增加挂载配置 )
$ kubectl apply -n monitor -f https://raw.githubusercontent.com/feiyu563/PrometheusAlert/master/example/kubernetes/PrometheusAlert-Deployment.yaml
#启动后可使用浏览器打开以下地址查看:http://[YOUR-PrometheusAlert-URL]:8080
#默认登录帐号和密码在app.conf中有配置
使用helm部署
#clone项目源代码
$ git clone https://github.com/feiyu563/PrometheusAlert.git
$ cd PrometheusAlert/example/helm
#如需修改配置文件,请更新config中的app.conf
#helm部署模版支持配置Ingress域名,可在values.yaml中进行配置
#配置修改完成后,通过以下命令启动即可(注意默认的部署模版中未挂载模版数据库文件 db/PrometheusAlertDB.db,为防止模版数据丢失,请自行增加挂载配置 )
$ helm upgrade --install monitor prometheusalert -n monitor
#启动后可使用浏览器打开以下地址查看: http://[Ingress_url]:[Ingress_port]
#默认登录帐号和密码在app.conf中有配置
使用控制器文件部署
数据保持在持久化存储中,先创建持久化存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prome-alert-data-pvc
namespace: monitor
spec:
accessModes:
- ReadWriteMany
storageClassName: "nfs-storage"
resources:
requests:
storage: 5Gi
下载配置文件
wget https://raw.githubusercontent.com/feiyu563/PrometheusAlert/master/example/kubernetes/PrometheusAlert-Deployment.yaml
###配置
app.conf: |
#---------------------↓全局配置-----------------------
appname = PrometheusAlert
#登录用户名
login_user=admin
#登录密码
login_password=admin123
#监听地址
httpaddr = "0.0.0.0"
#监听端口
httpport = 8080
...
#数据库驱动,支持sqlite3,mysql,postgres如使用mysql或postgres,请开启db_host,db_port,db_user,db_password,db_name的注释
db_driver=mysql
db_host=192.10.192.134
db_port=3306
db_user=root
db_password=XXXXXXXXXXX
db_name=prometheusalert
...
#是否开启告警记录定时删除 0为关闭,1为开启
RecordLive=1
#告警记录定时删除周期,单位天
RecordLiveDay=7
...
#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
#默认企业微信机器人地址
wxurl=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=b3738de5-9f00-45de-9e3d-45e6309bc54c
...
- name: prometheus-alert-db
mountPath: /app/db
- name: prometheus-alert-db
persistentVolumeClaim:
claimName: prome-alert-data-pvc
ingress路由配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus-alert-ing
namespace: monitor
annotations:
prometheus.io/http_probe: "true"
spec:
ingressClassName: nginx
rules:
- host: prometheusalert.kubernets.cn
http:
paths:
- pathType: Prefix
backend:
service:
name: prometheus-alert-center
port:
number: 8080
path: /
部署MySQL作为后端数据存储
k8s部署
## 创建秘钥
kubectl create secret generic mysql-root-password --from-literal=password=mysqlpwd123
## 创建pvc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs-storage
## 创建mysql控制器
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql
name: mysql
namespace: monitor
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-root-password
key: password
# 如果你不想使用secret对象保存mysql登录密码,可以直接使用下面的方式指定,简单粗暴未尝不可
#value: "123456"
ports:
- containerPort: 3306
volumeMounts:
- name: mysqlvolume
mountPath: /var/lib/mysql
volumes:
- name: mysqlvolume
# 使用pvc
persistentVolumeClaim:
claimName: mysql-pvc
---
#定义mysql的Service
apiVersion: v1
kind: Service
metadata:
labels:
app: svc-mysql
name: svc-mysql
namespace: monitor
spec:
selector:
app: mysql
type: ClusterIP
ports:
- port: 3306
protocol: TCP
targetPort: 3306
创建数据库
# 获取 mysql pod
kubectl get pod -n monitor|grep mysql
# 进入 mysql pod
kubectl exec -it mysql-6785bdcf-wsxhn -n monitor /bin/bash
# 在 mysql pod 容器内执行
# 登录 mysql
mysql -uroot -p
# 创建数据库 prometheusalert
CREATE DATABASE prometheusalert CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
kubectl apply -f prometheusalter-storage.yaml
kubectl apply -f PrometheusAlter-Deployment.yaml
获取Prometheusalter.sql
# 获取pod
kubectl get pod -n monitor|grep prometheus
# 进入pod
kubectl exec -it prometheus-alert-center-5d7dfb8c99-h78z4 -n monitor /bin/sh
# 拷贝文件
kubectl cp monitor/prometheus-alert-center-5d7dfb8c99-l48gw:/app/db/prometheusalert.sql /mnt/data-s3-fs/prometheusalert-mysql/data/prometheusalert.sql
导入sql
# 进入 mysql pod
kubectl exec -it mysql-6785bdcf-wsxhn -n monitor /bin/bash
# 在 mysql pod 容器内执行
# 切换到 mysql 数据目录下
cd /var/lib/mysql
# 登录 mysql
mysql -uroot -p
use prometheusalert
source prometheusalert.sql
prometheusAlert配置管理
自定义模板如下
{{ $var := .externalURL}}{{ range $k,$v:=.alerts }}{{if eq $v.status "resolved"}}[PROMETHEUS-恢复信息]({{$v.generatorURL}})
> **[{{$v.labels.alertname}}]({{$var}})**✅
> <font color="info">告警级别:</font> {{$v.labels.severity}}
> <font color="info">开始时间:</font> {{GetCSTtime $v.startsAt}}
> <font color="info">结束时间:</font> {{GetCSTtime $v.endsAt}}
> <font color="info">命名空间:</font> {{$v.labels.namespace}}
> <font color="info">实例名称:</font> {{$v.labels.pod}}
> <font color="info">实例地址:</font> {{$v.labels.instance}}
> <font color="info">**{{$v.annotations.description}}**</font>{{else}}[PROMETHEUS-告警信息]({{$v.generatorURL}})
> **[{{$v.labels.alertname}}]({{$var}})**🔥
> <font color="#FF0000">告警级别:</font> {{$v.labels.severity}}
> <font color="#FF0000">开始时间:</font> {{GetCSTtime $v.startsAt}}
> <font color="#FF0000">命名空间:</font> {{$v.labels.namespace}}
> <font color="#FF0000">实例名称:</font> {{$v.labels.pod}}
> <font color="#FF0000">实例地址:</font> {{$v.labels.instance}}
> <font color="#FF0000">**{{$v.annotations.description}}**</font>{{end}}{{ end }}
{{ $urimsg:=""}}{{ range $key,$value:=.commonLabels }}{{$urimsg = print $urimsg $key "%3D%22" $value "%22%2C" }}{{end}}[✍点我屏蔽该告警](http://alertmanager.kubernets.cn/#/silences/new?filter=%7B{{SplitString $urimsg 0 -3}}%7D)
在自定义模板中选择自己需要的模板
自定义模板内容分两部分:告警和回复,用不同的颜色做区分
新增自定义模板
{{ $var := .externalURL}}{{ range $k,$v:=.alerts }}{{if eq $v.status "resolved"}}[PROMETHEUS-恢复信息]({{$v.generatorURL}})
> **[{{$v.labels.alertname}}]({{$var}})**✅
> <font color="info">告警级别:</font> {{$v.labels.severity}}
> <font color="info">当前状态:</font> **<font color="#67C23A">已恢复</font>**
> <font color="info">开始时间:</font> {{GetCSTtime $v.startsAt}}
> <font color="info">结束时间:</font> {{GetCSTtime $v.endsAt}}
> <font color="info">实例地址:</font> {{$v.labels.instance}}
> <font color="info">**{{$v.annotations.description}}**</font>{{else}}[PROMETHEUS-告警信息]({{$v.generatorURL}})
> **[{{$v.labels.alertname}}]({{$var}})**🔥
> <font color="#FF0000">告警级别:</font> {{$v.labels.severity}}
> <font color="#FF0000">当前状态:</font> **<font color="#E6A23C">需要处理</font>**
> <font color="#FF0000">开始时间:</font> {{GetCSTtime $v.startsAt}}
> <font color="#FF0000">实例地址:</font> {{$v.labels.instance}}
> <font color="#FF0000">**{{$v.annotations.description}}**</font>{{end}}{{ end }}
{{ $urimsg:=""}}{{ range $key,$value:=.commonLabels }}{{$urimsg = print $urimsg $key "%3D%22" $value "%22%2C" }}{{end}}[✍点我屏蔽该告警](http://alertmanager.kubernets.cn/#/silences/new?filter=%7B{{SplitString $urimsg 0 -3}}%7D)
告警测试
平台为了方便专门提供了webui的测试
点击告警测试,就会提示告警已发送
同时对应的告警媒介也会受到对应的测试告警信息
告警路由
之前的内容我们通过label匹配告警,对应labels发送到对应的告警媒介中以及对应的告警接收人
标签可以采用正则的写法匹配对应的机器标签,需要注意的是前后不能有空格
配置Alertmanager接入PrometheusAlert
更新alertmanager配置,将所有的告警均指向告警分发平台
apiVersion: v1
kind: ConfigMap
metadata:
name: alertmanager-config
namespace: monitor
data:
alertmanager.yml: |-
global:
resolve_timeout: 1m
smtp_smarthost: 'smtp.exmail.qq.com:465' # 邮箱服务器的SMTP主机配置
smtp_from: 'zhdya@zhdya.cn' # 发送邮件主题
smtp_auth_username: 'zhdya@zhdya.cn' # 登录用户名
smtp_auth_password: 'yfXBXXXXX3DwYTjn' # 此处的auth password是邮箱的第三方登录授权密码,而非用户密码
smtp_require_tls: false # 有些邮箱需要开启此配置,这里使用的是企微邮箱,仅做测试,不需要开启此功能。
templates:
- '/etc/alertmanager/*.tmpl'
route:
group_by: ['env','instance','type','group','job','alertname','cluster']
group_wait: 10s
group_interval: 2m
repeat_interval: 10m
receiver: 'webhook'
receivers: #定义一个全局的receivers,就是PrometheusAlter,会接收所有的Prometheus告警,告警到PrometheusAlter告警平台之后会做第二次路由匹配将不同标签的告警路由到不同的媒介
- name: 'webhook'
webhook_configs:
- url: 'http://prometheus-alert-center.monitor.svc:8080/prometheusalert?type=wx&tpl=prometheus-wx&wxurqq.com/cgi-bin/webhook/send?key=71c0a6f0-43a0-4ecf-b8c9-52aff88f3b68&at=ZhangDaDan,ZHDYA' #有特定的格式具体参考下部分代码解释
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
wechat.tmpl: |-
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 监控报警 =========
告警状态:{{ .Status }}
告警级别:{{ .Labels.severity }}
告警类型:{{ $alert.Labels.alertname }}
故障主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
触发阀值:{{ .Annotations.value }}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
========= = end = =========
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
========= 告警恢复 =========
告警类型:{{ .Labels.alertname }}
告警状态:{{ .Status }}
告警主题: {{ $alert.Annotations.summary }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
========= = end = =========
{{- end }}
{{- end }}
{{- end }}
{{- end }}
email.tmpl: |-
{{ define "email.from" }}xxx.com{{ end }}
{{ define "email.to" }}xxx.com{{ end }}
{{ define "email.to.html" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{ range .Alerts }}
========= 监控报警 =========<br>
告警程序: prometheus_alert <br>
告警级别: {{ .Labels.severity }} <br>
告警类型: {{ .Labels.alertname }} <br>
告警主机: {{ .Labels.instance }} <br>
告警主题: {{ .Annotations.summary }} <br>
告警详情: {{ .Annotations.description }} <br>
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }} <br>
========= = end = =========<br>
{{ end }}{{ end -}}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{ range .Alerts }}
========= 告警恢复 =========<br>
告警程序: prometheus_alert <br>
告警级别: {{ .Labels.severity }} <br>
告警类型: {{ .Labels.alertname }} <br>
告警主机: {{ .Labels.instance }} <br>
告警主题: {{ .Annotations.summary }} <br>
告警详情: {{ .Annotations.description }} <br>
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }} <br>
恢复时间: {{ .EndsAt.Format "2006-01-02 15:04:05" }} <br>
========= = end = =========<br>
{{ end }}{{ end -}}
{{- end }}
关键字段说明
receivers:
- name: 'webhook'
webhook_configs:
- url: 'http://prometheus-alert-center.monitor.svc:8080/prometheusalert?type=wx&tpl=prometheus-wx&wxurqq.com/cgi-bin/webhook/send?key=71c0a6f0-43a0-4ecf-b8c9-52aff88f3b68&at=ZhangDaDan,ZHDYA'
## 接口说明:
/prometheusalert #自定义模版接口,可通过Dashboard自定义模版后,支持任意WebHook接入
type=?:指定消息转发的目标类型,如钉钉、企业微信、飞书等;该参数为必选参数
目前支持的值:
dd 钉钉
wx 企业微信
workwechat 企业微信应用
fs 飞书
webhook WebHook
txdx 腾讯云短信
txdh 腾讯云电话
alydx 阿里云短信
alydh 阿里云电话
hwdx 华为云短信
bddx 百度云短信
rlydh 容联云电话
7moordx 七陌短信
7moordh 七陌语音电话
email Email
tg Telegram
rl 百度Hi(如流)
tpl=?: 指定消息所使用的模版,如prometheus-dd(Prometheus针对钉钉的模板);模版可以去PrometheusAlert 页面的模版管理-->自定义模板页面查看或新建;该参数为必选参数
ddurl=?:指定PrometheusAlert发送消息的钉钉机器人地址,如需要多个地址可以通过,分割,该参数需要配合type=dd的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
wxurl=?:指定PrometheusAlert发送消息的企业微信机器人地址,如需要多个地址可以通过,分割,该参数需要配合type=wx的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
fsurl=?:指定PrometheusAlert发送消息的飞书机器人地址,如需要多个地址可以通过,分割,该参数需要配合type=fs的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
phone=?:指定PrometheusAlert发送消息的手机号,如需要多个号码可以通过,分割,该参数需要配合type=txdx | hwdx | bddx | alydx | txdh | alydh | rlydh | 7moordx | 7moordh的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
email=?:指定PrometheusAlert发送消息的email地址,如需要多个email可以通过,分割,该参数需要配合type=email的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
groupid=?:指定PrometheusAlert发送消息的groupid,该参数需要配合type=rl的模版使用;该参数为可选参数,如未填写,则默认从app.conf中获取默认配置
webhook=?:指定PrometheusAlert发送消息的webhook,该参数需要配合type=webhook的模版使用;该参数为可选参数
at=?:钉钉机器人、企业微信机器人开启@某人的功能,如需添加多个@目标,用,号分割即可。此处需注意:钉钉@使用的是手机号码,企业微信机器人@使用的是用户帐号。;该参数为可选参数
rr=?:该参数为开启随机轮询,目前仅针对ddurl,fsurl,wxurl有效,默认情况下如果上述Url配置的是多个地址,则多个地址全部发送,如开启该选项,则从多个地址中随机取一个地址发送,主要是为了避免消息发送频率过高导致触发部分机器人拦截消息。;该参数为可选参数
split=?:该参数仅针对Prometheus告警消息有效,作用是将Prometheus分组消息拆分成单条发送。默认开启,如果Prometheus一次告警附带的同分组的告警消息条数过多,可能会导致告警消息体过大。如需关闭请在url中加入split=false;该参数为可选参数
注意:此参数如设置为split=false,则PrometheusAlert web页面的路由和告警记录等功能将自动关闭,请谨慎。
热加载
$ curl -XPOST http://alertmanager.kubernets.cn/-/reload
PrometheusAlter总结
- 支持任意包含WebHook接口系统的消息作为消息来源,常见的如Prometheus,Zabbix,Grafana等。
- 支持多种类型的发送目标,支持钉钉,企业微信,email,飞书,公有云短信/电话等。
- 支持按照不同级别发送消息到不同目标对象。
- 简化Prometheus分组配置,支持按照具体消息发送到单个或多个接收方。
- 可按照企业中的排班制,通过自动轮询的方式发送到多个人员且支持按照不同日期发送到不同人员。