prometheus知识大全

一.Prometheus安装

1.prometheus安装

1
2
3
4
5
6
7
8
9
10
11
12
https://github.com/prometheus-operator/kube-prometheus.git
git checkout release-0.5

#或者下载压缩包上传至root
https://github.com/prometheus-operator/kube-prometheus/tree/release-0.5


#部署
#1.安装operator
cd manifests/setup && kubectl create -f .
#安装Prometheus
cd .. && kubectl create -f .

2更改svc的port类型

1
2
3
4
5
6
kubectl edit svc 【svc-name】 -n monitoring
#type: ClusterIP 修改为 type: NodePort,然后保存退出
需要修改的svc有:
alertmanager-main
grafana
prometheus-k8s

二.知识

image-20220909170637739

1.Metrics数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
counter:只增不减的计数器

​ 例:http_requests_total

​ node_cpu

Gauge:可增可减

​ 例:主机的cpu、内存、磁盘使用率

​ 当前的并发量

Histogram和Summary: 用于统计和分析样本的分布情况:
Histogram是一种只增直方图,每一个bucket样本包含了之前所有样本
Summary这类指标是根据样本计算出百分位的,是在客户端计算好的然后被抓取到promethues中的

2.promSQL

①瞬时向量和区间向量

1
2
3
4
5
6
瞬时向量:包含该时间序列最新的一个样本值
node_cpu_seconds_total{cpu="0",endpoint="https",instance="master",job="node-exporter",mode="idle",namespace="monitoring",pod="node-exporter-45l68",service="node-exporter"}
区间向量(带时间戳):一段时间范围内的数据
http_request_total{endpoint="http",handler="/*",instance="10.244.1.35:3000",job="grafana",method="get",namespace="monitoring",pod="grafana-5c55845445-gb8dd",service="grafana",statuscode="200"}[5m]
#Offset:查看多少分钟之前的数据 offset 30m
http_request_total{endpoint="http",handler="/*",instance="10.244.1.35:3000",job="grafana",method="get",namespace="monitoring",pod="grafana-5c55845445-gb8dd",service="grafana",statuscode="200"}[5m] offset 30s

Labelsets:

过略出具有某一个标签的label数据。

1
2
3
正则匹配:http_request_total{handler=~".*login.*"}
剔除某个label:http_request_total{handler!~".*login.*"}
匹配两个值:http_request_total{handler=~"/login|/password"}

③数学运算

+ - * / % ^

1
2
查看主机内存总大小(Mi)
node_memory_MemTotal_bytes / 1024 /1024

④集合运算

andorunless(剔除)

1
2
3
4
node_memory_MemTotal_bytes / 1024 /1024 <= 2772  or node_memory_MemTotal_bytes / 1024 /1024 == 	3758.59765625

#unless
node_memory_MemTotal_bytes / 1024 /1024 >= 2772 unless node_memory_MemTotal_bytes / 1024 /1024 == 3758.59765625

优先级

1
2
3
4
5
6
^ 
* / %
+ -
==, !=, <=, < >= >
And unless
Or

⑤聚合操作

sum,max,avg,stddev(标准差),stdvar(标准差异),count(计数),topk(取前n条时序),bottomk(取后n条时序),quantile(取数据的某一段)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#求和
sum(node_memory_MemTotal_bytes) / 1024^2
#根据某个字段进行统计
sum(http_request_total) by (statuscode, handler)
#最小值
min(node_memory_MemTotal_bytes)
#平均值
avg(node_memory_MemTotal_bytes)
#计数
count(http_request_total)
#对value进行统计计数
count_values("count", node_memory_MemTotal_bytes)
#取前5条时序
topk(5, sum(http_request_total) by (statuscode, handler))
#取后五条时序
bottomk(3, sum(http_request_total) by (statuscode, handler))
#取当前数据的中位数
quantile(0.5, http_request_total)

⑥内置函数

increase,rate,irate(一个指标的增长率)

1
2
3
4
5
6
7
8
两分钟内的平均CPU使用率:
rate(node_cpu[2m])和irate(node_cpu[2m])

需要注意的是使用rate或者increase函数去计算样本的平均增长速率,容易陷入“长尾问题”当中,其无法反应在时间窗口内样本数据的突发变化。
例如,对于主机而言在2分钟的时间窗口内,可能在某一个由于访问量或者其它问题导致CPU占用100%的情况,但是通过计算在时间窗口内的平均增长率却无法反应出该问题。为了解决该问题,PromQL提供了另外一个灵敏度更高的函数irate(v range-vector)。
irate同样用于计算区间向量的计算率,但是其反应出的是瞬时增长率。
irate函数是通过区间向量中最后两个两本数据来计算区间向量的增长速率。
这种方式可以避免在时间窗口范围内的“长尾问题”,并且体现出更好的灵敏度,通过irate函数绘制的图标能够更好的反应样本数据的瞬时变化状态。

predict_linear()预测

1
2
#根据一天的数据,预测4个小时之后,磁盘分区的空间会不会小于0
predict_linear(node_filesystem_files_free{mountpoint="/"}[1d], 4*3600) < 0

**absent()**:

1
如果样本数据不为空则返回no data,如果为空则返回1。判断数据是否在正常采集。

去除小数点

1
2
3
Ceil():四舍五入,向上取最接近的整数,2.79 -> 3

​ Floor:向下取, 2.79 -> 2

**Delta()**:差值

排序

1
2
3
	Sort:正序

​ Sort_desc:倒叙

**Label_join()**将数据中的一个或多个label的值赋值给一个新label

1
label_join(node_filesystem_files_free, "new_label", ",",  "instance", "mountpoint")

label_replace:根据数据中的某个label值,进行正则匹配,然后赋值给新label并添加到数据中

1
label_replace(node_filesystem_files_free, "host","$2", "instance", "(.*)-(.*)")

3.白盒监控

监控一些内部数据,topic的监控数据,redis key的大小,内部暴露的指标

关注的是原因

4.黑盒监控

站在用户的角度看到的东西。网站打不开,网站延迟

关注的是现象,表示正在发生的问题

①部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
https://github.com/prometheus/blackbox_exporter

#部署configmap
apiVersion: v1
data:
blackbox.yml: |-
modules:
http_2xx:
prober: http
http:
preferred_ip_protocol: "ip4"
http_post_2xx:
prober: http
http:
method: POST
tcp_connect:
prober: tcp
pop3s_banner:
prober: tcp
tcp:
query_response:
- expect: "^+OK"
tls: true
tls_config:
insecure_skip_verify: false
ssh_banner:
prober: tcp
tcp:
query_response:
- expect: "^SSH-2.0-"
irc_banner:
prober: tcp
tcp:
query_response:
- send: "NICK prober"
- send: "USER prober prober prober :prober"
- expect: "PING :([^ ]+)"
send: "PONG ${1}"
- expect: "^:[^ ]+ 001"
icmp:
prober: icmp
kind: ConfigMap
metadata:
creationTimestamp: "2020-05-13T13:44:52Z"
name: blackbox-conf
namespace: monitoring

#部署Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
generation: 1
labels:
app: blackbox-exporter
name: blackbox-exporter
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: blackbox-exporter
template:
metadata:
creationTimestamp: null
labels:
app: blackbox-exporter
spec:
containers:
- args:
- --config.file=/mnt/blackbox.yml
image: prom/blackbox-exporter:master
imagePullPolicy: IfNotPresent
name: blackbox-exporter
ports:
- containerPort: 9115
name: web
protocol: TCP
volumeMounts:
- mountPath: /mnt
name: config
restartPolicy: Always
volumes:
- configMap:
defaultMode: 420
name: blackbox-conf
name: config

#service
apiVersion: v1
kind: Service
metadata:
labels:
app: blackbox-exporter
name: blackbox-exporter
namespace: monitoring
spec:
ports:
- name: container-1-web-1
port: 9115
protocol: TCP
targetPort: 9115
selector:
app: blackbox-exporter
sessionAffinity: None
type: ClusterIP


#查看svc
访问测试
curl "http://10.102.165.69:9115/probe?target=www.baidu.com&module=http_2xx"

②prometheus_additional传统配置

用来收集监控blackbox的数据

1
2
3
https://github.com/prometheus/blackbox_exporter
https://github.com/prometheus/blackbox_exporter/blob/master/blackbox.yml
https://grafana.com/grafana/dashboards/5345

创建secrets

(官方地址:https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/additional-scrape-config.md)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat prometheus-additional.yaml

- job_name: 'blackbox'
metrics_path: /probe
params:
module: [http_2xx] # Look for a HTTP 200 response.
static_configs:
- targets:
- http://www.baidu.com # 这里我们监控百度网站测试
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115 # The blackbox exporter's real hostname:port.
1
2
3
4
kubectl create secret generic additional-scrape-configs --from-file=prometheus-additional.yaml --dry-run -oyaml > additional-scrape-configs.yaml

kubectl apply -f additional-scrape-configs.yaml -n monitoring

修改Prometheus的CRD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[root@k8s-master01 manifests]# vim prometheus-prometheus.yaml 

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
image: quay.io/prometheus/prometheus:v2.15.2
nodeSelector:
kubernetes.io/os: linux
podMonitorNamespaceSelector: {}
podMonitorSelector: {}
replicas: 1
resources:
requests:
memory: 700Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
version: v2.15.2
additionalScrapeConfigs:
name: additional-scrape-configs
key: prometheus-additional.yaml

[root@k8s-master01 manifests]# kubectl replace -f prometheus-prometheus.yaml
prometheus.monitoring.coreos.com/k8s replaced

image-20220911162455295

image-20220911162515782

三.prometheus报错问题

KubeControllerManagerDownKubeSchedulerDown

原因一:prometheus无法访问kube-controll,kube-schedule

image-20220909151519767

原因二:servicemonitor中的kube-controller-manager的标签在kube-system的svc中找不到对应的标签

image-20220909152525001

1
2
3
4
#查看标签
kubectl get servicemonitor -n monitoring kube-controller-manager -o yaml
#检查kube-system中是否有该标签
kubectl get svc -n kube-system -l k8s-app=kube-controller-manager

解决方法

将地址改为0.0.0.0

1
2
3
vi /etc/kubernetes/manifests/kube-controller-manager.yaml
vi /etc/kubernetes/manifests/kube-scheduler.yaml
systemctl daemon-reload

创建svc,endpoint

kube-controller-manager.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: v1
kind: Service
metadata:
name: kube-controller-manager
namespace: kube-system
labels:
k8s-app: kube-controller-manager
spec:
type: ClusterIP
clusterIP: None
ports:
- name: http-metrics
port: 10257
targetPort: 10257
protocol: TCP

---
apiVersion: v1
kind: Endpoints
metadata:
name: kube-controller-manager
namespace: kube-system
labels:
k8s-app: kube-controller-manager
subsets:
- addresses:
- ip: 192.168.200.155
ports:
- name: http-metrics
port: 10257
protocol: TCP

kube-scheduler.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: v1
kind: Service
metadata:
name: kube-scheduler
namespace: kube-system
labels:
k8s-app: kube-scheduler
spec:
type: ClusterIP
clusterIP: None
ports:
- name: http-metrics
port: 10259
targetPort: 10259
protocol: TCP

---
apiVersion: v1
kind: Endpoints
metadata:
name: kube-scheduler
namespace: kube-system
labels:
k8s-app: kube-scheduler
subsets:
- addresses:
- ip: 172.16.1.71
ports:
- name: http-metrics
port: 10259
protocol: TCP

补充:查看kubeadm的token

1
2
kubectl get secret -n kube-system
kubectl describe secret -n kube-system attachdetach-controller-token-85hdj

四.没有metrics接口(监控kafka)

部署deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vi kafka.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka
namespace: default
spec:
replicas: 1
selector:
matchLabels:
k8s-app: kafka
template:
metadata:
labels:
k8s-app: kafka
spec:
containers:
- name: kafka
image: bitnami/kafka
imagePullPolicy: IfNotPresent
command: ["/bin/bash", "-ce", "tail -f /dev/null"]
ports:
- containerPort: 9092

Alertmanager告警 系统整合

一.工作机制

image-20220912091238476

alertmanager-arch

1
2
3
4
5
6
在Prometheus生态架构里,警报是由独立的俩部分组成,可以通过上图很清晰的了解到 Prometheus 的警报工作机制。其中Prometheus与 Alertmanager 是分离的俩个组件。我们使用Prometheus Server端通过静态或者动态配置
去拉取 pull 部署在k8s或云主机上的各种类别的监控指标数据,然后基于我们前面讲到的 PromQL 对这些已经存储在本地存储 HDD/SSD 的 TSDB 中的指标定义阈值警报规则 Rules。Prometheus会根据配置的参数周期性的对警报规则进行计算,
如果满足警报条件,生产一条警报信息,将其推送到 Alertmanager 组件,Alertmanager 收到警报信息之后,会对警告信息进行处理,进行 **分组** Group 并将它们通过定义好的路由 Routing 规则转到 正确的接收器 receiver,
比如 Email Slack 钉钉、企业微信 Robot(webhook) 企业微信 等,最终异常事件 Warning、Error通知给定义好的接收人,其中如钉钉是基于第三方通知来实现的,对于通知人定义是在钉钉的第三方组件中配置。

在 Prometheus 中, 我们不仅仅可以对单条警报进行命名通过 PromQL定义规则,更多时候是对相关的多条警报进行分组后统一定义。

模板:https://prometheus.io/docs/alerting/configuration/#email_config

二.Altermanager的4个概念

image-20220912091807849

分组(Grouping)

  GroupingAlertmanager 把同类型的警报进行分组,合并多条警报到一个通知中。在生产环境中,特别是云环境下的业务之间密集耦合时,若出现多台 Instance 故障,可能会导致成千上百条警报触发。在这种情况下使用分组机制,
可以把这些被触发的警报合并为一个警报进行通知,从而避免瞬间突发性的接受大量警报通知,使得管理员无法对问题进行快速定位。

举个栗子,在Kubernetes集群中,运行着重量级规模的实例,即便是集群中持续很小一段时间的网络延迟或者延迟导致网络抖动,也会引发大量类似服务应用无法连接 DB 的故障。如果在警报规则中定义每一个应用实例都发送警报,那么到最后的结果就是
会有大量的警报信息发送给 Alertmanager

作为运维组或者相关业务组的开发人员,可能更关心的是在一个通知中就可以快速查看到哪些服务实例被本次故障影响了。为此,我们对服务所在集群或者服务警报名称的维度进行分组配置,把警报汇总成一条通知时,就不会受到警报信息的频繁发送影响了。

抑制(Inhivition)

  Inhibition 是 当某条警报已经发送,停止重复发送由此警报引发的其他异常或故障的警报机制。

  在生产环境中,IDC托管机柜中,若每一个机柜接入层仅仅是单台交换机,那么该机柜接入交换机故障会造成机柜中服务器非 up 状态警报。再有服务器上部署的应用服务不可访问也会触发警报。

  这时候,可以通过在 Alertmanager 配置忽略由于交换机故障而造成的此机柜中的所有服务器及其应用不可达而产生的警报。

在我们的灾备体系中,当原有集群故障宕机业务彻底无法访问的时候,会把用户流量切换到备份集群中,这样为故障集群及其提供的各个微服务状态发送警报机会失去了意义,此时, Alertmanager 的抑制特性就可以在一定程度上避免管理员收到过多无用的警报通知。

静默(Silences)

  Silences 提供了一个简单的机制,根据标签快速对警报进行静默处理;对传进来的警报进行匹配检查,如果接受到警报符合静默的配置,Alertmanager 则不会发送警报通知。

以上除了分组、抑制是在 Alertmanager 配置文件中配置,静默是需要在 WEB UI 界面中设置临时屏蔽指定的警报通知。

路由(router)

 用于配置 Alertmanager 如何处理传入的特定类型的告警通知,其基本逻辑是根据路由匹配规则的匹配结果来确定处理当前报警通知的路径和行为

三.范例

Alertmanager完整配置文件范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
## Alertmanager 配置文件
global:
resolve_timeout: 5m
# smtp配置
smtp_from: "123456789@qq.com"
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: "123456789@qq.com"
smtp_auth_password: "auth_pass"
smtp_require_tls: true
# email、企业微信的模板配置存放位置,钉钉的模板会单独讲如果配置。
templates:
- '/data/alertmanager/templates/*.tmpl'
# 路由分组
route:
receiver: ops
group_wait: 30s # 在组内等待所配置的时间,如果同组内,30秒内出现相同报警,在一个组内出现。
group_interval: 5m # 如果组内内容不变化,合并为一条警报信息,5m后发送。
repeat_interval: 24h # 发送报警间隔,如果指定时间内没有修复,则重新发送报警。
group_by: [alertname] # 报警分组
routes:
- match:
team: operations
group_by: [env,dc]
receiver: 'ops'
- match_re:
service: nginx|apache
receiver: 'web'
- match_re:
service: hbase|spark
receiver: 'hadoop'
- match_re:
service: mysql|mongodb
receiver: 'db'
# 接收器
# 抑制测试配置
- receiver: ops
group_wait: 10s
match:
status: 'High'
# ops
- receiver: ops # 路由和标签,根据match来指定发送目标,如果 rule的lable 包含 alertname, 使用 ops 来发送
group_wait: 10s
match:
team: operations
# web
- receiver: db # 路由和标签,根据match来指定发送目标,如果 rule的lable 包含 alertname, 使用 db 来发送
group_wait: 10s
match:
team: db
# 接收器指定发送人以及发送渠道
receivers:
# ops分组的定义
- name: ops
email_configs:
- to: '9935226@qq.com,10000@qq.com'
send_resolved: true
headers:
subject: "[operations] 报警邮件"
from: "警报中心"
to: "小煜狼皇"
# 钉钉配置
webhook_configs:
- url: http://localhost:8070/dingtalk/ops/send
# 企业微信配置
wechat_configs:
- corp_id: 'ww5421dksajhdasjkhj'
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
send_resolved: true
to_party: '2'
agent_id: '1000002'
api_secret: 'Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj'

# web
- name: web
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[web] 报警邮件"} # 接收邮件的标题
webhook_configs:
- url: http://localhost:8070/dingtalk/web/send
- url: http://localhost:8070/dingtalk/ops/send
# db
- name: db
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[db] 报警邮件"} # 接收邮件的标题
webhook_configs:
- url: http://localhost:8070/dingtalk/db/send
- url: http://localhost:8070/dingtalk/ops/send
# hadoop
- name: hadoop
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[hadoop] 报警邮件"} # 接收邮件的标题
webhook_configs:
- url: http://localhost:8070/dingtalk/hadoop/send
- url: http://localhost:8070/dingtalk/ops/send

# 抑制器配置
inhibit_rules: # 抑制规则
- source_match: # 源标签警报触发时抑制含有目标标签的警报,在当前警报匹配 status: 'High'
status: 'High' # 此处的抑制匹配一定在最上面的route中配置不然,会提示找不key。
target_match:
status: 'Warning' # 目标标签值正则匹配,可以是正则表达式如: ".*MySQL.*"
equal: ['alertname','operations', 'instance'] # 确保这个配置下的标签内容相同才会抑制,也就是说警报中必须有这三个标签值才会被抑制。

route路由匹配规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
route:
receiver: admin # 默认的接收器名称
group_wait: 30s # 在组内等待所配置的时间,如果同组内,30秒内出现相同报警,在一个组内出现。
group_interval: 5m # 如果组内内容不变化,5m后发送。
repeat_interval: 24h # 发送报警间隔,如果指定时间内没有修复,则重新发送报警
group_by: [alertname,cluster] # 报警分组,根据 prometheus 的 lables 进行报警分组,这些警报会合并为一个通知发送给接收器,也就是警报分组。
routes:
- match:
team: ops
group_by: [env,dc]
receiver: 'ops'
- match_re:
service: nginx|apache
receiver: 'web'
- match_re:
service: mysql|mongodb
receiver: 'db'
- match_re:
service: hbase|spark
receiver: 'hadoop'

在以上的例子中,默认的警报组全部发送给 admin ,且根据路由按照 alertname cluster 进行警报分组。在子路由中的若匹配警报中的标签 team 的值为 ops,Alertmanager 会按照标签 env dc 进行警报分组然后发送给接收器 receiver ops配置的警报通知源。
继续匹配的操作是对 service 标签进行匹配,并且配到了 nginx redis mongodb 的值,就会向接收器 receiver web配置的警报通知源发送警报信息。

receiver接收器

接受器是一个统称,每个 receiver 都有需要设置一个全局唯一的名称,并且对应一个或者多个通知方式,包括email、微信、Slack、钉钉等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
name: <string>
email_config:
[ - <config> ]
hipchat_configs: #此模块配置已经被移除了
[ <config> ]
pagerduty_configs:
[ <config> ]
pushover_configs:
[ <config> ]
slack_configs:
[ <config> ]
opsgenie_configs:
[ <config> ]
webhook_configs:
[ <config> ]
victorops_configs:
[ <config> ]
webchat_configs:
[ <config> ]

可以看到Alertmanager提供了很多种接收器的通知配置,我们可以使用webhook接收器来定义通知集成,支持用户自己定义编写。

官方配置Configuration | Prometheus

inhibit_rules抑制器

inhibit_rules 模块中设置警报抑制功能,可以指定在特定条件下需要忽略的警报条件。可以使用此选项设置首选,比如优先处理某些警报,如果同一组中的警报同时发生,则忽略其他警报。
合理使用 inhibit_rules ,可以减少频发发送没有意义的警报的产生。

inhibit_rules 配置信息:

1
2
3
4
5
6
7
8
9
10
trget_match:
[ <label_name>: <labelvalue>,... ]
trget_match_re:
[ <label_name>: <labelvalue>,... ]
source_match:
[ <label_name>: <labelvalue>,... ]
source_match_re:
[ <label_name>: <labelvalue>,... ]
[ equal: '[' <lable_name>, ...]']

范例

1
2
3
4
5
6
inhibit_rules: # 抑制规则
- source_match: # 源标签警报触发时抑制含有目标标签的警报,在当前警报匹配 status: 'High'
status: 'High' # 此处的抑制匹配一定在最上面的route中配置不然,会提示找不key。
target_match:
status: 'Warning' # 目标标签值正则匹配,可以是正则表达式如: ".*MySQL.*"
equal: ['alertname','operations', 'instance'] # 确保这个配置下的标签内容相同才会抑制,也就是说警报中必须有这三个标签值才会被抑制。

四.警报通知接收器

Email

前面已经讲过,Alertmanager默认支持配置Email,也是最普通的方式,在Alertmanager组件中内置了SMTP协议。直接可以把前面的Alertmanager.yml中的SMTP部分截取出来,然后进行调整与配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
global:
resolve_timeout: 5m
# smtp配置
smtp_from: "1234567890@qq.com" # 发送邮件主题
smtp_smarthost: 'smtp.qq.com:465' # 邮箱服务器的SMTP主机配置
smtp_auth_username: "1234567890@qq.com" # 登录用户名
smtp_auth_password: "auth_pass" # 此处的auth password是邮箱的第三方登录授权密码,而非用户密码,尽量用QQ来测试。
smtp_require_tls: false # 有些邮箱需要开启此配置,这里使用的是163邮箱,仅做测试,不需要开启此功能。
route:
receiver: ops
group_wait: 30s # 在组内等待所配置的时间,如果同组内,30秒内出现相同报警,在一个组内出现。
group_interval: 5m # 如果组内内容不变化,合并为一条警报信息,5m后发送。
repeat_interval: 24h # 发送报警间隔,如果指定时间内没有修复,则重新发送报警。
group_by: [alertname] # 报警分组
routes:
- match:
team: operations
group_by: [env,dc]
receiver: 'ops'
- receiver: ops # 路由和标签,根据match来指定发送目标,如果 rule的lable 包含 alertname, 使用 ops 来发送
group_wait: 10s
match:
team: operations
# 接收器指定发送人以及发送渠道
receivers:
# ops分组的定义
- name: ops
email_configs:
- to: '9935226@qq.com,xxxxx@qq.com' # 如果想发送多个人就以 ','做分割,写多个邮件人即可。
send_resolved: true
headers:
from: "警报中心"
subject: "[operations] 报警邮件"
to: "小煜狼皇"

image-20220912093336699

企业微信

第一步登录进入以后,在应用管理中新建应用。

img

第二步,创建应用,信息填写如下,上传应用logo随意。

img

创建成功以后如下图。

img

微信应用信息

这时候需要把 AgentIdSecret 记录下来,对于你的这种Secret信息,最好管理好,我的用过就会删除,所以不用担心安全隐患。

ID key
AgentId 1000004
Secret F-fzpgsabmfiFt7_4QRQwWEl8eyx7evO12sRYe_Q5vA

第三步,现在我们来用新建的企业微信应用在Alertmanager配置,可以配置全局,也可以对单独需要发送的接收器,因为警报需要分级,所以需要单独处理,在这里使用的的单独的配置,需要知道 企业ID ,以及 部门ID

企业ID 通过

img

部门ID 通过通讯录获取

img

这时候我们重启Alertmanager,然后使用之前的方式来触发模拟警报,看看发送是不是已经没有问题了,这时我们的企业微信中、Email都可以收到警报了,这里的警报已经被我用模块处理过了。可读性会更高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
cat wechat.tmpl
## wechat模板
{{ define "wechat.default.message" }}
{{ if gt (len .Alerts.Firing) 0 -}}
Alerts Firing:
{{ range .Alerts }}
警报级别:{{ .Labels.status }}

警报类型:{{ .Labels.alertname }}

故障主机: {{ .Labels.instance }}

警报主题: {{ .Annotations.summary }}

警报详情: {{ .Annotations.description }}

⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- end }}
{{- end }}

{{ if gt (len .Alerts.Resolved) 0 -}}
Alerts Resolved:
{{ range .Alerts }}
警报级别:{{ .Labels.status }}

警报类型:{{ .Labels.alertname }}

故障主机: {{ .Labels.instance }}

警报主题: {{ .Annotations.summary }}

警报详情: {{ .Annotations.description }}

⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
⏲ : {{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- end }}
{{- end }}
{{- end }}

钉钉机器人

Prometheus-webhook-Dingtalk组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mkdir -p /etc/prometheus-webhook-dingtalk/template/
cd /etc/prometheus-webhook-dingtalk/
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
tar xf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
mv prometheus-webhook-dingtalk-1.4.0.linux-amd64/* /etc/prometheus-webhook-dingtalk/
mv prometheus-webhook-dingtalk /bin/
cat <<EOF> /lib/systemd/system/prometheus-webhook-dingtalk.service
[Unit]
Description=prometheus-webhook-dingding
Documentation=https://prometheus.io/
After=network.target

[Service]
Type=simple
User=prometheus
ExecStart=/bin/prometheus-webhook-dingtalk --web.listen-address=":8070" --web.enable-ui --config.file="/etc/prometheus-webhook-dingtalk/config.yml"
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
## 启动服务
systemctl enable prometheus-webhook-dingtalk.service
systemctl start prometheus-webhook-dingtalk.service

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
## Request timeout
# timeout: 5s

## Customizable templates path
## Customizable templates path
templates:
# - contrib/templates/legacy/template.tmpl
# 自定义模板路径
- /etc/prometheus-webhook-dingtalk/template/default.tmpl

## 你还可以使用' default_message '覆盖默认模板
## 下面的示例使用v0.3.0中的“legacy”模板
# default_message:
# title: '{{ template "legacy.title" . }}'
# text: '{{ template "legacy.content" . }}'

## Targets, previously was known as "profiles"
# 定义的webhook,钉钉创建的webhook token
targets:
# 如果有多个分组就可以在这里定义多个接口
ops:
url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2322222222222222222222222
web:
url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2325c1333333333333333333333

定义模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
cd /etc/prometheus-webhook-dingtalk/template
cat default.tmpl
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver }}{{ end }}

{{ define "__text_alert_list" }}{{ range . }}
**Labels**
{{ range .Labels.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Annotations**
{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})
{{ end }}{{ end }}

{{/* Firing */}}

{{ define "default.__text_alert_list" }}{{ range . }}

**Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}

**Summary:** {{ .Annotations.summary }}

**Description:** {{ .Annotations.description }}

**Graph:** [📈 ]({{ .GeneratorURL }})

**Details:**
{{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}{{ end }}
{{ end }}{{ end }}

{{/* Resolved */}}

{{ define "default.__text_resolved_list" }}{{ range . }}

**Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}

**Resolved Time:** {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}

**Summary:** {{ .Annotations.summary }}

**Graph:** [📈 ]({{ .GeneratorURL }})

**Details:**
{{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}{{ end }}
{{ end }}{{ end }}

{{/* Default */}}
{{ define "default.title" }}{{ template "__subject" . }}{{ end }}
{{ define "default.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ if gt (len .Alerts.Firing) 0 -}}

![Firing-img](https://is3-ssl.mzstatic.com/image/thumb/Purple20/v4/e0/23/cf/e023cf56-0623-0cdf-afce-97ae90eabfda/mzl.uplmrpgi.png/320x0w.jpg)

**Alerts Firing**
{{ template "default.__text_alert_list" .Alerts.Firing }}
{{- end }}
{{ if gt (len .Alerts.Resolved) 0 -}}

![Resolved-img](https://is3-ssl.mzstatic.com/image/thumb/Purple18/v4/41/72/99/4172990a-f666-badf-9726-6204a320c16e/mzl.dypdixoy.png/320x0w.png)

**Alerts Resolved**
{{ template "default.__text_resolved_list" .Alerts.Resolved }}
{{- end }}
{{- end }}

{{/* Legacy */}}
{{ define "legacy.title" }}{{ template "__subject" . }}{{ end }}
{{ define "legacy.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ template "__text_alert_list" .Alerts.Firing }}
{{- end }}

{{/* Following names for compatibility */}}
{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}

在alertmanager中配置警报

让三个报警报警

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 接收器指定发送人以及发送渠道
receivers:
# ops分组的定义
- name: ops
email_configs:
- to: '9935226@qq.com,10000@qq.com'
send_resolved: true
headers: { Subject: "[operations] 报警邮件"} # 接收邮件的标题
# 钉钉配置
webhook_configs:
- url: http://localhost:8070/dingtalk/ops/send # 这里是在钉钉开源组件中的接口,如果单独定义的receiver需要对应你的分组与钉钉机器人的webhook token
# 企业微信配置
wechat_configs:
- corp_id: 'ww5421dksajhdasjkhj'
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
send_resolved: true
to_party: '2'
agent_id: '1000002'
api_secret: 'Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj'
# web
- name: web
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[web] 报警邮件"} # 接收邮件的标题
webhook_configs:
- url: http://localhost:8070/dingtalk/web/send

报警规则

1
vi prometheus-rules.yaml