docker部署Prometheus+AlertManager實現郵件告警

misakivv發表於2024-04-13

目錄
  • 一、環境準備
    • 1、硬體準備(虛擬機器)
    • 2、關閉防火牆,selinux
    • 3、所有主機安裝docker
  • 二、配置Prometheus
    • 1、docker啟動Prometheus
  • 三、新增監控節點
    • 1、docker啟動node-exporter
  • 四、Prometheus配置node-exporter
    • 1、修改prometheus.yml配置檔案
  • 五、配置Alertmanager
    • 1、docker啟動Alertmanager
  • 六、Alertmanager配置郵件告警
  • 七、配置Alertmanager告警規則
    • 1、建立報警規則檔案node-up.rules
    • 2、然後修改 prometheus.yml 配置檔案,新增 rules 規則檔案。
  • 八、觸發報警傳送Email
    • 1、停止服務測試
  • 九、Alertmanager配置自定義郵件模板
    • 1、建立一個模板檔案

一、環境準備

1、硬體準備(虛擬機器)

主機名 IP地址
server 192.168.112.40
node-exporter 192.168.112.50

2、關閉防火牆,selinux

firewalld:

 systemctl stop firewalld	#關閉
 systemctl disable firewalld		#開機不自啟
 systemctl status firewalld		#檢視狀態

selinux:

 sed -i 's/enforcing/disabled/' /etc/selinux/config 
 setenforce 0

3、所有主機安裝docker

yum install wget.x86_64 -y
rm -rf /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y

二、配置Prometheus

1、docker啟動Prometheus

docker run本地沒有映象直接從Docker Hub上拉取映象,-p引數將主機的9090埠對映到容器內的9090埠,沒指定Prometheus版本就會自動拉取最新版本

server主機

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

image-20240413161909637

Prometheus的預設埠是9090。瀏覽器訪問192.168.112.40:9090即可看到Prometheus預設的UI介面

image-20240413162436754

Prometheus預設配置檔案 prometheus.yml 在容器內路徑為 /etc/prometheus/prometheus.yml

[root@server ~]# 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"]
#配置檔案解釋:
scrape_interval:每次資料採集的時間間隔,預設為1分鐘
scrape_timeout:採集請求超時時間,預設為10秒
evaluation_interval:執行rules的頻率,預設為1分鐘
scrape_configs:主要用於配置被採集資料節點操作,每一個採集配置主要由以下幾個引數
job_name:全域性唯一名稱
scrape_interval:預設等於global內設定的引數,設定後可以覆蓋global中的值
scrape_timeout:預設等於global內設定的引數
metrics_path:從targets獲取meitric的HTTP資源路徑,預設是/metrics
honor_labels:Prometheus如何處理標籤之間的衝突。若設定為True,則透過保留變遷來解
決衝突;若設定為false,則透過重新命名;
scheme:用於請求的協議方式,預設是http
params:資料採集訪問時HTTP URL設定的引數
relabel_configs:採集資料重置標籤配置
metric_relabel_configs:重置標籤配置
sample_limit:對每個被已知樣本數量的每次採集進行限制,如果超過限制,該資料將被視為失敗。預設值為0,表示無限制

三、新增監控節點

在被監控主機:192.168.112.50(node-exporter)上操作

1、docker啟動node-exporter

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

image-20240413164047226

node-exporter預設埠是9100,瀏覽器訪問192.168.112.50:9100/metrics可以看到Prometheus可提供的監控項列表

image-20240413164716363

四、Prometheus配置node-exporter

1、修改prometheus.yml配置檔案

將 node-exporter 資訊配置到 Prometheus 中,來讓 Prometheus 定期獲取 exporter 採集的資訊

在監控主機:192.168.112.40(server)上操作

[root@server ~]# mkdir -p /root/prometheus
[root@server ~]# cd /root/prometheus/
[root@server 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.112.40:9090']
      labels:
        instance: centos7

  - job_name: node-exporter
    static_configs:
    - targets: ['192.168.112.50:9100']
      labels:
        instance: centos7

配置完畢,需要將新的配置檔案覆蓋容器內配置檔案,並重啟 Prometheus 來使配置生效。

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

這裡透過掛載的方式將外部配置檔案覆蓋容器內配置,重啟 prometheus 服務,瀏覽器訪問 192.168.112.40:9090 可以看到新增加的 target,並且是 healthy狀態。

image-20240413171915933

預設使用的是static_configs靜態配置方式,這樣就導致了每次配置都需要重啟Prometheus服務。Prometheus提供了多種服務發現方式

  1. azure_sd_configs

  2. consul_sd_configs

  3. dns_sd_configs

  4. ec2_sd_configs

  5. openstack_sd_configs

  6. file_sd_configs

  7. kubernetes_sd_configs

  8. marathon_sd_configs

  9. nerve_sd_configs

  10. serverset_sd_configs

  11. triton_sd_configs

這裡採用file_sd_configs 方式,將 targets 以 Json 或 Yaml 方式寫入特定檔案中,那麼只要檔案發生變化,Prometheus 就會自動載入。

[
    {
        "targets": [
            "192.168.112.50:9100"
        ],
        "labels": {
            "instance": "centos7",
        }
    }
]

新建一個 node.json 檔案,將 prometheus.ymljob_name: 'node-exporter' 下的資訊以 Json 方式配置到該檔案中,然後修改 prometheus.yml 載入方式為 file_sd_configs,配置修改如下:

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

image-20240413173248620

這裡我們指定載入容器內目錄配置檔案,那麼需要將本地 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

啟動成功,以後在新增或修改 Node 相關的 exproter,就可以直接在該 Json 檔案中更新即可,不需要重啟 Prometheus 服務。

五、配置Alertmanager

1、docker啟動Alertmanager

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

AlertManager 的預設啟動埠為 9093,啟動完成後,瀏覽器訪問 192.168.112.40:9093 可以看到預設提供的 UI 頁面,不過現在是沒有任何告警資訊的,因為我們還沒有配置報警規則來觸發報警。

image-20240413174340359

六、Alertmanager配置郵件告警

AlertManager 預設配置檔案為 alertmanager.yml,在容器內路徑為 /etc/alertmanager/alertmanager.yml,預設配置如下:

route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  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']
  1. route: 用來設定報警的分發策略,它是一個樹狀結構,按照深度優先從左向右的順序進行匹配。

  2. receivers: 配置告警訊息接受者資訊,例如常用的 email、wechat、slack、webhook 等訊息通知方式。

  3. inhibit_rules: 抑制規則配置,當存在與另一組匹配的警報(源)時,抑制規則將禁用與一組匹配的警報(目標)。

以QQ郵箱為例:

global:
  resolve_timeout: 5m
  smtp_from: '2830909671@qq.com'
  smtp_smarthost: 'smtp.qq.com:465'
  smtp_auth_username: '2830909671@qq.com'
  smtp_auth_password: 'asdjkbmlggxiddfc'
  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: 'misakikk@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 埠為 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.yml 檔案掛載到容器內指定位置。

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

七、配置Alertmanager告警規則

1、建立報警規則檔案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;

labels 和 annotations 對該 alert 新增更多的標識說明資訊,所有新增的標籤註解資訊,以及 prometheus.yml 中該 job 已新增 label 都會自動新增到郵件內容中。

2、然後修改 prometheus.yml 配置檔案,新增 rules 規則檔案。

...
# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - 192.168.112.40: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

瀏覽器輸入192.168.112.40:9090/rules

image-20240413182230068

Prometheus Alert 告警狀態有三種狀態:Inactive、Pending、Firing。

Inactive:非活動狀態,表示正在監控,但是還未有任何警報觸發。

Pending:表示這個警報必須被觸發。由於警報可以被分組、壓抑/抑制或靜默/靜音,所以等待驗證,一旦所有的驗證都透過,則將轉到 Firing 狀態。

Firing:將警報傳送到 AlertManager,它將按照配置將警報的傳送給所有接收者。一旦警報解除,則將狀態轉到 Inactive,如此迴圈。

八、觸發報警傳送Email

1、停止服務測試

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

在被監控主機:192.168.112.50(node-exporter)上操作

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 則按照配置規則向接受者傳送郵件告警。

image-20240413200009033

image-20240413223232145

image-20240413200436162

預設的郵件資訊:

image-20240413200222525

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

docker start node-exporter

image-20240413200906993


image-20240413200926531

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

image-20240413201016124

九、Alertmanager配置自定義郵件模板

1、建立一個模板檔案

郵件格式內容可以更優雅直觀一些,那麼,AlertManager 也是支援自定義郵件模板配置的,首先新建一個模板檔案 email.tmpl

{{ define "email.from" }}2830909671@qq.com{{ end }}
{{ define "email.to" }}misakikk@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 "2024-04-13 22:30:00" }} <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: 'asdjkbmlggxiddfc'
  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 服務),也是可以正常傳送模板郵件出來的。

相關文章