目录

Opentelemetry-9-Prometheus的告警与自定义

目录

在之前的文章中完成了alertmanager发日志相关的告警,今天这篇是关于发送Prometheus告警的,在上篇中,日志的告警规则比较简单,{level=“error”}一条语句就可以过滤所有告警,但是在Prometheus中,定义告警规则没有那么容易,需要根据不同的metrics经过计算来定义不同的告警。

在之前部署的Prometheus中,已经有一些告警了,我们这次就来定义自己的告警,本篇举两个例子:

  • 部署exporter来监控中间件
  • 监控非k8s集群的node-exporter

这两个部分基本可以涵盖常用的情况了,在我的k8s集群中,已经存在一个rocketmq集群了,所以本文就以rocketmq来演示

rocketmq

查看一下我的rocketmq

1
2
3
4
5
6
7
kubectl get pod -n rocketmq
NAME                               READY   STATUS    RESTARTS        AGE
broker-0-master-0                  1/1     Running   0               497d
broker-0-replica-1-0               1/1     Running   0               497d
console-db7d7fb79-tftxn            1/1     Running   0               343d
name-service-0                     1/1     Running   0               497d
rocketmq-operator-867c4955-jfksv   1/1     Running   0               344d

首先需要部署我们的rocketmq-exporter

 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
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: rocketmq-exporter
  name: rocketmq-exporter
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rocketmq-exporter
  template:
    metadata:
      labels:
        app: rocketmq-exporter
    spec:
      containers:
      - env:
        - name: Options
          value: -Drocketmq.config.namesrvAddr=name-server-service.rocketmq:9876 -Drocketmq.config.rocketmqVersion=V4_5_0
        image: registry.cn-hangzhou.aliyuncs.com/example/rocketmq-exporter:v0.2
        imagePullPolicy: IfNotPresent
        name: rocketmq-exporter
        ports:
        - containerPort: 5557
          protocol: TCP
      imagePullSecrets:
      - name: standard
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: rocketmq-exporter
  name: rocketmq-exporter
  namespace: monitoring
spec:
  ports:
  - name: http
    port: 5557
    protocol: TCP
    targetPort: 5557
  selector:
    app: rocketmq-exporter
  type: ClusterIP

由于kube-prometheus官方部署文件中,对于Prometheus的RBAC有namespace的限制,网上有很多解决办法,我这里就使用monitoring这个namespace即便是不修改RBAC也可以使用,灵活编配。

POD

1
rocketmq-exporter-7854597c65-4c9s2     1/1     Running   0          90d

SERVICE

1
rocketmq-exporter  ClusterIP   192.168.146.147  <none>  5557/TCP    90d

部署完成之后可以尝试请求一下

我是在master节点执行的,可以与svcIP互通

1
curl 192.168.146.147:5557/metrics

可以请求到指标,这里就不贴出来了

然后需要创建servicemonitor,来让Prometheus抓取这个exporter。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: rocketmq-exporter
  labels:
    app: rocketmq-exporter
spec:
  selector:
    matchLabels:
      app: rocketmq-exporter
  endpoints:
    - port: http

这样就可以在Prometheus的Target页面中查看到rocketmq了

../images/otel-prometheus1.png

这里只是演示接入自己的中间件监控,就不演示grafana大盘的东西了

vm

对于非集群内的服务,例如部署在vm上的中间件,或者监控vm的node-exporter,会比k8s内监控要稍微复杂一点点,需要我们把外部的IP:port接到k8s里面来,这里假设我有一台服务器,上面部署了一个node-exporter,ip端口为192.168.122.16:9100,现在我们来把他接入到Prometheus吧

首先我们需要把这个node-exporter创建成一个endpoint

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: v1
kind: Endpoints
metadata:
  name: vm-exporter
  namespace: monitoring
  labels:
    name: vm-exporter
subsets:
  - addresses:
    - ip: 192.168.122.16
    ports:
    - name: metrics
      port: 9100

然后需要创建一个service绑定这个endpoint

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
  name: vm-exporter
  namespace: monitoring
  labels:
    name: vm-exporter
spec:
  ports:
  - name: metrics  
    port: 9100
    targetPort: 9100
    protocol: TCP
  type: ClusterIP

然后我们需要创建一个servicemonitor来让Prometheus来抓取这个endpoint的内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: vm-exporter
  namespace: monitoring
  labels:
    app.kubernetes.io/name: vm-exporter
    app.kubernetes.io/part-of: kube-prometheus
spec:
  jobLabel: vm-exporter
  endpoints:
  - port: metrics
    interval: 30s
    scheme: http
  selector:
    matchLabels:
      name: vm-exporter
  namespaceSelector:
    matchNames:
    - monitoring

部署这三个资源后,可能会出现问题,Prometheus会报错rbac没有对service的list操作,此时需要修改官方Prometheusroleconfig描述文件,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/component: prometheus
    app.kubernetes.io/instance: k8s
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 2.32.1
  name: prometheus-k8s-config
  namespace: monitoring
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  - services
  - endpoints
  verbs:
  - get
  - list
  - watch

再查看Prometheus的Target页面,就可以查看到我们的vm-exporter了。

../images/otel-prometheus2.png

到这里我们就完成了Prometheus的监控了,那么如何告警呢

我们需要创建我们自己的告警规则文件:

 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: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: basemetricalerts
  namespace: monitoring
spec:
  groups:
  - name: BaseMetricAlerts
    rules:
    - alert: HighNodeLoad1
      expr: |
                node_load1 > 8
      for: 5m
      labels:
        severity: warning
        group: operator
        at: "12345678910"
        metrics: prometheus
      annotations:
        summary: "{{ $labels.instance }}节点load1负载高于8核."
    - alert: HighNodeDiskUsage
      expr: |
                node_filesystem_avail_bytes/node_filesystem_size_bytes * 100 < 20
      for: 5m
      labels:
        severity: critical
        group: operator
        at: "12345678910"
        metrics: prometheus
      annotations:
        summary: "{{ $labels.instance }}节点{{ $labels.mountpoint }}分区磁盘空间不足20%,请及时清理."

这里只是一个示例,在之前几篇中,大家知道我是用的是webhook来发钉钉通知,所以这里会比普通的prometheusRule要多一点内容,groupat,这里主要是我的webhook来实现分钉钉群和at负责人的功能,大家在创建时可以根据自己的需求来改造。

这样我们就实现了Prometheus的监控和自定义告警了

由于webhook代码已经更新过太多次了,主要是之前只是为了日志告警设计的,现在把Prometheus兼容进来,已经有点臃肿了,就不献丑了