Prometheus監控神器(Rules篇)



本章主要對如何使用Prometheus與Alertmanager組件集成配置,以及對警報規則 Rules 的倆種類型及其模板內容進行講解。node

與Alertmanager集成

Prometheus把產生的警報發給Alertmanager進行處理時,須要在Prometheus使用的配置文件中添加關聯Alertmanager的組件的對應配置信息。web

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以前應用於警報。它具備與目標從新標記相同的配置格式和操做,外部標籤標記後應用警報從新標記,主要是針對集羣配置。redis

這個設置的用途是確保具備不一樣外部label的HA對Prometheus服務端發送相同的警報信息。數組

Alertmanager 能夠經過 static_configs 參數靜態配置,也可使用其中一種支持的服務發現機制動態發現,咱們上面的配置是靜態的單實例,針對集羣HA配置,後面會講。瀏覽器

此外,relabel_configs 容許從發現的實體中選擇 Alertmanager,並對使用的API路徑提供高級修改,該路徑經過 __alerts_path__ 標籤公開。微信

完成以上配置後,重啓Prometheus服務,用以加載生效,也可使用前文說過的熱加載功能,使其配置生效。而後經過瀏覽器,訪問 http://192.168.1.220:19090/alerts 就能夠看 inactive pending firing 三個狀態,沒有警報信息是由於咱們尚未配置警報規則 rulesapp

警報規則

警報規則 rules 使用的是 yaml 格式進行定義,在Prometheus中經過咱們前面講過的 PromQL 配置實際警報觸發條件,Prometheus 會根據設置的警告規則 Ruels 以及配置間隔時間進行週期性計算,當知足觸發條件規則會發送警報通知。警報規則加載的是在 prometheus.yml 文件中進行配置,默認的警報規則進行週期運行計算的時間是1分鐘,可使用 global 中的 evaluation_interval 來決定時間間隔。curl

範例:編輯器

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>}

ALETS

當警報處於激活狀態 Pending 或者 Firing時候,如上圖所示,樣本值爲1。其餘狀態爲0。則不顯示。上圖已經觸發警報,其警報已經被轉發給Alertmanager組件,此時能夠在瀏覽器上經過能夠用過9093端口訪問,查看警報狀態。

Alert-Action

如今咱們來講一下整理下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 下能夠包含多條規則 rulesRecordingRules 保存在 groups 內,Groups 中的規則以規則的配置時間間隔順序運算,也就是全局中的 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 聚合運算符 計算 函數ratehttp_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中看到模板信息 summarydescription 已經成功顯示。

alert-summary

須要注意的是,一個穩定健壯的Prometheus監控系統中,要儘可能使用模板化,這樣會下降性能開銷(Debug調試信息等),同時也易於維護。

下面網站收錄了當前大部分的rules規則,你們能夠對應本身的環境,配置相關服務的Rules。

[Prometheus警報規則收集(https://awesome-prometheus-alerts.grep.to/)

專輯:

監控神器-Prometheus

推薦個大佬講的Ceph課程,如今正在優惠中~

歡迎關注個人公衆號!



本文分享自微信公衆號 - Kubernetes技術棧(k8stech)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索