Prometheus 監控報警系統 AlertManager 之郵件告警


轉載自:https://cloud.tencent.com/developer/article/1486483

文章目錄1、Prometheus & AlertManager 介紹2、環境、軟件准備3、啟動並配置 Prometheus3.1、Docker 啟動 Prometheus3.2、Docker 啟動 node-exporter3.3、Prometheus 配置 node-exproter4、啟動並配置 AlertManager4.1、AlertManager 配置郵件告警4.2、Prometheus 配置 AlertManager 告警規則4.3、觸發報警發送 Email4.4、AlertManager 配置自定義郵件模板

1、Prometheus & AlertManager 介紹

Prometheus 是一套開源的系統監控、報警、時間序列數據庫的組合,最初有 SoundCloud 開發的,后來隨着越來越多公司使用,於是便獨立成開源項目。Alertmanager 主要用於接收 Prometheus 發送的告警信息,它支持豐富的告警通知渠道,例如郵件、微信、釘釘、Slack 等常用溝通工具,而且很容易做到告警信息進行去重,降噪,分組等,是一款很好用的告警通知系統。

2、環境、軟件准備

本次演示環境,我是在本機 MAC OS 上操作,以下是安裝的軟件及版本:

  • Docker: 18.06.3-ce
  • Oracle VirtualBox: 6.0.8 r130520 (Qt5.6.3)
  • Linux: 7.6.1810
  • Prometheus: v2.11.1
  • Alertmanager: v0.18.0
  • Node-Exporter: v0.18.1

注意:這里為了快速方便啟動 Prometheus、Alertmanager、Node-Exporter 服務,我使用 Docker 方式啟動,所以本機需要安裝好 Docker 環境,這里忽略 Docker 的安裝過程,着重介紹一下如何啟動並配置 Prometheus 監控報警系統 集成 AlertManager,並配置 Email 發送告警信息。

3、啟動並配置 Prometheus

3.1、Docker 啟動 Prometheus

啟動 Prometheus 很簡單,這里為了方便,我采用 Docker 方式啟動,最簡單的啟動命令如下:

$ docker run --name prometheus -d -p 9090:9090 prom/prometheus:latest

這里默認 Prometheus 開放 9090 端口,我們使用最新版官方鏡像,當前最新版本為 v2.11.1,啟動完成后,瀏覽器訪問 http://<IP>:9090 即可看到默認 UI 頁面。

img

Prometheus 默認配置文件 prometheus.yml 在容器內路徑為 /etc/prometheus/prometheus.yml,我們可以進入到容器內查看一下。

$ docker exec -it prometheus /bin/sh
/prometheus $ cat /etc/prometheus/prometheus.yml
# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ['localhost:9090']

從默認配置可以看到 Alertmanager 配置、rule 報警規則、監聽目標端點配置等,每一項的配置我就不一一解釋了,下邊具體使用中,會分別講到。現在 Prometheus 已經啟動起來了,我們需要啟動一個 exporter 來供 Prometheus 監控獲取指標值,這里以一個常用的 node-exproter 為例,它是最基本的節點監控客戶端,負責監控機器的各個指標,包括節點存活、CPU、Mem、Network、IO 等等,方便后邊演示 Alertmanager 報警時的觸發條件,例如配置節點存活檢測,當機器 Down 時,觸發報警控制,那么就可以通過停止 node-exporter 來模擬實現了。

3.2、Docker 啟動 node-exporter

同樣采用 Docker 方式啟動 node-exporter 服務,最簡單的啟動命令如下:

$ docker run --name node-exporter -d -p 9100:9100 prom/node-exporter:latest

這里 node-exporter 默認啟動端口為 9100,當前鏡像最新版本為 v0.18.0。啟動完成后,瀏覽器訪問 http://<IP>:9100/metrics 可以看到提供的監控指標項列表了。

img

3.3、Prometheus 配置 node-exproter

接下來,我們需要將 node-exporter 信息配置到 Prometheus 中,來讓 Prometheus 定期獲取 exporter 采集的信息,那么就需要修改 prometheus.yml 配置文件,在 scrape_configs 下新增一個 job,配置如下:

$ mkdir -p /root/prometheus && cd /root/prometheus
$ vim prometheus.yml
global:
  scrape_interval:     15s 
  evaluation_interval: 15s  
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['192.168.1.124:9090']
      labels:
        instance: prometheus
        service: prometheus-service
 
  - job_name: 'node-exporter'
    static_configs:
    - targets: ['192.168.1.124:9100'] 
      labels: 
        instance: vm-192.168.1.124
        service: node-service

注意:這里新增一個名稱為 node-exporter 的 job 配置,target 就是上邊 node-exporter 請求地址,默認 http 方式,請求地址后綴默認為 /metric,如果不是該地址,那么就需要配置 metrics_path: <path>。同時我為每個 job 新增了 label 標簽配置,這個是很有必要的,通過配置不同的 label 來附加一些必要的信息,在后邊 Alertmanager 告警郵件中和 Grafana Dashboard 展示中,都是很重要的區分表示。配置完畢,需要將新的配置文件覆蓋容器內配置文件,並重啟 Prometheus 來使配置生效。

$ docker run -d
	--name prometheus 
	-p 9090:9090 
	-v /root/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml 
	prom/prometheus:latest

這里通過掛載的方式將外部配置文件覆蓋容器內配置,重啟 prometheus 服務,瀏覽器訪問 http://192.168.1.124:9090/targets 可以看到新增加的 target,並且是 healthy 狀態。

img

不過,有沒有發現默認使用 static_configs 靜態配置方式,雖然可以正確配置,但是每次配置都需要重啟 Prometheus 服務,當我們需要分批次添加很多 Node 時,頻繁重啟服務就會造成監控的多次中斷,這太不友好了。當然 Prometheus 也提供了多種服務發現方式。

更多詳細配置可查看 這里,這里我們可以采用 file_sd_configs 方式,將 targets 以 Json 或 Yaml 方式寫入特定文件中,那么只要文件發生變化,Prometheus 就會自動加載,是不是很方便啦!

$ midir -p /root/prometheus/groups/nodegroups && cd /root/prometheus/groups/nodegroups
$ vim node.json
[
    {
        "targets": [
            "192.168.1.124:9100"
        ],
        "labels": {
            "instance": "vm-192.168.1.124",
            "service": "node-service"
        }
    }
]

新建一個 node.json 文件,將 prometheus.ymljob_name: 'node-exporter' 下的信息以 Json 方式配置到該文件中,然后修改 prometheus.yml 加載方式為 file_sd_configs,配置修改如下:

...
	- job_name: 'node-exporter'
     file_sd_configs:
       - files: ['/usr/local/prometheus/groups/nodegroups/*.json']

注意:這里我們指定加載容器內目錄配置文件,那么需要將本地 node.json 文件掛載到容器內指定目錄上,修改 Prometheus 啟動命令如下:

$ docker run -d
	--name prometheus
	-p 9090:9090 
	-v /root/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml 
	-v /root/prometheus/groups/:/usr/local/prometheus/groups/ prom/	prometheus:latest        

啟動成功,以后在添加或修改 Node 相關的 exproter,就可以直接在該 Json 文件中更新即可,不需要重啟 Prometheus 服務,更多關於 Prometheus 配置可以參考 官網文檔

4、啟動並配置 AlertManager

接下來,我們需要啟動 AlertManager 來接受 Prometheus 發送過來的報警信息,並執行各種方式的告警。同樣以 Docker 方式啟動 AlertManager,最簡單的啟動命令如下:

$ docker run --name alertmanager -d -p 9093:9093 prom/alertmanager:latest

這里 AlertManager 默認啟動的端口為 9093,啟動完成后,瀏覽器訪問 http://<IP>:9093 可以看到默認提供的 UI 頁面,不過現在是沒有任何告警信息的,因為我們還沒有配置報警規則來觸發報警。

img

4.1、AlertManager 配置郵件告警

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: 抑制規則配置,當存在與另一組匹配的警報(源)時,抑制規則將禁用與一組匹配的警報(目標)。

那么,我們就來配置一下使用 Email 方式通知報警信息,這里以 QQ 郵箱為例,配置如下:

global:
  resolve_timeout: 5m
  smtp_from: 'xxxxxxxx@qq.com'
  smtp_smarthost: 'smtp.qq.com:465'
  smtp_auth_username: 'xxxxxxxx@qq.com'
  smtp_auth_password: 'xxxxxxxxxxxxxxx'
  smtp_require_tls: false
  smtp_hello: 'qq.com'
route:
  group_by: ['alertname']
  group_wait: 5s
  group_interval: 5s
  repeat_interval: 5m
  receiver: 'email'
receivers:
- name: 'email'
  email_configs:
  - to: 'xxxxxxxx@qq.com'
    send_resolved: true # 注意這個參數:控制告警恢復后發不發郵件的
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

以上配置我反復試驗后,發現不同的環境參數配置也不一樣,調試期間出現了各種報錯問題,將其中幾個關鍵的配置說明一下:

  • smtp_smarthost: 這里為 QQ 郵箱 SMTP 服務地址,官方地址為 smtp.qq.com 端口為 465587,同時要設置開啟 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.yml 文件掛載到容器內指定位置。

$ docker run -d
	--name alertmanager
	-p 9093:9093 
	-v /root/prometheus/alertmanager.yml:/etc/alertmanager/alertmanager.yml
	prom/alertmanager:latest

4.2、Prometheus 配置 AlertManager 告警規則

接下來,我們需要在 Prometheus 配置 AlertManager 服務地址以及告警規則,新建報警規則文件 node-up.rules 如下:

$ mkdir -p /root/prometheus/rules && cd /root/prometheus/rules/
$ vim node-up.rules
groups:
- name: node-up
  rules:
  - alert: node-up
    expr: up{job="node-exporter"} == 0
    for: 15s
    labels:
      severity: 1
      team: node
    annotations:
      summary: "{{ $labels.instance }} 已停止運行超過 15s!"

說明一下:該 rules 目的是監測 node 是否存活,expr 為 PromQL 表達式驗證特定節點 job="node-exporter" 是否活着,for 表示報警狀態為 Pending 后等待 15s 變成 Firing 狀態,一旦變成 Firing 狀態則將報警發送到 AlertManager,labelsannotations 對該 alert 添加更多的標識說明信息,所有添加的標簽注解信息,以及 prometheus.yml 中該 job 已添加 label 都會自動添加到郵件內容中,更多關於 rule 詳細配置可以參考 這里

然后,修改 prometheus.yml 配置文件,添加 rules 規則文件。

...
# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - 172.30.12.39:9093

rule_files:
  - "/usr/local/prometheus/rules/*.rules"
...

注意: 這里 rule_files 為容器內路徑,需要將本地 node-up.rules 文件掛載到容器內指定路徑,修改 Prometheus 啟動命令如下,並重啟服務。

$ docker run --name prometheus -d -p 9090:9090 
	-v /root/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml 
	-v /root/prometheus/groups/:/usr/local/prometheus/groups/ 
	-v /root/prometheus/rules/:/usr/local/prometheus/rules/ 
	prom/prometheus:latest

img

這里說明一下 Prometheus Alert 告警狀態有三種狀態:InactivePendingFiring

  • Inactive:非活動狀態,表示正在監控,但是還未有任何警報觸發。
  • Pending:表示這個警報必須被觸發。由於警報可以被分組、壓抑/抑制或靜默/靜音,所以等待驗證,一旦所有的驗證都通過,則將轉到 Firing 狀態。
  • Firing:將警報發送到 AlertManager,它將按照配置將警報的發送給所有接收者。一旦警報解除,則將狀態轉到 Inactive,如此循環。

4.3、觸發報警發送 Email

上邊我們定義的 rule 規則為監測 job="node-exporter" Node 是否活着,那么就可以停掉 node-exporter 服務來間接起到 Node Down 的作用,從而達到報警條件,觸發報警規則。

$ docker stop node-exporter

停止服務后,等待 15s 之后可以看到 Prometheus target 里面 node-exproter 狀態為 unhealthy 狀態,等待 15s 后,alert 頁面由綠色 node-up (0 active) Inactive 狀態變成了黃色 node-up (1 active) Pending 狀態,繼續等待 15s 后狀態變成紅色 Firing 狀態,向 AlertManager 發送報警信息,此時 AlertManager 則按照配置規則向接受者發送郵件告警。

img

img

img

img

img

最終發送的默認報警郵件信息如下:

img

從上圖可以看到,默認郵件模板 Title 及 Body 會將之前配置的 Labels 及 Annotations 信息均包含在內,而且每隔 5m 會自動發送,直到服務恢復正常,報警解除為止,同時會發送一封報警解除郵件。接下來,我們啟動 node-exporter 來恢復服務。

$ docker start node-exporter

等待 15s 之后,Prometheus Alerts 頁面變成綠色 node-up (0 active) Inactive 狀態,同時也收到了報警解除郵件提醒。

img

這里有幾個地方需要解釋一下:

  1. 每次停止/恢復服務后,15s 之后才會發現 Alert 狀態變化,是因為 prometheus.ymlglobal -> scrape_interval: 15s 配置決定的,如果覺得等待 15s 時間太長,可以修改小一些,可以全局修改,也可以局部修改。例如局部修改 node-exporter 等待時間為 5s。 ... - job_name: 'node-exporter' scrape_interval: 5s file_sd_configs: - files: ['/usr/local/prometheus/groups/nodegroups/*.json']
  2. Alert 狀態變化時會等待 15s 才發生改變,是因為 node-up.rules 中配置了 for: 15s 狀態變化等待時間。
  3. 報警觸發后,每隔 5m 會自動發送報警郵件(服務未恢復正常期間),是因為 alertmanager.ymlroute -> repeat_interval: 5m 配置決定的。

4.4、AlertManager 配置自定義郵件模板

看到上邊默認發送的郵件模板,雖然所有核心的信息已經包含了,但是郵件格式內容可以更優雅直觀一些,那么,AlertManager 也是支持自定義郵件模板配置的,首先新建一個模板文件 email.tmpl

$ mkdir -p /root/prometheus/alertmanager-tmpl && cd /root/prometheus/alertmanager-tmpl
$ vim email.tmpl
{{ define "email.from" }}xxxxxxxx@qq.com{{ end }}
{{ define "email.to" }}xxxxxxxx@qq.com{{ end }}
{{ define "email.to.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 "2019-08-04 16:58:15" }} <br>
=========end==========<br>
{{ end }}
{{ end }}

簡單說明一下,上邊模板文件配置了 email.fromemail.toemail.to.html 三種模板變量,可以在 alertmanager.yml 文件中直接配置引用。這里 email.to.html 就是要發送的郵件內容,支持 Html 和 Text 格式,這里為了顯示好看,采用 Html 格式簡單顯示信息。下邊 {{ range .Alerts }} 是個循環語法,用於循環獲取匹配的 Alerts 的信息,下邊的告警信息跟上邊默認郵件顯示信息一樣,只是提取了部分核心值來展示。然后,需要增加 alertmanager.yml 文件 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: 'xxxxxxxxxxxxxxx'
  smtp_require_tls: false
  smtp_hello: 'qq.com'
templates:
  - '/etc/alertmanager-tmpl/email.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.to.html" . }}'
    send_resolved: true
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

然后,修改 AlertManager 啟動命令,將本地 email.tmpl 文件掛載到容器內指定位置並重啟。

$ docker run -d
    --name alertmanager
    -p 9093:9093 
    -v /root/prometheus/alertmanager.yml:/etc/alertmanager/alertmanager.yml
    -v /root/prometheus/alertmanager-tmpl/:/etc/alertmanager-tmpl/
    prom/alertmanager:latest

上邊模板中由於配置了 {{ .Annotations.description }} 變量,而之前 node-up.rules 中並沒有配置該變量,會導致獲取不到值,所以這里我們修改一下 node-up.rules 並重啟 Promethues 服務。

$ vim /root/prometheus/rules/node-up.rules
groups:
- name: node-up
  rules:
  - alert: node-up
    expr: up{job="node-exporter"} == 0
    for: 15s
    labels:
      severity: 1
      team: node
    annotations:
      summary: "{{ $labels.instance }} 已停止運行!"
      description: "{{ $labels.instance }} 檢測到異常停止!請重點關注!!!"

重啟完畢后,同樣模擬觸發報警條件(停止 node-exporter 服務),也是可以正常發送模板郵件出來的,這次就是我們想要的風格啦!

img

當然我們還可以配置郵件標題,這里就不在演示了,詳細配置可參考 這里。這里除了監控節點是否存活外,還可以監控很多很多指標,例如 CPU 負載告警、Mem 使用量告警、Disk 存儲空間告警、Network 負載告警等等,這些都可以通過自定義 PromQL 表達式驗證值來定義一些列的告警規則,來豐富日常工作中需要的各種告警。 這里,我們只演示了如何通過 AlertManager 來配置發送郵件告警,其他的告警方式,可以參考 官網文檔 來配置,這里就不再演示了。下一篇,我們繼續通過 Prometheus 來監控 SpringBoot 工程應用程序 JVM 情況,以及自定義 metrics 來實現特定功能的監控。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM