一、部署Alertmanager服務
1.1 alertmanager服務介紹
在Prometheus平台中,警報由獨立的組件Alertmanager處理。通常情況下,我們首先告訴Prometheus Alertmanager所在的位置,然后在Prometheus配置中創建警報規則,最后配置Alertmanager來處理警報並發送給接收者(郵件,webhook、slack等)。
軟件下載地址:
https://prometheus.io/download/ https://github.com/prometheus/alertmanager/releases
1.2 alertmanager服務部署
Anertmanager可以不用和Prometheus部署在同一台機器,只要服務之間可以通信即可。
# wget https://github.com/prometheus/alertmanager/releases/download/v0.20.0/alertmanager-0.20.0.linux-amd64.tar.gz # tar xf alertmanager-0.20.0.linux-amd64.tar.gz -C /usr/local/ # ln -s /usr/local/alertmanager-0.20.0.linux-amd64/ /usr/local/alertmanager # 修改alertmanager配置文件 # cat alertmanager.yml global: resolve_timeout: 5m smtp_smarthost: 'smtp.163.com:25' smtp_from: 'gaojing@163.com' smtp_auth_username: 'gaojing@163.com' smtp_auth_password: 'password' smtp_require_tls: false route: group_by: ['alertname'] # 分組標簽 group_wait: 10s # 分組等待時間,同一組內在10秒鍾內還有其它告警,如果有則一同發送 group_interval: 10s # 上下兩組間隔時間 repeat_interval: 1h # 重復告警間隔時間 receiver: 'mail' # 接收者是誰 receivers: # 定義接收者,將告警發送給誰 - name: 'web.hook' webhook_configs: - url: 'http://127.0.0.1:5001/' - name: 'mail' email_configs: - to: '532141928@qq.com' # 檢查配置文件 # ./amtool check-config alertmanager.yml # 使用systemd來管理alertmanager服務 # cat /usr/lib/systemd/system/alertmanager.service [Unit] Description=https://prometheus.io [Service] Restart=on-failure ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml [Install] WantedBy=multi-user.target # 啟動alertmanager服務 # systemctl daemon-reload # systemctl start alertmanager # systemctl enable alertmanager
二、配置Prometheus與alertmanager集成
2.1 配置prometheus與alertmanager告警
配置告警規則可參考:https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
# vim /usr/local/prometheus/prometheus.yml 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. alerting: alertmanagers: - static_configs: - targets: - 127.0.0.1:9093 # alertmanager的通信地址 rule_files: - "rules/*.yml" # alertmanager使用的配置文件存放地址 # mkdir /usr/local/prometheus/rules # cat /usr/local/prometheus/rules/general.yml groups: - name: example rules: - alert: InstanceDown expr: up == 0 # 表達式當前實例服務狀態,1為正常 for: 3m # 告警持續時間5分鍾 labels: severity: page # 告警級別 annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} 已經停止工作3分鍾." # /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml Checking /usr/local/prometheus/prometheus.yml SUCCESS: 1 rule files found Checking /usr/local/prometheus/rules/general.yml SUCCESS: 1 rules found # systemctl restart prometheus.service
重啟服務之后就能看到新的規則:
停止一個服務進行驗證
2.2 告警狀態
Inactive:這里什么都沒有發生。
Pending:已觸發閾值,但未滿足告警持續時間(即rule中的for字段)
Firing:已觸發閾值且滿足告警持續時間。警報發送到Notification Pipeline,經過處理,發送給接受者。
這樣的目的是多次判斷失敗才發告警,減少郵件。
查看郵箱已經收到郵件:
2.3 告警分配到指定接收到組,處理流程如下
1.接收到Alert,根據labels判斷屬於哪些Route(可存在多個Route,一個Route有多個Group,一個Group有多個Alert)。
2.將Alert分配到Group中,沒有則新建Group。
3.新的Group等待group_wait指定的時間(等待時可能收到同一Group的Alert),根據resolve_timeout判斷Alert是否解決,然后發送通知。
4.已有的Group等待group_interval指定的時間,判斷Alert是否解決,當上次發送通知到現在的間隔大於repeat_interval或者Group有更新時會發送通知。
route: receiver: 'default-receiver' # 所有不匹配以下子路由的告警都將保留在根節點,並發送到“default-receiver” group_wait: 30s # 為一個組發送通知的初始等待時間,默認30s group_interval: 5m # 在發送新告警前的等待時間。通常5m或以上 repeat_interval: 1h # 發送重復告警的周期。如果已經發送了通知,再次發送之前需要等待多長時間。 group_by: [cluster, alertname] # 報警分組依據 routes: - receiver: 'database-pager' # 所有service=mysql或者service=cassandra的告警分配到數據庫接收端 group_wait: 10s match_re: service: mysql|cassandra - receiver: 'frontend-pager' # 所有帶有team=frontend標簽的告警都與此子路由匹配,它們是按產品和環境分組的,而不是集群 group_by: [product, environment] match: team: frontend receivers: # 定義接收者,將告警發送給誰 - name: 'database-pager' webhook_configs: - url: 'http://127.0.0.1:5001/' - name: 'frontend-pager' email_configs: - to: '532141928@qq.com'
三、告警的收斂(分組、抑制、靜默)
告警面臨最大問題,是警報太多,相當於狼來了的形式。收件人很容易麻木,不再繼續理會。關鍵的告警常常被淹沒。在一問題中,alertmanger在一定程度上得到很好解決。
Prometheus成功的把一條告警發給了Altermanager,而Altermanager並不是簡簡單單的直接發送出去,這樣就會導致告警信息過多,重要告警被淹沒。所以需要對告警做合理的收斂。
告警收斂手段:
分組(group):將類似性質的警報分類為單個通知 (相同組中的告警合並到一封郵件中進行發送 - alert: InstanceDown)
抑制(Inhibition):當警報發出后,停止重復發送由此警報引發的其他警報
靜默(Silences):是一種簡單的特定時間靜音提醒的機制
抑制
# vim /usr/local/alertmanager/alertmanager.yml inhibit_rules: # 抑制 告警收斂 發送關鍵告警 - source_match: severity: 'critical' # 如果是此級別的告警,就會忽略下面warning級別告警郵件的發送 target_match: severity: 'warning' equal: ['app', 'instance'] # 根據標簽來判斷主機
靜默
特定的時間內不再發送告警,訪問IP:9093端口在WEB頁面進行配置,一般用來在維護階段組止預期的告警通知。
觸發告警的流程:
1.Prometheus Server監控目標主機上暴露的http接口(這里假設接口A),通過上述Promethes配置的'scrape_interval'定義的時間間隔,定期采集目標主機上監控數據。
2.當接口A不可用的時候,Server端會持續的嘗試從接口中取數據,直到"scrape_timeout"時間后停止嘗試。這時候把接口的狀態變為"DOWN"。
3.Prometheus同時根據配置的"evaluation_interval"的時間間隔,定期(默認1min)的對Alert Rule進行評估;當到達評估周期的時候,發現接口A為DOWN,即UP=0為真,激活Alert,進入“PENDING”狀態,並記錄當前active的時間;
4.當下一個alert rule的評估周期到來的時候,發現UP=0繼續為真,然后判斷警報Active的時間是否已經超出rule里的"for" 持續時間,如果未超出,則進入下一個評估周期;如果時間超出,則alert的狀態變為"FIRING";同時調用Alertmanager接口,發送相關報警數據。
5.AlertManager收到報警數據后,會將警報信息進行分組,然后根據alertmanager配置的"group_wait"時間先進行等待。等wait時間過后再發送報警信息。
6.屬於同一個Alert Group的警報,在等待的過程中可能進入新的alert,如果之前的報警已經成功發出,那么間隔"group_interval"的時間間隔后再重新發送報警信息。比如配置的是郵件報警,那么同屬一個group的報警信息會匯總在一個郵件里進行發送。
7.如果Alert Group里的警報一直沒發生變化並且已經成功發送,等待"repeat_interval"時間間隔之后再重復發送相同的報警郵件;如果之前的警報沒有成功發送,則相當於觸發第6條條件,則需要等待group_interval時間間隔后重復發送。
8.同時最后至於警報信息具體發給誰,滿足什么樣的條件下指定警報接收人,設置不同報警發送頻率,這里有alertmanager的route路由規則進行配置。
四、自定義告警
自定義磁盤、CPU、內存大於80%的告警
# vim /usr/local/prometheus/rules/node.yml groups: - name: node.rules rules: - alert: NodeFilesystemUsage expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"} * 100) > 80 for: 2m labels: severity: warning annotations: summary: "{{$labels.instance}}: {{$labels.mountpoint }} 分區使用過高" description: "{{$labels.instance}}: {{$labels.mountpoint }} 分區使用大於 80% (當前值: {{ $value }})" - alert: NodeMemoryUsage expr: 100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100 > 80 for: 2m labels: severity: warning annotations: summary: "{{$labels.instance}}: 內存使用過高" description: "{{$labels.instance}}: 內存使用大於 80% (當前值: {{ $value }})" - alert: NodeCPUUsage expr: 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 80 for: 2m labels: severity: warning annotations: summary: "{{$labels.instance}}: CPU使用過高" description: "{{$labels.instance}}: CPU使用大於 80% (當前值: {{ $value }})" # /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml Checking /usr/local/prometheus/prometheus.yml SUCCESS: 2 rule files found Checking /usr/local/prometheus/rules/general.yml SUCCESS: 1 rules found Checking /usr/local/prometheus/rules/node.yml SUCCESS: 3 rules found # systemctl restart prometheus.service