Prometheus AlertManager 实战
Prometheus
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 #这里已经显示我们创建好的alert-config
现在我们在之前的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可以看到被禁用的监控
非常好 就是 可以吧内存规则修改下
rules.yml: |
groups:
– name: abcdocker-test-rule
rules:
– alert: NodeMemoryUsage
expr: 100-(node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes)/node_memory_MemTotal_bytes*100 >= 10
for: 1m
annotations:
summary: “机器 $labels.instance 内存使用的率超过10%”
一些相关配置马上优化了