在前一篇博文中介紹,服務器監控已經部署成功。如果每天都需要人去盯着服務情況,那也不太現實。既然監控平台已經部署好了,是不是可以自動觸發報警呢?
在上一篇Prometheus架構中有講到,核心組件之一:AlertManager,AlertManager即Prometheus體系中的告警處理中心。所以實現告警功能,可以使用該組件,具體如何實現,我們來看。
AlertManager配置
服務部署
拉取鏡像
使用命令 docker pull prom/alertmanager:latest
服務啟動
使用如下命令:
docker run -d --name alertmanager -p 9093:9093 \
prom/alertmanager:latest
啟動服務后,通過地址訪問,http://
配置文件
AlertManager 默認配置文件為 alertmanager.yml,在容器內路徑為 /etc/alertmanager/alertmanager.yml
,默認配置如下:
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
簡單介紹一下主要配置的作用:
• global: 全局配置,包括報警解決后的超時時間、SMTP 相關配置、各種渠道通知的 API 地址等等。
• route: 用來設置報警的分發策略,它是一個樹狀結構,按照深度優先從左向右的順序進行匹配。
• receivers: 配置告警消息接受者信息,例如常用的 email、wechat、slack、webhook 等消息通知方式。
• inhibit_rules: 抑制規則配置,當存在與另一組匹配的警報(源)時,抑制規則將禁用與一組匹配的警報(目標)。
告警規則
alertmanager配置好后,我們來添加告警規則,就是符合規則,才會推送消息,規則配置如下:
mkdir -p /root/prometheus/rules && cd /root/prometheus/rules/
vim host.rules
添加如下信息:
groups:
- name: node-up
rules:
- alert: node-up
expr: up{job="linux"} == 0
for: 15s
labels:
severity: 1
team: node
annotations:
summary: "{{ $labels.instance }} 已停止運行超過 15s!"
說明一下:該 rules
目的是監測 node
是否存活,expr 為 PromQL 表達式驗證特定節點 job="linux"
是否活着,for 表示報警狀態為 Pending 后等待 15s 變成 Firing 狀態,一旦變成 Firing 狀態則將報警發送到 AlertManager,labels 和 annotations 對該 alert 添加更多的標識說明信息,所有添加的標簽注解信息,以及 prometheus.yml 中該 job 已添加 label 都會自動添加到郵件內容中 ,參考規則。
prometheus.yml配置文件
修改prometheus.yml配置文件,添加 rules 規則文件,已有內容不變,配置文件中添加如下內容:
alerting:
alertmanagers:
- static_configs:
- targets:
- 'ip:9093'
rule_files:
- "/etc/prometheus/rules/*.rules"
注意: 這里rule_files為容器內路徑,需要將本地host.rules文件掛載到容器內指定路徑,修改 Prometheus 啟動命令如下,並重啟服務。
docker run -d --name prometheus \
-p 9090:9090 \
-v /root/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-v /root/prometheus/rules/:/etc/prometheus/rules/ \
prom/prometheus
通過ip+端口訪問,查看rules,如下所示:
這里說明一下 Prometheus Alert 告警狀態有三種狀態:Inactive、Pending、Firing。
- Inactive:非活動狀態,表示正在監控,但是還未有任何警報觸發。
- Pending:表示這個警報必須被觸發。由於警報可以被分組、壓抑/抑制或靜默/靜音,所以等待驗證,一旦所有的驗證都通過,則將轉到 Firing 狀態。
- Firing:將警報發送到 AlertManager,它將按照配置將警報的發送給所有接收者。一旦警報解除,則將狀態轉到 Inactive,如此循環。
說了這么多,就用推送郵件來實踐下結果。
郵件推送
郵件配置
我們來配置一下使用 Email 方式通知報警信息,這里以 QQ 郵箱為例,新建目錄 mkdir -p /root/prometheus/alertmanager/ && cd /root/prometheus/alertmanager/
使用vim命令 vim alertmanager.yml
,配置文件中添加如下內容:
global:
resolve_timeout: 5m
smtp_from: '11111111@qq.com'
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: '11111111@qq.com'
smtp_auth_password: 'XXXXXXXXX'
smtp_hello: 'qq.com'
smtp_require_tls: false
route:
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: '222222222@foxmail.com'
send_resolved: true
#insecure_skip_verify: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
其中幾個關鍵的配置說明一下:
- smtp_smarthost: 這里為 QQ 郵箱 SMTP 服務地址,官方地址為 smtp.qq.com 端口為 465 或 587,同時要設置開啟 POP3/SMTP 服務。
- smtp_auth_password: 這里為第三方登錄 QQ 郵箱的授權碼,非 QQ 賬戶登錄密碼,否則會報錯,獲取方式在 QQ 郵箱服務端設置開啟 POP3/SMTP 服務時會提示。
- smtp_require_tls: 是否使用 tls,根據環境不同,來選擇開啟和關閉。如果提示報錯 email.loginAuth failed: 530 Must issue a STARTTLS command first,那么就需要設置為 true。着重說明一下,如果開啟了 tls,提示報錯 starttls failed: x509: certificate signed by unknown authority,需要在 email_configs 下配置 insecure_skip_verify: true 來跳過 tls 驗證。
重啟AlertManager
修改 AlertManager 啟動命令,將本地alertmanager.yml文件掛載到容器內指定位置,是配置生效,命令如下所示:
docker run -d --name alertmanager -p 9093:9093 \
-v /root/prometheus/alertmanager/:/etc/alertmanager/ \
prom/alertmanager:latest
觸發報警
之前我們定義的 rule 規則為監測 job="linux" Node 是否活着,那么就可以停掉node-exporter服務來間接起到 Node Down 的作用,從而達到報警條件,觸發報警規則。
使用命令 docker stop 容器id
,停止服務后,等待 60s 之后可以看到 Prometheus target 里面 linux 狀態為 unhealthy 狀態,等待 60s 后,alert 頁面由綠色 node-up (0 active) Inactive 狀態變成了黃色 node-up (1 active) Pending 狀態,繼續等待 60s 后狀態變成紅色 Firing 狀態,向 AlertManager 發送報警信息,此時 AlertManager 則按照配置規則向接受者發送郵件告警。
停掉服務后,我們來看狀態的變化,首先是Inactive狀態,AlertManager也沒有報警信息,如下所示:
等待60s后,再次查看服務狀態,變成了Pending狀態,如下所示:
繼續等待 60s,變成了Firing狀態,如下所示:
並且AlertManager 有報警信息,如下所示:
查看自己的郵件,收到了郵件推送,如下所示:
服務一直處於停止狀態,會一直推送消息,5分鍾一次,如下所示:
說到這里,對有些時間節點有點不理解,這里有幾個地方需要解釋一下:
• 每次停止/恢復服務后,60s 之后才會發現 Alert 狀態變化,是因為 prometheus.yml中 global -> scrape_interval: 60s 配置決定的,如果覺得等待 60s 時間太長,可以修改小一些,可以全局修改,也可以局部修改。例如局部修改 linux 等待時間為 5s。
• Alert 狀態變化時會等待 15s 才發生改變,是因為host.rules中配置了for: 15s狀態變化等待時間。
• 報警觸發后,每隔 5m 會自動發送報警郵件(服務未恢復正常期間),是因為alertmanager.yml中route -> repeat_interval: 5m配置決定的。
郵件自定義
在剛才的郵件內容中,基本信息有,但不直觀,那可不可以自定義模板內容呢?答案是有的,我們繼續來看。
自定義模板
自定義一個郵件模板,在/root/prometheus/alertmanager/目錄下,vim email.tmpl配置如下:
{{ define "email.from" }}1111111111@qq.com{{ end }}
{{ define "email.to" }}222222222222@foxmail.com{{ end }}
{{ define "email.html" }}
{{ range .Alerts }}
=========start==========<br>
告警程序: prometheus_alert <br>
告警級別: {{ .Labels.severity }} 級 <br>
告警類型: {{ .Labels.alertname }} <br>
故障主機: {{ .Labels.instance }} <br>
告警主題: {{ .Annotations.summary }} <br>
告警詳情: {{ .Annotations.description }} <br>
觸發時間: {{ .StartsAt.Format "2006-01-02 08:08:08" }} <br>
=========end==========<br>
{{ end }}
{{ end }}
簡單說明一下,上邊模板文件配置了 email.from、email.to、email.to.html 三種模板變量,可以在 alertmanager.yml 文件中直接配置引用。這里 email.to.html 就是要發送的郵件內容,支持 Html 和 Text 格式,這里為了顯示好看,采用 Html 格式簡單顯示信息。下邊 {{ range .Alerts }} 是個循環語法,用於循環獲取匹配的 Alerts 的信息,下邊的告警信息跟上邊默認郵件顯示信息一樣,只是提取了部分核心值來展示。
修改alertmanager.yml
由於已經定義了變量,所以我們在alertmanager配置文件中可以引用變量,並且引用我們自定義的模板,引用模板需要增加 templates ,配置如下:
global:
resolve_timeout: 5m
smtp_from: '{{ template "email.from" . }}'
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: '{{ template "email.from" . }}'
smtp_auth_password: 'XXXXXXXXXXXXXXXXX'
smtp_hello: 'qq.com'
smtp_require_tls: false
templates:
- '/etc/alertmanager/*.tmpl'
route:
group_by: ['alertname']
group_wait: 5s
group_interval: 5s
repeat_interval: 5m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: '{{ template "email.to" . }}'
html: '{{ template "email.html" . }}'
send_resolved: true
#insecure_skip_verify: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
重啟AlertManager
修改 AlertManager 啟動命令,將本地email.tmpl文件掛載到容器內指定位置並重啟。由於我的配置是跟alertmanager的配置文件在同一個目錄下,所以不用重新掛載,重啟容器即可。
我們將node服務停止,再次查收郵件,查看下效果,如下所示:
模板優化
時間格式
我們從上圖可以看出,郵件內容格式已經改變,但時間卻顯示的有點離譜,原因是時間格式問題,修改郵件模板,針對時間配置格式,如下所示:
{{ define "email.from" }}11111111111@qq.com{{ end }}
{{ define "email.to" }}2222222222222@foxmail.com{{ end }}
{{ define "email.html" }}
{{ range .Alerts }}
=========start==========<br>
告警程序: prometheus_alert <br>
告警級別: {{ .Labels.severity }} 級 <br>
告警類型: {{ .Labels.alertname }} <br>
故障主機: {{ .Labels.instance }} <br>
告警主題: {{ .Annotations.summary }} <br>
告警詳情: {{ .Annotations.description }} <br>
觸發時間: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }} <br>
=========end==========<br>
{{ end }}
{{ end }}
保存后再次重啟alertmanager服務,重新操作一遍之前的動作,查看最終的郵件效果,如下所示:
配置時間格式后,我們看效果圖,時間是修正了的。
郵件標題
還可以自定義郵件標題,修改alertmanager.yml配置文件,增加參數:headers即可,如下所示:
receivers:
- name: 'email'
email_configs:
- to: '{{ template "email.to" . }}'
html: '{{ template "email.html" . }}'
send_resolved: true
headers: { Subject: "{{ .CommonAnnotations.summary }}" }
配置好重啟alertmanager服務,再次觸發告警郵件,收到的內容如下:
以上就是今天的分享內容,報警系統功能就已完成,后續介紹微信、釘釘推送,下期再見。