Prometheus AlertManager 实战
AlerManager 简介
Prometheus包含了一个报警模块,那就是AlertManager,主要用于接受Prometheus发送的告警信息,它支持丰富的告警通知渠道,而且很容易做到告警信息进行去重,降噪,分组等,是一个前卫的告警通知系统
安装 AlerManager
prometheus配置文件官方文档
https://prometheus.io/docs/alerting/configuration/
首先,我们需要先指定配置文件 ,这里我们还是创建一个ConfigMap
资源对象
cat >> prometheus-alert-conf.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: alert-config
namespace: kube-system
data:
config.yml: |-
global:
# 在没有报警的情况下声明为已解决的时间
resolve_timeout: 5m
# 配置邮件发送信息
smtp_smarthost: 'smtp.163.com:465'
smtp_from: 'xxx@163.com'
smtp_auth_username: 'xxx@163.com'
smtp_auth_password: '授权密码'
smtp_hello: '163.com'
smtp_require_tls: false
# 所有报警信息进入后的根路由,用来设置报警的分发策略
route:
# 这里的标签列表是接收到报警信息后的重新分组标签,例如,接收到的报警信息里面有许多具有 cluster=A 和 alertname=LatncyHigh 这样的标签的报警信息将会批量被聚合到一个分组里面
group_by: ['alertname', 'cluster']
# 当一个新的报警分组被创建后,需要等待至少group_wait时间来初始化通知,这种方式可以确保您能有足够的时间为同一分组来获取多个警报,然后一起触发这个报警信息。
group_wait: 30s
# 当第一个报警发送后,等待'group_interval'时间来发送新的一组报警信息。
group_interval: 5m
# 如果一个报警信息已经发送成功了,等待'repeat_interval'时间来重新发送他们
repeat_interval: 5m
# 默认的receiver:如果一个报警没有被一个route匹配,则发送给默认的接收器
receiver: default
# 上面所有的属性都由所有子路由继承,并且可以在每个子路由上进行覆盖。
routes:
- receiver: email
group_wait: 10s
match:
team: node
receivers:
- name: 'default'
email_configs:
- to: '604419314@qq.com'
send_resolved: true
- name: 'email'
email_configs:
- to: '604419314@qq.com'
send_resolved: true
EOF
授权密码申请,这里以163邮箱为例
我们现在创建alertmanager的配置文件
[root@abcdocker prometheus]# kubectl create -f prometheus-alert-conf.yaml
configmap/alert-config created
[root@yzsjhl82-138 prometheus]# kubectl get cm -n kube-system
NAME DATA AGE
alert-config 1 25s
coredns 1 40d
extension-apiserver-authentication 6 40d
grafana-config 1 20h
kube-flannel-cfg 2 40d
kubernetes-dashboard-settings 1 40d
prometheus-config 1 23m
现在我们在之前的prometheus pod的yaml文件中添加这个容器
这里我们将上面创建的aler-config这个configmap资源对象volume的形式挂载到/etc/alertmanager
目录下去,然后在启动参数中指定--config.file=/etc/alertmanager/config.yml
- name: alermanager
image: prom/alertmanager:v0.15.3
imagePullPolicy: IfNotPresent
args:
- "--config.file=/etc/alertmanager/config.yml"
- "--storage.path=/alertmanager/data"
ports:
- containerPort: 9093
name: http
volumeMounts:
- mountPath: "/etc/alertmanager"
name: alertcfg
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 200m
memory: 1024Mi
...
- name: alertcfg
configMap:
name: alert-config
在0.15版本,alertmanager的WORKDIR发生了变化,变成/etc/alertmanager默认情况下存储路径--storage.path
是相对目录data/
,因此alertmanager会在我们上面挂载的ConfigMap中去创建这个目录,所以会报错,这里通过--storage.path
参数来解决
#更新deployment
[root@abcdocker prometheus]# kubectl apply -f prometheus.deploy.yaml
deployment.extensions/prometheus configured
如果不会修改yaml可以直接使用我的yaml文件
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: prometheus
namespace: kube-system
labels:
app: prometheus
spec:
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
containers:
- image: prom/prometheus:v2.4.3
name: prometheus
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention=7d"
- "--web.enable-admin-api" # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
- "--web.enable-lifecycle" # 支持热更新,直接执行localhost:9090/-/reload立即生效
ports:
- containerPort: 9090
protocol: TCP
name: http
volumeMounts:
- mountPath: "/prometheus"
subPath: prometheus
name: data
- mountPath: "/etc/prometheus"
name: config-volume
resources:
requests:
cpu: 400m
memory: 100Mi
limits:
cpu: 400m
memory: 2Gi
- name: alermanager
image: prom/alertmanager:v0.15.3
imagePullPolicy: IfNotPresent
args:
- "--config.file=/etc/alertmanager/config.yml"
- "--storage.path=/alertmanager/data"
ports:
- containerPort: 9093
name: http
volumeMounts:
- mountPath: "/etc/alertmanager"
name: alertcfg
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 200m
memory: 1024Mi
securityContext:
runAsUser: 0
volumes:
- name: data
persistentVolumeClaim:
claimName: prometheus
- configMap:
name: prometheus-config
name: config-volume
- name: alertcfg
configMap:
name: alert-config
查看一下pod启动状态
[root@abcdocker prometheus]# kubectl get pod -n kube-system |grep prometheus
prometheus-5486fc867b-cb7z6 2/2 Running 0 2m20s
AlertManager容器启动之后,我们还需要在Prometheus中配置下AlertManager的地址,让Prometheus能够访问AlertManager
alerting:
alertmanagers:
- static_configs:
- targets: ["localhost:9093"]
配置截图
接下来更新一下Prometheus配置文件
[root@abcdocker prometheus]# kubectl delete -f prometheus.configmap.yaml
configmap "prometheus-config" deleted
[root@abcdocker prometheus]# kubectl create -f prometheus.configmap.yaml
configmap/prometheus-config created
[root@abcdocker prometheus]# curl -X POST http://10.101.143.162:9090/-/reload
#确保更新配置没有报错(刷新比较慢可以等等)
现在prometheus alertmanager并没有告警的规则,还需要我们添加报警规则
Prometheus 报警规则
上面我们将prometheus和alertmanager进行了关联,但是现在并没有报警规则,所以这里还需要配置一些报警规则。让prometheus触发报警
#首先在prometheus.configmap.yaml文件中添加报警规则,下面的文件就是prometheus报警的规则文件
rule_files:
- /etc/prometheus/rules.yml
报警规则允许基于Prometheus表达式语言来定义报警规则条件,并在出发报警时发送给外部
我们上面已经将
/etc/promtehus
进行挂载了,所以这里只需要修改prometheus-configmap就可以了。
rules.yml: |
groups:
- name: abcdocker-test-rule
rules:
- alert: NodeMemoryUsage
expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 > 50
for: 1m
labels:
team: node
annotations:
summary: "{{ $labels.instance }}:High Memory Usage detected"
description: "{{ $labels.instance }}: Memory usage us avive 50% (current value is :: {{ $value }})"
#配置相关参数说明
rules.yml: |
groups:
- name: abcdocker-test-rule
rules: #规则
- alert: NodeMemoryUsage #报警名称(内存报警)
expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 > 50 #规则表达式
for: 1m #等待1分钟执行查询条件
labels:
team: node #当我们触发报警后,带有team=node的标签,并且这里走的是我们alertmanager node标签,这里对应的就是我们的email接收器
annotations: #指定另外一组标签,不会将这个标签当做我们告警的身份标示(不会在我们报警信息里操作)这里主要是用于额外的展示,例如发送给邮件里面>的报警信息
summary: "{{ $labels.instance }}:High Memory Usage detected" #label标签,instance代表节点名称
description: "{{ $labels.instance }}: Memory usage us avive 50% (current value is :: {{ $value }})" #描述:相当于报警信息 $value代表当前值
说明一点
expr
所执行的命令是可以在prometheus上获取到数据的
配置截图
完整配置如下
[root@yzsjhl82-135 prometheus]# cat prometheus.configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: kube-system
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ["localhost:9093"]
rule_files:
- /etc/prometheus/rules.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'kubernetes-node'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
- job_name: 'kubernetes-cadvisor'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
rules.yml: |
groups:
- name: abcdocker-test-rule
rules:
- alert: NodeMemoryUsage
expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 > 20
for: 1m
labels:
team: node
annotations:
summary: "{{ $labels.instance }}:High Memory Usage detected"
description: "{{ $labels.instance }}: Memory usage us avive 50% (current value is :: {{ $value }})"
报警说明
本次报警大概意思是当服务器内存百分比大于80的时候,就进行报警,并且通过labels标签关联team:node (这里team=node是在我们alertmanager里面配置的接收器,默认是default),并且报警内容添加主机和当前内存使用率
接下来我们访问prometheus,点击alerts,就可以看到我们添加的NodeMemoryUsage
我这里将脚本改成>50
等待1分钟后
prometheus进入了等待PENDING
状态
当前值已经大于我们设置的50%,现在已经出发报警
邮件内容如下
alertManager Ui界面
我们可以在邮件内容中看到包含View in AlertManager
的链接,这是alertmanager自带的Ui界面。我们可以使用NodePort进行访问
这里需要修改一下prometheus的service
cat >>prometeheus-svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: kube-system
labels:
app: prometheus
spec:
selector:
app: prometheus
type: NodePort
ports:
- name: web
port: 9090
targetPort: http
- name: alertmanager
port: 9093
targetPort: 9093
EOF
如果前面也是按照我的文档操作的,可以在prometheus后面添加一个svc端口接口
- name: alertmanager
port: 9093
targetPort: 9093
我们查看一下node-port端口
[root@abcdocker prometheus]# kubectl get svc -n kube-system |grep prometheus
prometheus NodePort 10.96.163.206 9090:32567/TCP,9093:31212/TCP 73s
访问alertmanager端口为9093=31212
(集群任一节点访问即可)
在上面的图片,我们可以看到IP为82.139
一直在报警,如果不想接收这个IP报警。可以点击Slience
注意Prometheus有8小时时区问题
这时候报警匹配为82.139的IP,在2个小时内。不进行报警,我们点击创建就可以。在Comment输入提交内容就可以了
这里可以直接编辑,或者直接让它过期
这里我们已经看不到报警内容了
点击Silences可以看到被禁用的监控