背景
目前的告警通知采用grafana來通知dingding群,這只是grafana的一個功能,所以在靈活性上還是有很多缺陷的,不如專門做告警通知的alertmanager方便
grafana告警
優(yōu)點:
- 可以發(fā)送趨勢圖,并且配置上來講比較方便,直接在監(jiān)控圖里配置即可,比較簡單
缺點:
- 不能創(chuàng)建一個告警模板應(yīng)用到一批實例上,意味著我們要每個實例都去配置一下告警,非常麻煩。
- 不能分組,比如: 一個集群的多臺機器,都掛掉了,那我們可能一下分別收到5,6個告警,這樣大量冗余消息,時間長了人可能會有疏忽。
- 告警恢復(fù)的消息,不能顯示恢復(fù)的是哪個機器,只有一個ok和告警名,多個告警下來,具體是哪個恢復(fù)了我們也不知道。
alertmanger告警
優(yōu)點:
- 可分組、靜默、抑制(三大特性)來靈活控制告警規(guī)則發(fā)送到微信,釘釘,郵件,比如多個機器同個級別的告警可以合并成一個,避免冗余郵件。
- 告警恢復(fù)是完整顯示信息的,恢復(fù)后我們可以知道是哪個機器恢復(fù)了,這直接完美替代了grafana的缺點。
缺點:
- 相對于grafana來講,配置流程上要繁瑣許多,并且很多字段也需要熟悉,dingding之類告警還需要安裝第三方插件實現(xiàn)。維護起來確實有成本,但是一次配置好了,就可以慢慢享受它帶來的優(yōu)點了
核心概念
1. 分組
將類似性質(zhì)的警報分類到單個通知中。這在較大的中斷期間特別有用,因為許多系統(tǒng)同時發(fā)生故障,并且可能同時觸發(fā)數(shù)百到數(shù)千個警報。這樣解決了警報冗余
2. 抑制
抑制是一種概念,即在某些其他警報已觸發(fā)時禁止顯示某些警報的通知,比如server01觸發(fā)了嚴(yán)重級別的警報,那警告(waring)級別的就沒必要在通知了。抑制就是干這個用的
3. 靜默
靜默是一種在給定時間內(nèi)簡單地將警報靜音的簡單方法。靜音是根據(jù)匹配器配置的,就像路由樹一樣。將檢查傳入警報是否與活動靜默的所有相等或正則表達式匹配器匹配。如果這樣做,則不會為該警報發(fā)送任何通知。 靜默是在警報管理器的 Web 界面中配置的。場景就比如: 某一臺機器設(shè)置了數(shù)據(jù)備份的定時任務(wù),每天凌晨這段時間會占用大量CPU或內(nèi)存,會超過閾值觸發(fā)告警,那我們設(shè)置靜默將其”靜音“, 杜絕不必要的告警信息
整體實現(xiàn)思路
部署alertmanager
部署prometheus-webhook(實現(xiàn)釘釘告警的第三方插件)
在alertmanager.yml配置文件中配置郵箱服務(wù)器,模板路徑,路由數(shù),分組,接收人(定義接受的對象,如郵箱,微信,釘釘)
在prometheus-webhook配置文件config.yml中,來配置釘釘機器人的密鑰與url(提前加好機器人),引用模板文件(就是alertmanager定義的模板)
配置Prometheus與Alertmanager通信
在Prometheus中創(chuàng)建告警規(guī)則
重啟服務(wù),測試
一. 安裝Alertmanger
1.1 安裝包下載
#alertmanager
地址1:https://prometheus.io/download/
地址2:https://github.com/prometheus/alertmanager/releases
#prometheus-webhook
https://github.com/timonwong/prometheus-webhook-dingtalk/releases
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v0.3.0/prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz
1.2 兩個安裝包解壓安裝在/opt/下
tar zxvf alertmanager-xxxx.tar.gz
ln -s alertmanager-0.24.0.linux-amd64 alertmanager
tar zxvf prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz
ln -s prometheus-webhook-dingtalk-2.0.0.linux-amd64/ /opt/prometheus-webhook
1.3 兩個服務(wù)service文件
alertmanager:
# cat /usr/lib/systemd/system/alertmanager.service
[Unit]
Description=alertmanager
[Service]
ExecStart=/opt/alertmanager/alertmanager --config.file=/opt/alertmanager/alertmanager.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
prometheus-webhook:
# cat /usr/lib/systemd/system/prometheus-webhook.service
[Unit]
Description=Prometheus Dingding Webhook
[Service]
ExecStart=/opt/prometheus-webhook/prometheus-webhook-dingtalk --config.file=/opt/prometheus-webhook/config.yml
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
啟動服務(wù)
systemctl start alertmanager
systemctl start prometheus-webhook.service
二. 配置Prometheus
1. 配置Prometheus與Alertmanager通信
打開prometheus的配置文件 /opt/prometheus/prometheus.yml , /opt/prometheus/prometheus2.yml 分別進行修改(根據(jù)實際情況,有兩個prometheus實例)
找到并修改為如下內(nèi)容:
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- 127.0.0.1:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
- "rules/*.yml"
2. 創(chuàng)建規(guī)則目錄
mkdir -pv /opt/prometheus/rules
3. 配置規(guī)則
注意: 這里列舉兩個常用的規(guī)則文件,其余根據(jù)實際情況自行修改(可以去prometheus的web頁面上自己先查一遍,看表達式是否正確查出數(shù)據(jù))
a. 主機存活告警文件,分組名為servers_survival:
root@rancher2x.hw:/opt/prometheus/rules# cat servers_survival.yml
groups:
- name: servers_survival
rules:
- alert: 節(jié)點存活--測試--應(yīng)用服務(wù)器 #告警規(guī)則名稱
expr: up{job="hw-nodes-test-rancher"} == 0
for: 1m #等待評估時間
labels: #自定義標(biāo)簽,定義一個level標(biāo)簽,標(biāo)記這個告警規(guī)則警告級別: critical嚴(yán)重,warning警告
level: critical
annotations: #指定附加信息(郵件標(biāo)題文本)
summary: "機器 {{ $labels.instance }} 掛了"
description: "服務(wù)器{{$labels.instance}} 掛了 (當(dāng)前值: {{ $value }})"
- alert: 節(jié)點存活--華為云--生產(chǎn)其他服務(wù)器
expr: up{job="hw-nodes-prod-other"} == 0
for: 1m
labels:
level: critical
annotations:
summary: "機器 {{ $labels.instance }} 掛了"
description: "{{$labels.instance}} 宕機(當(dāng)前值: {{ $value }})"
- alert: 節(jié)點存活--華為云--生產(chǎn)ES服務(wù)器
expr: up{job="hw-nodes-prod-ES"} == 0
for: 1m
labels:
level: critical
annotations:
summary: "機器 {{ $labels.instance }} 掛了"
description: "{{$labels.instance}} 宕機(當(dāng)前值: {{ $value }})"
b. 主機狀態(tài)告警文件,分組名為servers_status:
root@rancher2x.hw:/opt/prometheus/rules# cat servers_status.yml
groups:
- name: servers_status
rules:
- alert: CPU負(fù)載1分鐘告警
expr: node_load1{job!~"(nodes-dev-GPU|hw-nodes-test-server|hw-nodes-prod-ES|hw-nodes-prod-MQ)"} / count (count (node_cpu_seconds_total{job!~"(nodes-dev-GPU|hw-nodes-test-server|hw-nodes-prod-ES|hw-nodes-prod-MQ)"}) without (mode)) by (instance, job) > 2.5
for: 1m
labels:
level: warning
annotations:
summary: "{{ $labels.instance }} CPU負(fù)載告警 "
description: "{{$labels.instance}} 1分鐘CPU負(fù)載(當(dāng)前值: {{ $value }})"
- alert: CPU使用率告警
expr: 1 - avg(irate(node_cpu_seconds_total{mode="idle",job!~"(IDC-GPU|hw-nodes-prod-ES|nodes-test-GPU|nodes-dev-GPU)"}[30m])) by (instance) > 0.85
for: 1m
labels:
level: warning
annotations:
summary: "{{ $labels.instance }} CPU使用率告警 "
description: "{{$labels.instance}} CPU使用率超過85%(當(dāng)前值: {{ $value }} )"
- alert: CPU使用率告警
expr: 1 - avg(irate(node_cpu_seconds_total{mode="idle",job=~"(IDC-GPU|hw-nodes-prod-ES)"}[30m])) by (instance) > 0.9
for: 1m
labels:
level: warning
annotations:
summary: "{{ $labels.instance }} CPU負(fù)載告警 "
description: "{{$labels.instance}} CPU使用率超過90%(當(dāng)前值: {{ $value }})"
- alert: 內(nèi)存使用率告警
expr: (1-node_memory_MemAvailable_bytes{job!="IDC-GPU"} / node_memory_MemTotal_bytes{job!="IDC-GPU"}) * 100 > 90
labels:
level: critical
annotations:
summary: "{{ $labels.instance }} 可用內(nèi)存不足告警"
description: "{{$labels.instance}} 內(nèi)存使用率已達90% (當(dāng)前值: {{ $value }})"
- alert: 磁盤使用率告警
expr: 100 - (node_filesystem_avail_bytes{fstype=~"ext4|xfs", mountpoint !~ "/var/lib/[kubelet|rancher].*" } / node_filesystem_size_bytes{fstype=~"ext4|xfs", mountpoint !~ "/var/lib/[kubelet|rancher].*"}) * 100 > 85
labels:
level: warning
annotations:
summary: "{{ $labels.instance }} 磁盤使用率告警"
description: "{{$labels.instance}} 磁盤使用率已超過85% (當(dāng)前值: {{ $value }})"
4. 熱加載prometheus配置
curl -X POST http://localhost:9090/-/reload
去web上查看確認(rèn)rules是否被prometheus加載

三. 配置Alertmanger
上面配置了prometheus與alertmanager的通信,接下來我們配下alertmanager來實現(xiàn)發(fā)送告警信息給我們
這里我們主要以釘釘告警為例子
1. 釘釘上添加一個釘釘機器人,
設(shè)置好名字,群組,選擇加簽,確定。
2. 修改prometheus-webook配置文件綁定申請的機器人
我只綁定了一個webhook所以只要配置到webhook1
root@rancher2x.hw:/opt/prometheus-webhook# cat config.yml
## Customizable templates path
templates:
## - templates/alertmanager-dingtalk.tmpl
- /opt/alertmanager/dingding3.tmpl # 配置告警模板的所在位置
#default_message:
# title: '{{ template "legacy.title" . }}'
# text: '{{ template "legacy.content" . }}'
## Targets, previously was known as "profiles"
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxx # 配置機器人的webhook_url
# secret for signature
secret: SEC65342be21ab54b730da9347be9307b7831bd65adf1c99406fedc786f62fecb98 # 配置加簽(申請的時候那串?dāng)?shù)字)
message:
title: '{{ template "ops.title" . }}' # 給這個webhook應(yīng)用上 模板標(biāo)題 (ops.title是我們模板文件中的title 可在下面給出的模板文件中看到)
text: '{{ template "ops.content" . }}' # 給這個webhook應(yīng)用上 模板內(nèi)容 (ops.content是我們模板文件中的content 可在下面給出的模板文件中看到)
3. 告警模板文件
root@rancher2x.hw:/opt/# cat /opt/alertmanager/dingding3.tmpl
{{ define "__subject" }}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}]
{{ end }}
{{ define "__alert_list" }}{{ range . }}
---
**告警類型**: {{ .Labels.alertname }}
**告警級別**: {{ .Labels.level }}
**故障主機**: {{ .Labels.instance }}
**告警信息**: {{ .Annotations.description }}
**觸發(fā)時間**: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{ end }}{{ end }}
{{ define "__resolved_list" }}{{ range . }}
---
**告警類型**: {{ .Labels.alertname }}
**告警級別**: {{ .Labels.level }}
**故障主機**: {{ .Labels.instance }}
**觸發(fā)時間**: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
**恢復(fù)時間**: {{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{ end }}{{ end }}
{{ define "ops.title" }}
{{ template "__subject" . }}
{{ end }}
{{ define "ops.content" }}
{{ if gt (len .Alerts.Firing) 0 }}
**====偵測到{{ .Alerts.Firing | len }}個故障====**
{{ template "__alert_list" .Alerts.Firing }}
---
{{ end }}
{{ if gt (len .Alerts.Resolved) 0 }}
**====恢復(fù){{ .Alerts.Resolved | len }}個故障====**
{{ template "__resolved_list" .Alerts.Resolved }}
{{ end }}
{{ end }}
{{ define "ops.link.title" }}{{ template "ops.title" . }}{{ end }}
{{ define "ops.link.content" }}{{ template "ops.content" . }}{{ end }}
{{ template "ops.title" . }}
{{ template "ops.content" . }}
4. 修改alertmanager配置文件為如下內(nèi)容
注:這里也加上了郵件相關(guān)的配置
root@rancher2x.hw:/opt/alertmanager# cat alertmanager.yml
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.163.com:25'
smtp_from: 'xxx@163.com'
smtp_auth_username: 'xxxx@163.com'
smtp_auth_password: '郵箱的授權(quán)碼'
smtp_require_tls: false
templates:
- '/opt/alertmanager/*.tmpl' #告警模板位置
route:
group_by: ['servers_survival','servers_status'] # 根據(jù)告警規(guī)則組名進行分組
group_wait: 30s # 分組內(nèi)第一個告警等待時間,10s內(nèi)如有第二個告警會合并一個告警
group_interval: 5m # 發(fā)送新告警間隔時間
repeat_interval: 30m #重復(fù)告警間隔發(fā)送時間,如果沒處理過多久再次發(fā)送一次
receiver: 'dingtalk_webhook' # 接收人
receivers:
- name: 'ops'
email_configs:
- to: 'tianye@163.com'
html: '{{ template "email.to.html" .}}'
headers: { Subject: "[WARNING]Prometheus告警郵件" }
send_resolved: true
- name: 'dingtalk_webhook'
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send' # 填寫prometheus-webhook的webhook1 url
send_resolved: true # 在恢復(fù)后是否發(fā)送恢復(fù)消息給接收人
5. 重啟服務(wù)
systemctl restart prometheus-webhook.service
systemctl restart alertmanager.service
四. 測試
- 我們可以通過故意調(diào)整閾值 或者 停掉告警檢測中主機上的node_exporter探針來測試一下
root@rs02.test.hw:~# systemctl stop node_exporter.service
-
prometheus上可以看到已經(jīng)觸發(fā)了告警規(guī)則閾值
image.png -
此時釘釘群里收到了告警郵件 (這里圖示是恢復(fù)探針后,告警和恢復(fù)消息一起展示)
1661223198483.png
以上只是初步使用 ,后面更新我們更好的利用好三大特性中的抑制和靜默完成最佳實踐
———————————————————————————————————————————————————
20220831更新:
Alertmanager之抑制
場景:
當(dāng)我們的分級告警時,比如:
平時監(jiān)控 server-01機器的存活,也監(jiān)控這臺機器的nginx服務(wù)存活時,當(dāng)主機宕機后,我們會同時收到 server-01掛掉和nginx服務(wù)掛掉 兩條警報(甚至連帶更多),顯然對我們來講,這都是沒必要發(fā)出的郵件,真正造成這個告警的原因是-主機宕機這個警告,所以我們只需要關(guān)注這個就好,別的沒必要發(fā)了。
平時監(jiān)控 jenkins主機的內(nèi)存使用率,85%定為warnning級別,90%定為critical級別 ,在內(nèi)存飆升的過程中,可能剛觸發(fā)完85%又觸發(fā)了90%,所以我們也會收到兩個告警。比如下圖:

所以這個情況需要,一段時間內(nèi),同一個主機的critical級別要抑制住warning級別,減少冗余發(fā)送。
操作
我們用監(jiān)控nginx和docker服務(wù)做一個實踐

分別停了nginx和docker服務(wù)后,收到兩個告警。

恢復(fù)以上服務(wù),現(xiàn)在只需要在alertmanager配置文件中加入(頂級配置),再次重啟alertmanager
inhibit_rules:
# source_match: 匹配當(dāng)前告警發(fā)生后其他告警抑制掉
- source_match:
level: 'critical'
# target_match:被抑制告警
target_match:
level: 'warning'
# equal: 只有包含指定標(biāo)簽才可成立規(guī)則,這里表示兩個告警級別的主機都“相同”時,成功抑制 ,這里也可以寫多個標(biāo)簽
equal: ['instance']
再次嘗試停掉nginx和docker,可以看到只有critical的告警

Alertmanager之靜默
場景
今晚有業(yè)務(wù)維護,需要停掉nginx服務(wù),必然會發(fā)生警告,所以我們可以將這個告警提前 "靜音"
操作
還是以上nginx服務(wù)告警為例。
打開alertmanager的web頁面(127.0.0.1:9093),點擊 New Silence,將匹配項填上去,完成創(chuàng)建。
匹配項:
可以是alertname(就是你prometheus中rules告警規(guī)則yml文件中的name),job ,instance,這些在Promethues中可用的都可以。

完成創(chuàng)建后,停掉nginx
systemctl stop nginx
告警已經(jīng)觸發(fā),prometheus已經(jīng)將警告給了alertmanager,但是alertmanager將這個項“靜音”了,我們維護的時候不會收到告警


