这是一篇Prometheus-Operator监控k8s服务的部署、监控原理讲解、监控配置、告警模板配置。

初始条件:

  • K8s1.12+集群

Prometheus-operator

安装monitoring.coreos.com/v1 api(prometheus-operator)

此处我们直接使用yaml文件方式安装,不使用helm安装,helm安装会缺少一些服务,不方便我们更深了解

1
git clone https://github.com/coreos/prometheus-operator.git

已迁移到如下

1
2
git clone https://github.com/coreos/kube-prometheus.git
cd prometheus-operator/contrib/kube-prometheus

1
2
kubectl get pod --all-namespaces
kubectl api-versions

如果整个集群是否设置tain,解除即可

1
for i in api.huisebug.com node1.huisebug.com node2.huisebug.com; do kubectl taint nodes $i node-role.kubernetes.io/master:NoSchedule-; done

集群状态

查看是否建立并启动好所有容器

1
kubectl get pod --all-namespaces -o wide 或者 kubectl get pod -n monitoring

问题汇总

  • Prometheus can’t access node-exporter and kube-state-metrics

解决地址

https://github.com/coreos/prometheus-operator/issues/2330

  • alertmanager无法建立pod,主要是服务器环境硬件跟不上

解决地址

https://github.com/coreos/prometheus-operator/issues/1902

https://github.com/coreos/prometheus-operator/issues/965

  • prometheus的storage.local.retention(数据存储时间)设置更长时间

解决地址

https://github.com/coreos/prometheus-operator/issues/732

只需在prometheus-prometheus.yaml文件中增加一行配置

主要介绍一下alertmanager无法建立pod的问题的解决方法,默认的alertmanager重启嗅探如下:

即嗅探10*10=100秒以后就会重启,显然模拟环境是无法在100秒内成功启动alertmanager,所以这里我们需要给配置文件alertmanager-alertmanager.yaml添加paused:true参数,添加步骤如下:

  1. 首先已经建立所有的prometheus-operator服务(kubectl apply -f manifests/ )
  2. 然后给alertmanager-alertmanager.yaml添加paused: true参数; paused: true参数解释参考地址:https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#alertmanagerspec
  3. 重载配置文件alertmanager-alertmanager.yaml (kubectl apply -f alertmanager-alertmanager.yaml)
  4. 将配置文件alertmanager-alertmanager.yaml建立后生成的statefulset转储到文件中(kubectl get statefulsets alertmanager-main -n monitoring -o yaml > alertmanager-main-statefulsets.yaml)
  5. 在集群中删除alertmanager(kubectl delete -f alertmanager-main-statefulsets.yaml)
  6. 修改文件alertmanager-main-statefulsets.yaml的嗅探失败次数,修改为30次,即30*10=300秒,也可根据你的实际环境来调节
  7. 再次创建,即可成功建立alertmanager

解析prometheus-operator原理

新加了两个apiversion,获取命令:

1
kubectl api-versions

metrics.k8s.io/v1beta1
monitoring.coreos.com/v1

  • monitoring.coreos.com/v1是作为四个资源对象的组而添加到api中
  • metrics.k8s.io/v1beta1是使用资源对象APIService进行建立的,这个apiversion需关联到service对应的pod prometheus-adapter建立成功才会成功建立,所以记住需要使用kubectl api-versions命令关注是否建立成功

使用自定义资源定义CustomResourceDefinitions(CRD)新增4个kind:

  1. Prometheus,它定义了所需的Prometheus部署。运营商始终确保正在运行与资源定义匹配的部署。
  2. ServiceMonitor,以声明方式指定应如何监控服务组。操作员根据定义自动生成Prometheus刮削配置。
  3. PrometheusRule,它定义了一个所需的Prometheus规则文件,该文件可以由包含Prometheus警报和记录规则的Prometheus实例加载。
  4. Alertmanager,它定义了所需的Alertmanager部署。运营商始终确保正在运行与资源定义匹配的部署。

获取命令如下

1
2
kubectl get Servicemonitor --all-namespaces
kubectl get Prometheus --all-namespaces

yaml类型

  1. 0prometheus-operator*:建立整个prometheus-operator的CRD、提供服务支持的pod运行
  2. alertmanager*:prometheus所需的告警处理,alertmanager告警的pod建立
  3. grafana*:监控页面展示
  4. kube-state-metrics*:增加对deployment建立的pod、statefulset建立的pod等资源对象的metrics数据,参考地址:https://github.com/kubernetes/kube-state-metrics
  5. node-exporter*:运行k8s集群的node的服务器数据抓取
  6. prometheus-adapter:为metrics.k8s.io/v1beta1提供metrics数据支持,获取集群的node和pod的CPU、内存使用情况,但是在这里只能获取到pod的,无法获取node的,后续将会在HPA V2章节讲解如何解决。
  7. prometheus*:prometheus监控系统的pod建立,为需要添加到监控列表的服务增加metrics

简易原理

数据源是从prometheus获取的,那么prometheus是如何获取k8s中这些数据的呢?

  1. 资源类型ServiceMonitor来定义添加的要被监控的k8s的服务service,然后使用operator工具来定义一个资源类型Prometheus进行筛选ServiceMonitor进行服务监控。PrometheusRule和Alertmanager进行规制和告警设置。

资源类型Prometheus

这里我们来深度解析下这个资源类型为Prometheus

1
kubectl get Prometheus --all-namespaces -o yaml > k8s-prometheus.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
32
33
34
35
36
37
38
apiVersion: v1
items:
- apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
baseImage: quay.io/prometheus/prometheus
nodeSelector:
beta.kubernetes.io/os: linux
replicas: 2
resources:
requests:
memory: 400Mi
ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: prometheus-k8s
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
version: v2.5.0
kind: List
metadata:
resourceVersion: ""
selfLink: ""
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
kind: List
metadata:
resourceVersion: ""
selfLink: ""
这一段是定义多个,不必在意。

- apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
这是基础的头定义,定义了api类型,资源对象类型,标签,名称,命名空间。

alerting:
alertmanagers:
- name: alertmanager-main
namespace: monitoring
port: web
这是定义告警方式的alertmanager的k8s服务service名称(kubectl get svc –all-namespaces)获取查看,web是定义service时spec.ports下的一个名称name(kubectl get svc alertmanager-main -n monitoring -o yaml)获取查看。

baseImage: quay.io/prometheus/prometheus
nodeSelector:
beta.kubernetes.io/os: linux
replicas: 2
resources:
requests:
memory: 400Mi
设置prometheus建立pod时的参数,基础镜像,节点选择,副本因子数,资源配额。

ruleSelector:
matchLabels:
prometheus: k8s
role: alert-rules
规则选择器,依照标签来选择规则列表,获取规则列表可以(kubectl get prometheusrule prometheus-k8s-rules -n monitoring),prometheus-operator添加api时候定义了一个新的资源类型PrometheusRule,如何查看添加哪些新的kind呢,我是依照安装prometheus-operator时候会建立资源对象推断出的

securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
安全上下文配置,这里我猜测应该是基于容器container的安全上下文配置。具体参考官方
https://www.kubernetes.org.cn/security-context-psp

serviceAccountName: prometheus-k8s
RBAC认证账户

serviceMonitorNamespaceSelector: {}
服务监控(ServiceMonitor)命名空间选择,这里是匹配所有;

serviceMonitorSelector: {}
对(ServiceMonitor)进行筛选,这里也是匹配所有

version: v2.5.0
镜像的版本号,即prometheus的版本号

建立的pod是使用statefulsets部署的

资源类型PrometheusRule

专门用于prometheus的rules配置,执行以下命令来参照修改

1
kubectl get prometheusrule prometheus-k8s-rules -n monitoring -o yaml

后续将会在企业微信告警配置中讲解

资源类型ServiceMonitor

kubectl get Servicemonitor –all-namespaces
以下举例三个不同namespace下的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
25
26
27
28
29
30
31
kubectl get Servicemonitor kube-apiserver -n monitoring -o yaml > kube-apiserver-servicemonitor.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
k8s-app: apiserver
name: kube-apiserver
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 30s
metricRelabelings:
- action: drop
regex: etcd_(debugging|disk|request|server).*
sourceLabels:
- __name__
port: https
scheme: https
tlsConfig:
caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
serverName: kubernetes
jobLabel: component
namespaceSelector:
matchNames:
- default
selector:
matchLabels:
component: apiserver
provider: kubernetes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kubectl get Servicemonitor node-exporter -n monitoring -o yaml > node-exporter-servicemonitor.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
k8s-app: node-exporter
name: node-exporter
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 30s
port: https
scheme: https
tlsConfig:
insecureSkipVerify: true
jobLabel: k8s-app
selector:
matchLabels:
k8s-app: node-exporter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
kubectl get Servicemonitor coredns -n monitoring -o yaml > coredns-servicemonitor.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
labels:
k8s-app: coredns
name: coredns
namespace: monitoring
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 15s
port: metrics
namespaceSelector:
matchNames:
- kube-system
selector:
matchLabels:
k8s-app: kube-dns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
endpoints:   #端点配置
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token #serviceaccount自动建立的token
interval: 30s #间隔时间
metricRelabelings:
- action: drop
regex: etcd_(debugging|disk|request|server).*
sourceLabels:
- __name__
port: https #端点配置中的port定义名称,使用kubectl get ep ep名称 -o yaml 可以查看到
scheme: https #访问metrics的方式,一般是http和https,但是源代码是没有固定参数,可以任意传字符串,所以这里还是写http或者https
tlsConfig: #在抓取端点时使用的TLS配置

namespaceSelector: #命名空间选择器
matchNames: #当监控的pod与servicemonitor不在同一个命名空间就需要进行筛选,使用any: true匹配所有命名空间,不然就写matchNames来匹配
- default

selector: #service标签选择器,kubectl get svc kubernetes -o yaml进行查看,注意svc必须在metadata.label下声明才能进行匹配。
matchLabels:
component: apiserver
provider: kubernetes

官方解析地址如下:
https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md

资源对象Alertmanagers

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
kubectl get alertmanagers main -n monitoring -o yaml > main-alertmanagers.yaml

apiVersion: v1
items:
- apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
labels:
alertmanager: main
name: main
namespace: monitoring
spec:
baseImage: quay.io/prometheus/alertmanager
nodeSelector:
beta.kubernetes.io/os: linux
replicas: 3
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
serviceAccountName: alertmanager-main
version: v0.15.3
kind: List
metadata:
resourceVersion: ""
selfLink: ""
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
- apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
labels:
alertmanager: main
name: main
namespace: monitoring
这是基础的头定义,定义了api类型,资源对象类型,标签,名称,命名空间。
spec:
baseImage: quay.io/prometheus/alertmanager
nodeSelector:
beta.kubernetes.io/os: linux
replicas: 3
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000

设置prometheus建立pod时的参数,基础镜像,节点选择,副本因子数,安全上下文。
安全上下文配置,这里我猜测应该是基于容器container的安全上下文配置。具体参考官方https://www.kubernetes.org.cn/security-context-psp

serviceAccountName: alertmanager-main
RBAC认证账户

version: v0.15.3
镜像的版本号,即alertmanager的版本号

建立的pod是使用statefulsets部署的,会建立一个无头服务service:
serviceName: alertmanager-operated

使用命令kubectl get statefulsets alertmanager-main -n monitoring -o yaml可以查看到;

验证效果

查看建立的service,我们需要访问prometheus数据源和grafana的监控展示web-UI界面,如何访问呢,可以使用service的Nodeport方式,显然这是非常lose的,这里我使用traefik代理方式(traefik安装就不赘述了),建立ingress

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
第一步,查看service
kubectl get svc --all-namespaces

第二步,查看ingress
kubectl get ingress --all-namespaces

新建一个ingress在命名空间monitoring下的
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: prometheus-k8s-grafana
namespace: monitoring
spec:
rules:
- host: prometheus.huisebug.com
http:
paths:
- backend:
serviceName: prometheus-k8s
servicePort: 9090
path: /
- host: grafana.huisebug.com
http:
paths:
- backend:
serviceName: grafana
servicePort: 3000
path: /

给客户机的hosts添加本地解析记录
192.168.137.13 prometheus.huisebug.com grafana.huisebug.com

grafana.huisebug.com

grafana.huisebug.com需要密码验证用户名admin 密码admin并提示修改初始密码

grafana已经添加了k8s集群的监控

prometheus.huisebug.com

从上面可以看到没有获取到kube-controller-manager、kube-scheduler的metric,接下来就解决这个问题,因为这2个服务不是使用kubeadm方式部署的是使用二进制部署的,所以无法获取到。使用kubeadm方式部署的服务都是存在于namespace:kube-system中,例如:

metrics

解决scheduler和controller-manager的metric

想要解决上述问题,先来查看整个集群的service和endpoint

可以看到:

  • service中不存在kube-controller-manager、kube-scheduler
  • endpoint中都有

所以我们需要建立对应的service和修改endpoint的参数

注意新建立service的port名称要与serviceMonitor配置文件对应的上

参考地址,记得修改其中的地址为你的服务器node_ip地址

1
kubectl apply -f https://raw.githubusercontent.com/huisebug/k8s1.12-Ecosphere/master/Prometheus-operator/metrics/scheduler_controller-manager/metics_services.yaml

如果建立后还是无法访问记得使用命令netstat -lntp查看端口是否设置是所有网卡可以访问,如果是127.0.0.1,就修改服务的启动参数,设置为0.0.0.0

上述修改完毕后,就可以再次查看是否成功获取到

mysql-metrics

此处我们建立一个mysql服务的metric验证

首先建立一个mysql服务

参考地址

1
kubectl apply -f https://raw.githubusercontent.com/huisebug/k8s1.12-Ecosphere/master/Prometheus-operator/metrics/mysql-metrics/mysql-metric.yaml

测试是否成功建立mysql服务命令

1
docker run --rm -it mysql sh -c 'exec mysql -h192.168.137.13 -P32306 -pmysql -uroot'

如果能登录,说明mysql服务已经建立

使用helm方式安装mysql-exporter

找到到之前安装traefik的官方charts目录;
进入到stable/prometheus-mysql-exporter目录下就是mysql-exporter的chart了;
values.yaml文件中要指定mysql服务的用户和密码。然后再安装

1
helm install -f values.yaml --name mysql-exporter .

访问mysql-exporter是否有metric生成

这里同样采用traefik代理来访问,建立ingress,上述两个pod都是建立在default命名空间的。

ingress yaml文件参考地址:

1
https://github.com/huisebug/k8s1.12-Ecosphere/blob/master/Prometheus-operator/metrics/mysql-metrics/mysql-metric.yaml

本地解析添加
192.168.137.13 mysqlexporter.huisebug.com

验证访问http://mysqlexporter.huisebug.com/metrics

ServiceMonitor资源对象建立

查看service的对应标签,用于servicemonitor

1
kubectl get svc mysql-exporter-prometheus-mysql-exporter -o yaml| grep -1 labels

参考yaml地址
https://github.com/huisebug/k8s1.12-Ecosphere/blob/master/Prometheus-operator/metrics/mysql-metrics/mysql-metric.yaml

记住servicemonitor必须建立在monitor命名空间下

Prometheus资源对象建立

promethes资源对象在安装monitoring.coreos.com/v1 api的时候建立了一个匹配所有servicemonitot的prometheus资源对象,所以这里我就不建立了,可以参考以下地址:
https://github.com/coreos/prometheus-operator/blob/master/contrib/kube-prometheus/manifests/prometheus-prometheus.yaml

验证效果

再次访问prometheus的target页面查看是否成功获取

成功建立mysql-metric

traefik-metrics

metrics建立

之前建立traefik的时候开启dashboard.enabled=true,dashboard.domain=traefik.huisebug.com,metrics.prometheus.enabled=true
这样我们就可以访问到traefik的metrics

访问地址:http://traefik.huisebug.com/metrics

ServiceMonitor资源对象建立

参考yaml文件

1
kubectl apply -f https://raw.githubusercontent.com/huisebug/k8s1.12-Ecosphere/master/Prometheus-operator/metrics/traefik-metrics/traefik-metrics.yaml

验证效果

alertmanager告警

alertmanager也是提供了web访问控制台的,先使用ingress进行访问

1
kubectl apply -f https://raw.githubusercontent.com/huisebug/k8s1.12-Ecosphere/master/Prometheus-operator/alertmanager/alertmanager-ingress.yaml

记得本地添加解析记录

访问效果

可以看到告警信息这么多,无法找到接收者,所以堆积了。

查看alertmanager的配置参数

下面演示如何用钉钉群组来接收告警信息

钉钉webhook报警2.0版本8060

安装钉钉插件

物理机安装

1
2
3
4
5
6
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v0.3.0/prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz

tar解压后启动

nohup ./prometheus-webhook-dingtalk --ding.profile="ops_dingding=钉钉机器人处复制webhook" 2>&1 1>dingding.log &

物理方式安装就不过多介绍

Docker单机容器部署

钉钉webhook 容器建立
1
docker run -d --restart=always -p 8060:8060 --name=prometheus-webhook-dingtalk timonwong/prometheus-webhook-dingtalk --ding.profile="ops_dingding=钉钉机器人处复制webhook"
修改alertmanager.yaml内容

此处需要修改/root/prometheus-operator-history/contrib/kube-prometheus/manifests/alertmanager-secret.yaml文件,其中的data数据是经过base64加密的,复制出来随便去一个base64解码即可看到。或者运行下面的命令

1
cat alertmanager-secret.yaml | grep alertmanager.yaml | cut -f 2- -d ":" | tr -d " " | base64 –d

我们需要将secret中的alertmanager.yaml修改为如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global:
resolve_timeout: 1h
route:
receiver: webhook
group_wait: 30s
group_interval: 30s
repeat_interval: 10m
group_by: [alertname]
routes:
- receiver: webhook
group_wait: 30s
match:
team: node
receivers:
- name: webhook
webhook_configs:
- url: http://192.168.137.13:8060/dingtalk/ops_dingding/send
send_resolved: true

上述的地址记得修改为你的服务器IP地址

首先在同一级目录下建立一个alertmanager.yaml文件,内容就是如上

运行如下命令

1
2
3
ALT_S=$(cat alertmanager-secret.yaml | grep alertmanager.yaml | cut -f 2- -d ":" | tr -d " ")
ALT_D=$(cat alertmanager.yaml | base64 | tr -d "n" )
sed -i "s/$ALT_S/$ALT_D/" ./alertmanager-secret.yaml

即可完成替换,然后重新建立secret,从之前的alertmanager-main-statefulsets.yaml文件中可以看出secret是挂载到卷的,不是环境变量的方式,这样是支持热更新的

执行修改后的secret文件

1
kubectl apply -f alertmanager-secret.yaml

查看是否修改成功

集群方式部署

都失败了,暂时放弃这种想法了。

hostnetwork方式访问

参考yaml地址
https://github.com/huisebug/k8s1.12-Ecosphere/tree/master/Prometheus-operator/alertmanager/hostnetwork%E6%96%B9%E5%BC%8F

service方式访问

这种方式会存在问题

alertmanager的日志

钉钉插件日志

参考yaml文件

https://github.com/huisebug/k8s1.12-Ecosphere/blob/master/Prometheus-operator/alertmanager/dd_webhook-deployment-svc.yaml

需要将其中的webhook设置成你的

修改alertmanager.yaml内容

此处需要修改/root/prometheus-operator-history/contrib/kube-prometheus/manifests/alertmanager-secret.yaml文件,其中的data数据是经过base64加密的,为了不与上面混淆,将其复制并命名为alertmanager-secret-k8sdd.yaml

我们需要将secret中的alertmanager.yaml修改为如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global:
resolve_timeout: 1h
route:
receiver: webhook
group_wait: 30s
group_interval: 30s
repeat_interval: 10m
group_by: [alertname]
routes:
- receiver: webhook
group_wait: 30s
match:
team: node
receivers:
- name: webhook
webhook_configs:
- url: http://dd-webhook:8060/dingtalk/ops_dingding/send
send_resolved: true

首先在同一级目录下建立一个alertmanager-k8sdd.yaml文件,内容就是如上,修改了地址为service名称
运行如下命令,记住alertmanager-k8sdd.yaml不能存在注释符号

1
2
3
ALT_S=$(cat alertmanager-secret-k8sdd.yaml | grep alertmanager.yaml | cut -f 2- -d ":" | tr -d " ")
ALT_D=$(cat alertmanager-k8sdd.yaml | base64 | tr -d "n" )
sed -i "s/$ALT_S/$ALT_D/" ./alertmanager-secret-k8sdd.yaml

上述方法我感觉是钉钉插件镜像的代码问题,镜像作者也很久未更新了,所以暂时放弃service方式访问

企业微信报警

后续的所有操作都可在以下GitHub地址找到
https://github.com/huisebug/Prometheus-Operator
后续演示的还是基于官方的github来操作

建立企业微信账户

step 1: 访问网站https://work.weixin.qq.com/ 注册企业微信账号(不需要企业认证)。
step 2: 访问apps 创建应用,点击 创建应用按钮 -> 填写应用信息:

如果有则忽略

修改alertmanager.yaml内容

此处需要修改kube-prometheus/manifests/alertmanager-secret.yaml文件,其中的data数据是经过base64加密的,复制出来随便去一个base64解码即可看到。或者运行下面的命令

1
cat alertmanager-secret.yaml | grep alertmanager.yaml | cut -f 2- -d ":" | tr -d " " | base64 –d

我们需要将secret中的alertmanager.yaml修改为如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global:
resolve_timeout: 1h
route:
group_by: ['alertname']
receiver: 'wechat'
group_wait: 30s
group_interval: 30s
repeat_interval: 10m

receivers:
- name: 'wechat'
wechat_configs:
- corp_id: '企业ID'
to_party: '组ID'
agent_id: '应用ID'
api_secret: '应用密钥'
#是否发送恢复信息
send_resolved: true

  • corp_id: 企业微信账号唯一 ID, 可以在”我的企业”中查看。
  • to_party: 需要发送的组(部门ID)。即
  • agent_id: 第三方企业应用的 ID,可以在自己创建的第三方企业应用详情页面查看。
  • api_secret:第三方企业应用的密钥,可以在自己创建的第三方企业应用详情页面查看。

    将上面修改好的内容进行base64加密,然后copy到alertmanager-secret.yaml中,然后在alertmanager web页面进行查看

建立资源类型PrometheusRule

默认的在建立Prometheus-Operator时候会建立官方推荐的一些告警规则,为便于测试,可暂时删除prometheus-rules.yaml中的资源类型PrometheusRule规则

1
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig delete -f kube-prometheus/manifests/prometheus-rules.yaml

然后执行我新建的一些简单告警规则资源类型PrometheusRule(服务状态规则,mysql服务状态规则)

1
2
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -f kube-prometheus/manifests/new/mysql-rules.yaml
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -f kube-prometheus/manifests/new/state-rules.yaml

建立对应的告警目标服务

根据上面我们建立的告警规则,我们需要建立mysql服务,mysql监控服务

1
2
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -f kube-prometheus/manifests/new/mysql-rc.yaml
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -fkube-prometheus/manifests/new/mysql-exporter.yaml

在prometheus web页面查看

验证告警效果

注意验证方法,MySQL服务自身是没有提供metrics,是依靠mysql-exporter这个服务去收集的,所以当MySQL服务无法访问的时候才能实现mysql告警,MySQL-exporter服务停止是服务停止告警,此处我需要将mysql服务的service配置删除,已达到服务无法访问的效果

1
2
kubectl.exe --kubeconfig=./kubeconfig/sre.kubeconfig get svc
kubectl.exe --kubeconfig=./kubeconfig/sre.kubeconfig delete svc mysql-svc

30秒后就可以在两个控制台分别看到如下

企业微信客户端收到错误告警如下

重新建立svc,验证恢复告警

1
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -f kube-prometheus/manifests/new/mysql-rc.yaml

总结:

  • 告警信息太多,太杂乱
  • 错误告警和恢复告警基本内容差不多,无法区别
  • 需要自定义告警模板来便于快速定位

建立自定义告警模板

alertmanager-temp-configmap.yaml

上面的模板是使用的gotemplate语法编写,其中包含了错误告警和恢复告警,具体编写请参考以下链接
https://github.com/songjiayang/prometheus_practice/issues/12

修改alertmanager.yaml内容

我们需要将secret中的alertmanager.yaml修改为如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
global:
resolve_timeout: 1h
route:
group_by: ['alertname']
receiver: 'wechat'
group_wait: 30s
group_interval: 30s
repeat_interval: 10m

receivers:
- name: 'wechat'
wechat_configs:
- corp_id: '企业ID'
to_party: '组ID'
agent_id: '应用ID'
api_secret: '应用密钥'
#是否发送恢复信息
send_resolved: true
#告警模板
templates:
- '/etc/alertmanager/configmaps/alertmanager-temp/temp.yaml'

  • templates:指定告警模板的存放位置,注意此处的路径是固定格式的/etc/alertmanager/configmaps/+configmap名称+configmap中的键名,即我在new目录下的alertmanager-temp-configmap.yaml,如下:

将上面修改好的内容进行base64加密,然后copy到alertmanager-secret.yaml中,然后在alertmanager web页面进行查看

alertmanager服务添加configmap挂载

alertmanager服务的建立是statefulset建立的,是依据alertmanager-alertmanager.yaml文件建立的,需要增加自定义模板的configmap挂载,并且默认是挂载到/etc/alertmanager/configmaps/下的,可参照官方介绍https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#alertmanagerspec

修改如下:

所以需要重新建立alertmanager服务

1
kubectl --kubeconfig=./kubeconfig/sre.kubeconfig apply -f kube-prometheus/manifests/alertmanager-alertmanager.yaml

再次验证告警效果,同样的删除mysql的svc。企业微信效果如下

企业微信/QQmail同时报警

配置文件如下

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: 1h
smtp_smarthost: 'smtp.qq.com:587'
smtp_from: '发件人'
smtp_auth_username: '发件人'
smtp_auth_password: '授权码'

route:
group_by: ['alertname']
group_wait: 30s
group_interval: 30s
repeat_interval: 10m
receiver: 'huisebug'
routes:
- receiver: 'wechat'
continue: true
- receiver: 'huisebug'
continue: true

receivers:
- name: 'huisebug'
email_configs:
- to: '收件人'
send_resolved: true
- name: 'wechat'
wechat_configs:
- corp_id: ''
to_party: '8'
agent_id: '1000009'
api_secret: ''
send_resolved: true

templates:
- '/etc/alertmanager/configmaps/alertmanager-temp/temp.yaml'