在前一篇博文中介紹,伺服器監控已經部署成功。如果每天都需要人去盯著服務情況,那也不太現實。既然監控平臺已經部署好了,是不是可以自動觸發報警呢?
在上一篇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服務,再次觸發告警郵件,收到的內容如下:
以上就是今天的分享內容,報警系統功能就已完成,後續介紹微信、釘釘推送,下期再見。