Alertmanager部署和簡單使用
部署
解壓
[root@server01 src]# wget https://github.com/prometheus/alertmanager/releases/download/v0.15.0/alertmanager-0.15.0.linux-amd64.tar.gz [root@server01 src]# tar -xvf alertmanager-0.15.0.linux-amd64.tar.gz -C /opt/ [root@server01 src]# cd /opt/ [root@server01 opt]# ln -s alertmanager-0.15.0.linux-amd64 alertmanager
配置
[root@server01 alertmanager]# cat alertmanager.yml
global:
# 在沒有報警的情況下聲明為已解決的時間
resolve_timeout: 5m
# 配置郵件發送信息
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '15737684975@163.com'
smtp_auth_username: '15737684975@163.com'
smtp_auth_password: 'wsl116002'
smtp_require_tls: false # 禁用tls
# 所有報警信息進入后的根路由,用來設置報警的分發策略
route:
# 這里的標簽列表是接收到報警信息后的重新分組標簽,例如,接收到的報警信息里面有許多具有 cluster=A 和 alertname=LatncyHigh 這樣的標簽的報警信息將會批量被聚合到一個分組里面
group_by: ['alertname', 'cluster']
# 當一個新的報警分組被創建后,需要等待至少group_wait時間來初始化通知,這種方式可以確保您能有足夠的時間為同一分組來獲取多個警報,然后一起觸發這個報警信息。
group_wait: 30s
# 當第一個報警發送后,等待'group_interval'時間來發送新的一組報警信息。
group_interval: 5m
# 如果一個報警信息已經發送成功了,等待'repeat_interval'時間來重新發送他們
repeat_interval: 5m
# 默認的receiver:如果一個報警沒有被一個route匹配,則發送給默認的接收器
receiver: default
receivers:
- name: 'default' # 自定義名稱 供receiver: default使用
email_configs: # 郵件報警模塊
- to: 'wangshile@datang.com'
send_resolved: true
創建啟動文件並啟動
[root@server02 opt]# vi /usr/lib/systemd/system/alertmanager.service [Unit] Description=alertmanager Documentation=https://prometheus.io/ After=network.target [Service] Type=simple User=prometheus ExecStart=/opt/alertmanager/alertmanager --config.file=/opt/alertmanager/alertmanager.yml Restart=on-failure [Install] WantedBy=multi-user.target [root@server01 alertmanager]# chown -R prometheus.prometheus /usr/lib/systemd/system/alertmanager.service [root@server01 alertmanager]# systemctl start alertmanager
Prometheus配置Alertmanager
添加報警規則
[root@server01 prometheus]# vi rules/node_alerts.yml
groups:
- name: node_alerts # 組名稱
rules:
- alert: HighNodeCPU # 規則名稱必須唯一
expr: instance:node_cpu:avg_rate5m > 80 # 該指標是否大於80,改表達式在自定義規則文件中
for: 60m # 需要在觸發警報之前的60分鍾內大於80%,限制了警報誤報或是暫時狀 態的可能性
labels:
severity: warning
annotations:
summary: High Node CPU of {{ humanize $value}}% for 1 hour # 警報的描述
prometheus配置
[root@server01 alertmanager]# vi /opt/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- "rules/*_rules.yml"
- "rules/*_alerts.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'alertmanager'
static_configs:
- targets: ['localhost:9093']
# 基於文件的服務發現
- job_name: node
file_sd_configs:
- files:
- targets/nodes/*.json
refresh_interval: 5m
- job_name: docker
file_sd_configs:
- files:
- targets/docker/*.json
refresh_interval: 5m
metric_relabel_configs:
- source_labels: [id]
regex: '/docker/([a-z0-9]+)'
replacement: '$1'
target_label: container_id
- source_labels: [__name__]
separator: ','
regex: '(container_tasks_state|container_memory_failures_total)'
action: drop
添加基於文件的服務發現
[root@server01 ~]# mkdir /opt/prometheus/targets/{nodes,docker} -p
[root@server01 ~]# vi /opt/prometheus/targets/nodes/nodes.json
[{
"targets": ["10.4.7.11:9100"]
}]
[root@server01 ~]# vi /opt/prometheus/targets/docker/daemons.json
[{
"targets": ["10.4.7.11:8080"]
}]
[root@server01 prometheus]# kill -HUP 15916
添加之后可以在頁面上看到。
警報觸發
警報可能有以下三種狀態:
- Inactive:警報未激活。
- Pending:警報已滿足測試表達式條件,但仍在等待for子句中指定的持續時間。
- Firing:警報已滿足測試表達式條件,並且Pending的時間已超過for子句的持續時間。
Pending到Firing的轉換可以確保警報更有效,且不會來回浮動。沒有for子句的警報會自動從Inactive轉換為Firing,只需要一個評估周期即可觸發。帶有for子句的警報將首先轉換為Pending,然后轉換為Firing,因此至少需要兩個評估周期才能觸發。
警報觸發過程
1. 節點的CPU不斷變化,每隔一段由scrape_interval定義的時間被Prometheus抓取一次,對我們來說 是15秒
2. 根據每個evaluation_interval的指標來評估警報規則,對我們來說還是15秒
3. 當警報表達式為true時(對於我們來說是CPU超過80%),會創建一個警報並轉換到Pending狀 態,執行for子句
4. 在下一個評估周期中,如果警報測試表達式仍然為true,則檢查for的持續時間。如果超過了持續 時間,則警報將轉換為Firing,生成通知並將其推送到Alertmanager
5. 如果警報測試表達式不再為true,則Prometheus會將警報規則的狀態從Pending更改為Inactive

添加新警報和模板
[root@server01 rules]# vi node_rules.yml
- alert: DiskWillFillIn4Hours
expr: predict_linear(node_filesystem_free_bytes{mountpoint="/"}[1h], 4*3600) < 0
for: 5m
labels:
severity: critical
annotations:
summary: Device {{$labels.device}} on node {{$labels.instance}} is running
full within the next 4 hours (mounted at {{ $labels.mountpoint }})
- alert: InstanceDown
expr: up{job="node"} == 0 # 服務停止則報警
for: 10s
labels:
severity: critical
annotations:
summary: Host {{ $labels.instance }} is down!
模板
模板使用標准的Go模板語法,並暴露一些包含時間序列的標簽和值的變量。標簽以變量$labels形式表示,指標的值則是變量$value。
要在summary注解中引用instance標簽,我們使用{{$labels.instance}}。如果想要引用時間序列的 值,那么我們會使用{{$value}}。
annotations:
summary: High Node CPU of {{ humanize $value}}% for 1 hour
這會將指標值顯示為兩位小數的百分比,例如88.23%。
Prometheus警報
在這里,我們添加了兩個新規則。第一個是PrometheusConfigReloadFailed,它讓我們知道 Prometheus配置重新加載是否失敗。如果上次重新加載失敗,則使用指標 prometheus_config_last_reload_successful,且指標的值為0
[root@server01 rules]# vi prometheus_alerts.yml
groups:
- name: prometheus_alerts
rules:
- alert: PrometheusConfigReloadFailed
expr: prometheus_config_last_reload_successful == 0 # prometheus是否加載成功
for: 10m
labels:
severity: warning
annotations:
description: Reloading Prometheus' configuration has failed on {{ $labels.instance }}.
- alert: PrometheusNotConnectedToAlertmanagers
expr: prometheus_notifications_alertmanagers_discovered < 1 # prometheus是否連接alertmanager
for: 10m
labels:
severity: warning
annotations:
description: Prometheus {{ $labels.instance }} is not connected to any Alertmanagers
在這里,我們添加了兩個新規則。第一個是PrometheusConfigReloadFailed,它讓我們知道 Prometheus配置重新加載是否失敗。如果上次重新加載失敗,則使用指標 prometheus_config_last_reload_successful,且指標的值為0
可用性警報
最后的警報可以幫助我們確定主機和服務的能力。第一個警報利用了我們使用Node Exporter收集 的systemd指標。如果我們在節點上監控的服務不再活動,則會生成一個警報。
- alert: NodeServiceDown
expr: node_systemd_unit_state{state="active"} != 1
for: 60s
labels:
severity: critical
annotations:
summary: Service {{ $labels.name }} on {{ $labels.instance }} is no longer active!
description: Werner Heisenberg says - "OMG Where's my service?"
如果帶有active標簽的node_systemd_unit_state指標值為0,則會觸發此警報,表示服務故障至少60秒,Prometheus有一個功能叫absent,可檢測是否存在缺失的指標
[root@server01 rules]# kill -HUP 25041
路由
[root@server01 rules]# vi /opt/alertmanager/alertmanager.yml
route:
group_by: ['instance'] # 分組報警的方式,使用instance進行分組
group_wait: 30s
group_interval: 5m # 發送第一次后第二次警報的等待時間
repeat_interval: 3h # 重復告警發送間隔時間
receiver: email
routes: # 路由表
- match:
severity: critical
receiver: pager # 接收器
routes:
- match:
service: application1 # 將所有severity標簽與application1值匹配,並將它們發送到pager接收器。
receiver: support_team
- match_re:
severity: ^(informational|warning)$ # 正則表達式匹配:匹配severity標簽中的informational或warning值
receiver: support_team
receivers:
- name: 'email'
email_configs:
- to: 'alerts@example.com'
- name: 'support_team'
email_configs:
- to: 'support@example.com'
- name: 'pager'
email_configs:
- to: 'alert-pager@example.com'
slack_configs:
- api_url: https://hooks.slack.com/services/ABC123/ABC123/EXAMPLE
text: '{{ .CommonAnnotations.summary }}'
路由分支
routes:
- match:
service: application1 # 將所有severity標簽與application1值匹配,並將它們發送到pager接收器。
receiver: pager
routes:
- match:
service: application1
receiver: support_team
可以看到我們的新routes塊嵌套在已有的route塊中。要觸發此路由,我們的警報首先需要severity 標簽為critical,並且service標簽是application1。如果這兩個條件都匹配,那么我們的警報將被路由到接收器support_team。
silence和維護
通常我們需要讓警報系統知道我們已經停止服務以進行維護,並且不希望觸發警報
可以使用以下兩種方法來設置silence:


