本章主要對如何使用Prometheus與Alertmanager元件整合配置,以及對警報規則 Rules 的倆種型別及其模板內容進行講解。
與Alertmanager整合
Prometheus把產生的警報發給Alertmanager進行處理時,需要在Prometheus使用的配置檔案中新增關聯Alertmanager的元件的對應配置資訊。
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]
# alertmanagers 為 alertmanager_config 陣列,
配置範例:
alerting:
alert_relabel_configs: # 動態修改 alert 屬性的規則配置。
- source_labels: [dc]
regex: (.+)\d+
target_label: dc1
alertmanagers:
- static_configs:
- targets: ['127.0.0.1:9093'] # 單例項配置
#- targets: ['172.31.10.167:19093','172.31.10.167:29093','172.31.10.167:39093'] # 叢集配置
- job_name: 'Alertmanager'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:19093']
上面的配置中的 alert_relabel_configs
是指警報重新標記在傳送到Alertmanager之前應用於警報。 它具有與目標重新標記相同的配置格式和操作,外部標籤標記後應用警報重新標記,主要是針對叢集配置。
這個設定的用途是確保具有不同外部label的HA對Prometheus服務端傳送相同的警報資訊。
Alertmanager 可以通過 static_configs
引數靜態配置,也可以使用其中一種支援的服務發現機制動態發現,我們上面的配置是靜態的單例項,針對叢集HA配置,後面會講。
此外,relabel_configs
允許從發現的實體中選擇 Alertmanager,並對使用的API路徑提供高階修改,該路徑通過 __alerts_path__
標籤公開。
完成以上配置後,重啟Prometheus服務,用以載入生效,也可以使用前文說過的熱載入功能,使其配置生效。然後通過瀏覽器,訪問 http://192.168.1.220:19090/alerts 就可以看 inactive
pending
firing
三個狀態,沒有警報資訊是因為我們還沒有配置警報規則 rules
。
警報規則
警報規則 rules
使用的是 yaml 格式進行定義,在Prometheus中通過我們前面講過的 PromQL
配置實際警報觸發條件,Prometheus 會根據設定的警告規則 Ruels
以及配置間隔時間進行週期性計算,當滿足觸發條件規則會傳送警報通知。
警報規則載入的是在 prometheus.yml
檔案中進行配置,預設的警報規則進行週期執行計算的時間是1分鐘,可以使用 global
中的 evaluation_interval
來決定時間間隔。
範例:
global:
evaluation_interval: 15s
警報規則可以指定多個檔案,也可以自定到自定義的目錄下面,為了管理更為便捷,方便閱讀,可以把警報規則拆成多分,用以區分環境,系統,服務等,如:prod,test,dev 等等,並且支援以正規表示式定義。
範例:
rule_files:
#- "/data/prometheus/rules/*.yml" # 正規表示式,會加在此目錄下所有警報規則配置檔案
- "/data/prometheus/rules/ops.yml" # 僅載入ops.yml警報規則檔案
#- "/data/prometheus/rules/prod-*.yml"
#- "/data/prometheus/rules/test-*.yml"
#- "/data/prometheus/rules/dev-*.yml"
現在開始講告警規則 Rules
的定義,格式為YAML。
groups:
- name: <string>
rules:
- alert: <string>
expr: <string>
for: [ <duration> | default 0 ]
labels:
[ <lable_name>: <label_value> ]
annotations:
[ <lable_name>: <tmpl_string> ]
引數 | 描述 |
---|---|
- name: <string> |
警報規則組的名稱 |
- alert: <string> |
警報規則的名稱 |
expr: <string |
使用PromQL表示式完成的警報觸發條件,用於計算是否有滿足觸發條件 |
<lable_name>: <label_value> |
自定義標籤,允許自行定義標籤附加在警報上,比如high warning |
annotations: <lable_name>: <tmpl_string> |
用來設定有關警報的一組描述資訊,其中包括自定義的標籤,以及expr計算後的值。 |
groups:
- name: operations
rules:
- alert: node-down
expr: up{env="operations"} != 1
for: 5m
labels:
status: High
team: operations
annotations:
description: "Environment: {{ $labels.env }} Instance: {{ $labels.instance }} is Down ! ! !"
value: '{{ $value }}'
summary: "The host node was down 20 minutes ago"
以上就是一個完整 Rules
的配置,如果Prometheus 在週期檢測中使用PromQ以env=operations
為維度查詢,如果當前查詢結果中具有標籤operations
,且返回值都不等於1的時候,傳送警報。
對於寫好的 Rules
可以是常用 promtool
來check ruls.yml 的書寫格式是否正確。
/usr/local/bin/promtool check rules /data/prometheus/rules/ops.yml
Checking /data/prometheus/rules/ops.yml
SUCCESS: 7 rules found
對於修改好的rules檔案,儲存以後,經過檢測沒有問題,直接重新熱載入 Prometheus就可以在頁面看到了。對於觸發警報規則,比較簡單了,直接修改運算值或者去停掉 node-exporter 服務,便可在介面看到警報資訊。一個告警在生命週期會有三種狀態
狀態 | 描述 |
---|---|
Inactive |
正常狀態,未啟用警報 |
Pending |
已滿足觸發條件,但沒有滿足傳送時間條件,此條件就是上面rules範例中的 for 5m 子句中定義的持續時間 |
Firing |
滿足條件,且超過了 for 子句中的的指定持續時間5m |
帶有for子句的警報觸發以後首先會先轉換成 Pending
狀態,然後在轉換為 Firing
狀態。這裡需要倆個週期才能觸發警報條件,如果沒有設定 for
子句,會直接 Inactive
狀態轉換成 Firing狀態
,然後觸發警報,傳送給 Receiver
設定的通知人。
在執行過程中,Prometheus會把Pending或Firing狀態的每一個告警建立一個 Alerts
指標名稱,這個可以通過Rules來觸發警報測試,直接在UI中Graph檢視指標 ALERTS
,格式如下:
ALERTS{alertname="alert name",alertstate="pending|firing",<additional alert label>}
當警報處於啟用狀態 Pending
或者 Firing
時候,如上圖所示,樣本值為1。其他狀態為0。則不顯示。上圖已經觸發警報,其警報已經被轉發給Alertmanager元件,此時可以在瀏覽器上通過可以用過9093埠訪問,檢視警報狀態。
現在我們來說一下整理下Prometheus從收集監控指標資訊到觸發警報的過程
狀態 | 描述 |
---|---|
1.定義規則 |
在Prometheus配置中,scrape_interval: 15s,預設是1分鐘,這個定義是收集監控指標資訊的採集週期,同時配置對應的警報規則,可以是全域性,也可以單獨為某一個metrics定義 |
2.週期計算 |
對於表示式進行計算時,Prometheus中的配置中配置了 evaluation_interval: 15s,預設也是一分鐘,為警報規則的計算週期,evaluation_interval 只是全域性計算週期值。 |
3.1警報狀態轉換(pending) |
當首次觸發警報規則條件成立,表示式為 true ,並且沒有滿足警報規則中的for子句中的持續時間時,警報狀態切換為 Pending |
3.2警報狀態轉換(firing) |
若下一個計算週期中,表示式仍為 true ,並且滿足警報規則中的for子句的持續時間時,警報狀態轉換為 Firing ,即為 active ,警報會被Prometheus推送到ALertmanager元件 |
3.3警報狀態轉換(period) |
如果在 evaluation_interval 的計算週期內,表示式還是為 true ,同時滿足 for子句的持續時間,持續轉發到Alertmanager,這裡只是轉發狀態到Alertmanager,並不是直接傳送通知到指定通知源 |
3.4警報狀態轉換(resolve) |
只到某個週期,表示式 為 false ,警報狀態會變成 inactive ,並且會有一個 resolve 被髮送到Alertmanager,用於說明警報故障依解決,傳送resolve資訊需要自己單獨在Alertmanager中定義 |
Rules型別
Prometheus 支援兩種型別的 Rules
,可以對其進行配置,然後定期進行運算:recording rules
記錄規則 與 alerting rules
警報規則,規則檔案的計算頻率與告警規則計算頻率一致,都是通過全域性配置中的 evaluation_interval
定義。
alerting rules
要在Prometheus中使用Rules規則,就必須建立一個包含必要規則語句的檔案,並讓Prometheus通過Prometheus配置中的rule_files欄位載入該檔案,前面我們已經講過了。
其實語法都一樣,除了 recording rules
中的收集的指標名稱 record: <string>
欄位配置方式略有不同,其他都是一樣的。
配置範例:
- alert: ServiceDown
expr: avg_over_time(up[5m]) * 100 < 50
annotations:
description: The service {{ $labels.job }} instance {{ $labels.instance }} is
not responding for more than 50% of the time for 5 minutes.
summary: The service {{ $labels.job }} is not responding
- alert: RedisDown
expr: avg_over_time(redis_up[5m]) * 100 < 50
annotations:
description: The Redis service {{ $labels.job }} instance {{ $labels.instance
}} is not responding for more than 50% of the time for 5 minutes.
summary: The Redis service {{ $labels.job }} is not responding
- alert: PostgresDown
expr: avg_over_time(pg_up[5m]) * 100 < 50
annotations:
description: The Postgres service {{ $labels.job }} instance {{ $labels.instance
}} is not responding for more than 50% of the time for 5 minutes.
summary: The Postgres service {{ $labels.job }} is not responding
recording rules
recording rules
是提前設定好一個比較花費大量時間運算或經常運算的表示式,其結果儲存成一組新的時間序列資料。當需要查詢的時候直接會返回已經計算好的結果,這樣會比直接查詢快,同時也減輕了PromQl的計算壓力,同時對視覺化查詢的時候也很有用,視覺化展示每次只需要重新整理重複查詢相同的表示式即可。
在配置的時候,除卻 record: <string>
需要注意,其他的基本上是一樣的,一個 groups
下可以包含多條規則 rules
,Recording
和 Rules
儲存在 group
內,Group
中的規則以規則的配置時間間隔順序運算,也就是全域性中的 evaluation_interval
設定。
配置範例:
groups:
- name: http_requests_total
rules:
- record: job:http_requests_total:rate10m
expr: sum by (job)(rate(http_requests_total[10m]))
lables:
team: operations
- record: job:http_requests_total:rate30m
expr: sum by (job)(rate(http_requests_total[30m]))
lables:
team: operations
上面的規則其實就是根據 record
規則中的定義,Prometheus 會在後臺完成 expr
中定義的 PromQL 表示式週期性運算,以 job
為維度使用 sum
聚合運算子 計算 函式rate
對http_requests_total
指標區間 10m
內的增長率,並且將計算結果儲存到新的時間序列 job:http_requests_total:rate10m
中,
同時還可以通過 labels
為樣本資料新增額外的自定義標籤,但是要注意的是這個 Lables
一定存在當前表示式 Metrics
中。
使用模板
模板是在警報中使用時間序列標籤和值展示的一種方法,可以用於警報規則中的註釋(annotation)與標籤(lable)。模板其實使用的go語言的標準模板語法,並公開一些包含時間序列標籤和值的變數。這樣查詢的時候,更具有可讀性,也可以執行其他PromQL查詢
來向警報新增額外內容,ALertmanager Web UI中會根據標籤值顯示器警報資訊。
{{ $lable.<lablename>}}
可以獲取當前警報例項中的指定標籤值
{{ $value }}
變數可以獲取當前PromQL表示式的計算樣本值。
groups:
- name: operations
rules:
# monitor node memory usage
- alert: node-memory-usage
expr: (1 - (node_memory_MemAvailable_bytes{env="operations",job!='atlassian'} / (node_memory_MemTotal_bytes{env="operations"})))* 100 > 90
for: 1m
labels:
status: Warning
team: operations
annotations:
description: "Environment: {{ $labels.env }} Instance: {{ $labels.instance }} memory usage above {{ $value }} ! ! !"
summary: "node os memory usage status"
調整好rules以後,我們可以使用 curl -XPOST http://localhost:9090/-/reload
或者 對Prometheus服務重啟,讓警報規則生效。
這個時候,我們可以把閾值調整為 50
來進行故障模擬操作,這時在去訪問UI的時候,當持續1分鐘滿足警報條件,實際告警狀態已轉換為 Firing
,可以在 Annotations中看到模板資訊 summary
與 description
已經成功顯示。
需要注意的是,一個穩定健壯的Prometheus監控系統中,要儘量使用模板化,這樣會降低效能開銷(Debug除錯資訊等),同時也易於維護。
下面網站收錄了當前大部分的rules規則,大家可以對應自己的環境,配置相關服務的Rules。
[Prometheus告警規則收集(https://awesome-prometheus-alerts.grep.to/)