Prometheus-Alertmanager原理和配置詳解

1。 摘要

警報一直是整個監控系統中的重要組成部分,Prometheus監控系統中,採集與警報是分離的。警報規則在 Prometheus 定義,警報規則觸發以後,才會將資訊轉發到給獨立的元件 Alertmanager ,經過 Alertmanager r對警報的資訊處理後,最終透過接收器傳送給指定使用者,另外在 Alertmanager 中沒有通知組的概念,只能自己對軟體重新Coding,或者使用第三方外掛來實現。 注意,這個通知組不是Alertmanager中的group概念,下面會詳細講 Group ,不要混淆哦。

前面已經介紹過一些關於 Alertmanager 知識點,本章開始針透過安裝 Alertmanager 元件,對配置檔案做詳細說明,同時介紹 Prometheus 的警報規則的定義,最後使用Email、Wechat(Robot)、Dingtalk(webhook)來接受警報通知。

2。 內容

2。1 Alertmanager工作機制

Prometheus-Alertmanager原理和配置詳解

在Prometheus生態架構裡,警報是由獨立的倆部分組成,可以透過上圖很清晰的瞭解到

Prometheus

的警報工作機制。其中

Prometheus

Alertmanager

是分離的倆個元件。我們使用Prometheus Server端透過靜態或者動態配置 去拉取 pull 部署在k8s或雲主機上的各種類別的監控指標資料,然後基於我們前面講到的 PromQL 對這些已經儲存在本地儲存 HDD/SSD 的 TSDB 中的指標定義閾值警報規則 Rules 。Prometheus會根據配置的引數週期性的對警報規則進行計算, 如果滿足警報條件,生產一條警報資訊,將其推送到

Alertmanager

元件,

Alertmanager

收到警報資訊之後,會對警告資訊進行處理,進行

分組

Group 並將它們透過定義好的路由 Routing 規則轉到 正確的接收器 receiver, 比如 Email Slack 釘釘、企業微信 Robot(webhook) 企業微信 等,最終異常事件 Warning、Error通知給定義好的接收人,其中如釘釘是基於第三方通知來實現的,對於通知人定義是在釘釘的第三方元件中配置。

Prometheus

中, 我們不僅僅可以對單條警報進行命名透過 PromQL定義規則,更多時候是對相關的多條警報進行分組後統一定義。這些定義會在後面說明與其管理方法。下面開始把

Alertmanager

中的分組 Grouping 、抑制 Inhibition、延遲 Silences 核心特性進行介紹,便於大家系統性的學習與理解。

分組

Grouping 是 Alertmanager 把同類型的警報進行分組,合併多條警報到一個通知中。在生產環境中,特別是雲環境下的業務之間密集耦合時,若出現多臺 Instance 故障,可能會導致成千上百條警報觸發。在這種情況下使用分組機制, 可以把這些被觸發的警報合併為一個警報進行通知,從而避免瞬間突發性的接受大量警報通知,使得管理員無法對問題進行快速定位。

舉個栗子,在Kubernetes叢集中,執行著重量級規模的例項,即便是叢集中持續很小一段時間的網路延遲或者延遲導致網路抖動,也會引發大量類似服務應用無法連線 DB 的故障。如果在警報規則中定義每一個應用例項都發送警報,那麼到最後的結果就是 會有大量的警報資訊傳送給 Alertmanager 。

作為運維組或者相關業務組的開發人員,可能更關心的是在一個通知中就可以快速檢視到哪些服務例項被本次故障影響了。為此,我們對服務所在叢集或者服務警報名稱的維度進行分組配置,把警報彙總成一條通知時,就不會受到警報資訊的頻繁傳送影響了。

抑制

Inhibition 是 當某條警報已經發送,停止重複傳送由此警報引發的其他異常或故障的警報機制。在生產環境中,IDC託管機櫃中,若每一個機櫃接入層僅僅是單臺交換機,那麼該機櫃接入交換機故障會造成機櫃中伺服器非 up 狀態警報。再有伺服器上部署的應用服務不可訪問也會觸發警報。 這時候,可以透過在 Alertmanager 配置忽略由於交換機故障而造成的此機櫃中的所有伺服器及其應用不可達而產生的警報。

在我們的災備體系中,當原有叢集故障宕機業務徹底無法訪問的時候,會把使用者流量切換到備份叢集中,這樣為故障叢集及其提供的各個微服務狀態傳送警報機會失去了意義,此時, Alertmanager 的抑制特性就可以在一定程度上避免管理員收到過多無用的警報通知。

靜默

Silences 提供了一個簡單的機制,根據標籤快速對警報進行靜默處理;對傳進來的警報進行匹配檢查,如果接受到警報符合靜默的配置,Alertmanager 則不會發送警報通知。

以上除了分組、抑制是在 Alertmanager 配置檔案中配置,靜默是需要在 WEB UI 介面中設定臨時遮蔽指定的警報通知。

以上的概念需要好好理解,這樣才可以輕鬆的在監控系統設計的時候針對警報設計的一些場景自行調整。

2。2 安裝Alertmanager

我們可以使用 ansible 中自動化對 Alertmanager 進行安裝、配置、啟動、更新,這裡僅僅只是用 Alertmanager 的二進位制安裝,以 systemd 管理啟動。

## 建立相關目錄mkdir -p /data/alertmanager/{bin,conf,logs,data,templates}## 下載二進位制包,並wget https://github。com/prometheus/alertmanager/releases/download/v0。21。0/alertmanager-0。21。0。linux-amd64。tar。gztar xvf alertmanager-0。21。0。linux-amd64。tar。gzmv alertmanager-0。21。0。linux-amd64/{alertmanager,amtool} /data/alertmanager/bin/mv alertmanager-0。21。0。linux-amd64/alertmanager。yml /data/alertmanager/conf/# 目錄結構/data/alertmanager/├── bin│ ├── alertmanager│ └── amtool├── conf│ └── alertmanager。yml├── data├── logs└── templates## 加入systemd啟動指令碼cat </lib/systemd/system/alertmanager。service[Unit]Description=alertmanagerDocumentation=https://prometheus。io/After=network。targetStartLimitIntervalSec=0[Service]Type=simpleUser=prometheusExecStart=/data/alertmanager/bin/alertmanager ——storage。path=“/data/alertmanager/data/” \——config。file=/usr/local/alertmanager/alertmanager。yml \——web。external-url=http://192。168。1。220 # 此處可以寫域名,需要做proxy。Restart=alwaysRestartSec=1# Restart=on-failure[Install]WantedBy=multi-user。targetEOF## 啟動systemctl enable alertmanagersystemctl start alertmanager

輝哥採用下載/alertmanager-0。16。2。linux-amd64版本,直接執行。/alertmanager啟動的。

Alertmanager 引數

引數

描述

——config。file=“alertmanager。yml”

指定Alertmanager配置檔案路徑

——storage。path=“data/”

Alertmanager的資料存放目錄

——data。retention=120h

歷史資料保留時間,預設為120h

——alerts。gc-interval=30m

警報gc之間的間隔

——web。external-url=WEB。EXTERNAL-URL

外部可訪問的Alertmanager的URL(例如Alertmanager是透過nginx反向代理)

——web。route-prefix=WEB。ROUTE-PREFIX

wen訪問內部路由路徑,預設是 ——web。external-url

——web。listen-address=“:9093”

監聽埠,可以隨意修改

——web。get-concurrency=0

併發處理的最大GET請求數,預設為0

——web。timeout=0

web請求超時時間

——cluster。listen-address=“0。0。0。0:9094”

叢集的監聽埠地址。設定為空字串禁用HA模式

——cluster。advertise-address=CLUSTER。ADVERTISE-ADDRESS

配置叢集通知地址

——cluster。gossip-interval=200ms

傳送條訊息之間的間隔,可以以增加頻寬為代價更快地跨叢集傳播。

——cluster。peer-timeout=15s

在同級之間等待發送通知的時間

。。。

。。。

——log。level=info

自定義訊息格式 [debug, info, warn, error]

——log。format=logfmt

日誌訊息的輸出格式: [logfmt, json]

——version

顯示版本號

Alertmanager配置詳解

Alertmanager一個完整的配置檔案範例:

## Alertmanager 配置檔案global: resolve_timeout: 5m # smtp配置 smtp_from: “123456789@qq。com” smtp_smarthost: ‘smtp。qq。com:465’ smtp_auth_username: “123456789@qq。com” smtp_auth_password: “auth_pass” smtp_require_tls: true# email、企業微信的模板配置存放位置,釘釘的模板會單獨講如果配置。templates: - ‘/data/alertmanager/templates/*。tmpl’# 路由分組route: receiver: ops group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。 group_interval: 5m # 如果組內內容不變化,合併為一條警報資訊,5m後傳送。 repeat_interval: 24h # 傳送報警間隔,如果指定時間內沒有修復,則重新發送報警。 group_by: [alertname] # 報警分組 routes: - match: team: operations group_by: [env,dc] receiver: ‘ops’ - match_re: service: nginx|apache receiver: ‘web’ - match_re: service: hbase|spark receiver: ‘hadoop’ - match_re: service: mysql|mongodb receiver: ‘db’# 接收器# 抑制測試配置 - receiver: ops group_wait: 10s match: status: ‘High’# ops - receiver: ops # 路由和標籤,根據match來指定傳送目標,如果 rule的lable 包含 alertname, 使用 ops 來發送 group_wait: 10s match: team: operations# web - receiver: db # 路由和標籤,根據match來指定傳送目標,如果 rule的lable 包含 alertname, 使用 db 來發送 group_wait: 10s match: team: db# 接收器指定傳送人以及傳送渠道receivers:# ops分組的定義- name: ops email_configs: - to: ‘9935226@qq。com,10000@qq。com’ send_resolved: true headers: subject: “[operations] 報警郵件” from: “警報中心” to: “小煜狼皇” # 釘釘配置 webhook_configs: - url: http://localhost:8070/dingtalk/ops/send # 企業微信配置 wechat_configs: - corp_id: ‘ww5421dksajhdasjkhj’ api_url: ‘https://qyapi。weixin。qq。com/cgi-bin/’ send_resolved: true to_party: ‘2’ agent_id: ‘1000002’ api_secret: ‘Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj’# web- name: web email_configs: - to: ‘9935226@qq。com’ send_resolved: true headers: { Subject: “[web] 報警郵件”} # 接收郵件的標題 webhook_configs: - url: http://localhost:8070/dingtalk/web/send - url: http://localhost:8070/dingtalk/ops/send# db- name: db email_configs: - to: ‘9935226@qq。com’ send_resolved: true headers: { Subject: “[db] 報警郵件”} # 接收郵件的標題 webhook_configs: - url: http://localhost:8070/dingtalk/db/send - url: http://localhost:8070/dingtalk/ops/send# hadoop- name: hadoop email_configs: - to: ‘9935226@qq。com’ send_resolved: true headers: { Subject: “[hadoop] 報警郵件”} # 接收郵件的標題 webhook_configs: - url: http://localhost:8070/dingtalk/hadoop/send - url: http://localhost:8070/dingtalk/ops/send# 抑制器配置inhibit_rules: # 抑制規則 - source_match: # 源標籤警報觸發時抑制含有目標標籤的警報,在當前警報匹配 status: ‘High’ status: ‘High’ # 此處的抑制匹配一定在最上面的route中配置不然,會提示找不key。 target_match: status: ‘Warning’ # 目標標籤值正則匹配,可以是正則表示式如: “。*MySQL。*” equal: [‘alertname’,‘operations’, ‘instance’] # 確保這個配置下的標籤內容相同才會抑制,也就是說警報中必須有這三個標籤值才會被抑制。

global

即為全域性設定,在 Alertmanager 配置檔案中,只要全域性設定配置了的選項,全部為公共設定,可以讓其他設定繼承,作為預設值,可以子引數中覆蓋其設定。其中 resolve_timeout 用於設定處理超時時間,也是生命警報狀態為解決的時間, 這個時間會直接影響到警報恢復的通知時間,需要自行結合實際生產場景來設定主機的恢復時間,預設是5分鐘。在全域性設定中可以設定smtp服務,同時也支援slack、victorops、pagerduty等,在這裡只講我們常用的Email,釘釘,企業微信, 同時也可以自己使用go語言開發的gubot進行二次開發,對接自定義webhook通知源。

template

警報模板可以自定義通知的資訊格式,以及其包含的對應警報指標資料,可以自定義Email、企業微信的模板,配置指定的存放位置,對於釘釘的模板會單獨講如何配置,這裡的模板是指的傳送的通知源資訊格式模板,比如Email,企業微信。

route

警報路由模組描述了在收到 Prometheus 生成的警報後,將警報資訊傳送給接收器 receiver 指定的目標地址規則。 Alertmanager 對傳入的警報資訊進行處理,根據所定義的規則與配置進行匹配。對於路由可以理解為樹狀結構, 設定的第一個route是跟節點,往下的就是包含的子節點,每個警報傳進來以後,會從配置的跟節點路由進入路由樹,按照深度優先從左向右遍歷匹配,當匹配的節點後停止,進行警報處理。

引數描述

引數

描述

receiver:

傳送警報的接收器名稱

group_by: [‘label_name1,。。。’]

根據 prometheus 的 lables 進行報警分組,這些警報會合併為一個通知傳送給接收器,也就是警報分組。

match: [ ,。。。]

透過此設定來判斷當前警報中是否有標籤的labelname,等同於labelvalue。

match_re: [,。。。]

透過正則表示式進行警報配置

group_wait: [

default=30s

設定從接受警報到傳送的等待時間,若在等待時間中group接收到新的警報資訊,這些警報會合併為一條傳送。

group_interval: [

default=5m

此設定控制的是 group 之間傳送警報通知的間隔時間。

repeat_interval: [

default=4h

此設定控制的是警報傳送成功以後,沒有對警報做解決操作的話,狀態 Firing 沒有變成 Inactive 或者 Pending ,會再次傳送警報的的間隔時間。

routes: - 。。。

子路由的匹配設定

路由匹配規則樣例:

route: receiver: admin # 預設的接收器名稱 group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。 group_interval: 5m # 如果組內內容不變化,5m後傳送。 repeat_interval: 24h # 傳送報警間隔,如果指定時間內沒有修復,則重新發送報警 group_by: [alertname,cluster] # 報警分組,根據 prometheus 的 lables 進行報警分組,這些警報會合併為一個通知傳送給接收器,也就是警報分組。 routes: - match: team: ops group_by: [env,dc] receiver: ‘ops’ - match_re: service: nginx|apache receiver: ‘web’ - match_re: service: mysql|mongodb receiver: ‘db’ - match_re: service: hbase|spark receiver: ‘hadoop’

在以上的例子中,預設的警報組全部發送給 admin ,且根據路由按照 alertname cluster 進行警報分組。在子路由中的若匹配警報中的標籤 team 的值為 ops,Alertmanager 會按照標籤 env dc 進行警報分組然後傳送給接收器 receiver ops配置的警報通知源。 繼續匹配的操作是對 service 標籤進行匹配,並且配到了 nginx redis mongodb 的值,就會向接收器 receiver web配置的警報通知源傳送警報資訊。

receiver

接受器是一個統稱,每個 receiver 都有需要設定一個全域性唯一的名稱,並且對應一個或者多個通知方式,包括email、微信、Slack、釘釘等。

官方現在滿足的配置是:

name: email_config: [ - ]hipchat_configs: #此模組配置已經被移除了 [ ]pagerduty_configs: [ ]pushover_configs: [ ]slack_configs: [ ]opsgenie_configs: [ ]webhook_configs: [ ]victorops_configs: [ ]webchat_configs: [

可以看到Alertmanager提供了很多種接收器的通知配置,我們可以使用webhook接收器來定義通知整合,支援使用者自己定義編寫。

官方receiver配置

inhibit_rules

inhibit_rules 模組中設定警報抑制功能,可以指定在特定條件下需要忽略的警報條件。可以使用此選項設定首選,比如優先處理某些警報,如果同一組中的警報同時發生,則忽略其他警報。 合理使用 inhibit_rules ,可以減少頻發發送沒有意義的警報的產生。

inhibit_rules 配置資訊:

trget_match: [ ,。。。 ]trget_match_re: [ ,。。。 ]source_match: [ ,。。。 ]source_match_re: [ ,。。。 ][ equal: ‘[’ , 。。。]‘]

範例:

inhibit_rules: # 抑制規則 - source_match: # 源標籤警報觸發時抑制含有目標標籤的警報,在當前警報匹配 status: ’High‘ status: ’High‘ # 此處的抑制匹配一定在最上面的route中配置不然,會提示找不key。 target_match: status: ’Warning‘ # 目標標籤值正則匹配,可以是正則表示式如: “。*MySQL。*” equal: [’alertname‘,’operations‘, ’instance‘] # 確保這個配置下的標籤內容相同才會抑制,也就是說警報中必須有這三個標籤值才會被抑制。

以上示例是指 如果匹配 equal 中的抑制的標籤值,觸發了包含 equal 中的標籤值的 status: ’High‘ 警報 ,則不傳送含包含 equal 中的標籤值的 status: ’Warning‘ 標籤的警報。 這裡儘量避免 source_match 與 target_match 之間的重疊,否則很難做到理解與維護,同時建議謹慎使用此功能。使用基於症狀的警報時,警報之間很少需要相互依賴。

2。3 警報通知接收器

前面一直是在Web UI 檢視警報資訊,現在開始使用接收器與Alertmanager整合,傳送警報資訊到 Email、企業微信、釘釘機器人,對於警報要求比較高的同學,可以根據下面提到的開源元件 【PrometheusAlert全家桶】 配置飛書、簡訊、語音電話等警報。

Email

前面已經講過,Alertmanager預設支援配置Email,也是最普通的方式,在Alertmanager元件中內建了SMTP協議。直接可以把前面的Alertmanager。yml中的SMTP部分截取出來,然後進行調整與配置

global: resolve_timeout: 5m # smtp配置 smtp_from: “1234567890@qq。com” # 傳送郵件主題 smtp_smarthost: ’smtp。qq。com:465‘ # 郵箱伺服器的SMTP主機配置 smtp_auth_username: “1234567890@qq。com” # 登入使用者名稱 smtp_auth_password: “auth_pass” # 此處的auth password是郵箱的第三方登入授權密碼,而非使用者密碼,儘量用QQ來測試。 smtp_require_tls: false # 有些郵箱需要開啟此配置,這裡使用的是163郵箱,僅做測試,不需要開啟此功能。route: receiver: ops group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。 group_interval: 5m # 如果組內內容不變化,合併為一條警報資訊,5m後傳送。 repeat_interval: 24h # 傳送報警間隔,如果指定時間內沒有修復,則重新發送報警。 group_by: [alertname] # 報警分組 routes: - match: team: operations group_by: [env,dc] receiver: ’ops‘ - receiver: ops # 路由和標籤,根據match來指定傳送目標,如果 rule的lable 包含 alertname, 使用 ops 來發送 group_wait: 10s match: team: operations# 接收器指定傳送人以及傳送渠道receivers:# ops分組的定義- name: ops email_configs: - to: ’9935226@qq。com,xxxxx@qq。com‘ # 如果想傳送多個人就以 ’,‘做分割,寫多個郵件人即可。 send_resolved: true headers: from: “警報中心” subject: “[operations] 報警郵件” to: “小煜狼皇”

配置完成後,直接重啟Alertmanager元件,使配置生效,然後使用前面記憶體閾值觸發一次警報來看下發送結果。

收到的警報資訊:

Prometheus-Alertmanager原理和配置詳解

當警報接觸以後收到的恢復資訊。

Prometheus-Alertmanager原理和配置詳解

企業微信

參考 https://zhuanlan。zhihu。com/p/179294441

釘釘機器人(Webhook)

參考 https://zhuanlan。zhihu。com/p/179294441

開源警報元件推薦

Prometheus-Webhook-Dingtalk

一個開源的第三方警報外掛,針對釘釘機器人 webhook 做整合,Go語言編寫,現在迭代的已經很不錯了,可能有一些功能還是有些限制,比如針對 Markdown @某個人無法實現,原因是因釘釘自身API沒有支援這個功能。

Alertmanager-wechatrobot-webhook

這個開源元件是將Alertmanger Webhook 訊息轉換為可以接收訊息的企業微信機器人,也是go語言編寫,Alertmanager 預設已經整合企業微信配置,如果有特殊需求,需要使用企業微信機器人的可以看看這個。

PrometheusAlert全家桶

如果有對簡訊、電話警報等其他需求的同學,推薦這個開源警報元件,Go語言編寫,Web框架是 Beego ,支援將收到的這些訊息傳送到釘釘,微信,飛書,騰訊簡訊,騰訊電話,阿里雲簡訊,阿里雲電話,華為簡訊,容聯雲電話等。

3。參考

(1)Prometheus監控神器-Alertmanager篇(1)

https://zhuanlan。zhihu。com/p/179292686

(2)Prometheus監控神器-Alertmanager篇(2)

https://zhuanlan。zhihu。com/p/179294441

源地址:https://www。jianshu。com/p/c661e8050434