[TOC]
描述: Alertmanager 负责接收来自所有Prometheus服务器的告警,并根据其规则将告警以邮件、聊天信息和呼叫等方式进行通知。
Tips : 注意在使用告警规则文件前必须在prometheus.yaml
中设置抓取目标以及加载规则文件,使用记录告警规则可以让Prometheus定期执行PromQL表达式并记录其结果。
alerting:
alertmanagers:
- follow_redirects: true
scheme: http
timeout: 10s
api_version: v2
static_configs:
- targets:
- localhost:9093
Prometheus 告警分为两个部分进行实现监控规则匹配以及告警信息的通知。
Prometheus
中添加告警规则,定义告警产生的逻辑。Alertmanager
系统将触发的警报转化为通知,例如邮件、呼叫和聊天消息。通知管道流程
repeat_interval
。告警状态
Prometheus Alert 告警状态有三种状态:Inactive、Pending、Firing
。
参考来源
描述: 下面主要讲解接收者(receiver)、路由树(route)、分组(Groupby)、抑制重复、已处理通知、抑制警告。
接收者 描述: receiver 字段指定了告警通知哪种方式进行发送,国内常用email、webhook、钉钉或者企业微信等方式进行告警,它也支持HipChat、PagerDuty(可以进行确认警告)、Pushover、Slack、OpsGenie、VictorOps等。
路由树 描述: route 字段指定顶级它是默认路由,根路由下可以设置许多字路由(你可将其比喻作根域名),路由的匹配是当告警规则到来后根据其携带的标签进行判断,如果匹配子路由1的规则就会匹配次路由并且停止继续匹配,如果不匹配将会对子路由2的规则进行匹配,如都没匹配到则采用根路由的设置。
Tips : Prometheus 官方有提供一个可视化路由编辑器,可以显示该树以及告警遵循的路由。
分组 描述: group_by 字段允许你指定标签列表对告警进行分组,在未设置分组时该路由默认将所有路由都放入一个组中,意味着你将得到一个内容很大的通知。当在设置分组后可以按照报警等级、环境、以及location来进行拆分警告。
注意: 通常按照instance标签
进行分组并不是一个好主意,因为当存在影响整个应用程序的问题时,它可能会导致大量信息。
# 个人理解(伪配置)
group_by: ['team']
group_by: ['env','region']
match_re:
severity: (page|ticket) # 重要事件&通知单
# severity标签值为ticket和page的记录也将按照region和env进行分组。
env {page|ticket}
team ->
region (page|ticket)
抑制重复 描述: 如果你不希望每次触发告警后当告警集发生改变时都将收到新的通知,这会导致大量的垃圾邮件。
此时我们可以使用 group_wait(每个来的警告组【Firing】发送等待
) 与 group_interval(发送一个警告组后,下一组警告组的等待时间) 、repeat_interval(发送警告成功后,如果在上面两个参数指定的时间内没有完成时,将等待该参数时间到了,便继续发送
-推荐设置4H)来设置Altermanager通知分组限制。
Tips : repeat_interval 必须要比 group_interval 大否则将无任何意义。
已处理通知 描述: send_resolved 字段,当告警问题解决后是否发送通知,启用后将在下一个通知包含此告警,如果列表中没有其它告警触发,它甚至只会发送已经解决通知的警告。
抑制警告 描述: inhibit_rules 字段 ,允许你在其它告警被触发时将某些警告视为不触发。例如数据迁移后旧的机器出现问题但由于用户数据已经转移到其它地方,那么发送此种警告便没有多大意义。
# (1) 全局设置
global:
# - QQ企业邮件通知相关配置
resolve_timeout: 5m
smtp_from: 'monitor@weiyigeek.top'
smtp_smarthost: 'smtp.exmail.qq.com:465'
smtp_auth_username: 'monitor@weiyigeek.top'
smtp_auth_password: 'xxxxxxxxxxxxxxx'
smtp_require_tls: false
# (2) 告警模板&告警接收者
templates:
- '/etc/alertmanager/*.tmpl'
- name: 'email-notify'
email_configs:
- send_resolved: true # 如设置为true问题已解决将发送信息,如设置false则不发送
from: 'monitor@weiyigeek.top'
to: '{{ template "email.to" . }}'
html: '{{ template "email.to.html" . }}'
- name: 'wechat-notify'
wechat_configs:
- send_resolved: true
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
corp_id: 'ww32cf0bf4e14b11487'
agent_id: '1000002'
api_secret: 'SYCdXbWj5SjdT9p1OSQnjIZ4RF_SIRqERVuZNWE1yE5g'
to_user: '@all'
to_party: '1'
message: '{{ template "wechat.default.message" . }}'
- name: 'wehook-notify'
webhook_configs:
- url: http://webhook.weiyigeek.top:8888/alert
# 抑制告警规则: 如果存在severity标签值为critical告警,将会抑制带有severity标签值为warning以及service标签的警告。
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['service']
# (3) 路由树
route:
# 路由默认通知接收器为邮箱通知
receiver: 'email-notify'
group_by: ['team'] # 默认路由告警按照team标签进行分组,如没有该标签的告警将不会进行后续匹配。
group_wait: 30s # 当传入警报创建新的警报组时,请至少等待“group_wait”以发送初始通知。
group_interval: 5m # 发送第一个通知时,请等待“group_interval”以发送一批新警报,这些警报已开始为该组触发。
repeat_interval: 4h # 如果警报已成功发送,请等待“重复间隔”发送警报。
# continue: true # 当匹配一个路由后它不会停止继续向下查找,主要用于将告警记录记录到另外一个系统。
# 非常注意: 所有上述属性都由所有子路由继承,并且可以在每个子路由上进行覆盖。
# * 子路由设置
routes:
# 前端团队,开发测试环境主机(team/severity)分别是在告警规则文件中设置的标签。
- match:
team: frontend
env: dev
group_by: ['region','env'] # frontend 团队根据region和env标签对告警进行分组,它针对后续子路有效,因此它们severity标签值为ticket和page的记录也将按照region和env进行分组。
group_interval: 6m # 组警告之间的间隔时间
receiver: 'email-notify' # 没有匹配到下述条件的告警将发送给该接收者。
# 还可嵌套子路由
routers:
- match:
severity: page # 重要事件
receiver: 'frontend-pager'
group_wait: 1m # 组警告等待
- match:
severity: ticket # 通知单
receiver: 'frontend-pager'
# 后端团队,开发测试环境主机
- match:
team: backend
env: dev
receiver: 'email-notify'
# 还可嵌套子路由
routers:
- match:
severity: page # 重要事件
receiver: 'backend-pager'
- match:
severity: ticket # 通知单
receiver: 'backend-pager'
# 全团队,线上环境
- match:
env: prod
receiver: 'wechat-notify'
# 还可嵌套子路由
routers:
- match:
severity: critical # 极为严重
receiver: 'wechat-notify-manager'
# 支持正则匹配就不用写多行标签了。
- match_re:
severity: (page|ticket) # 重要事件&通知单
receiver: 'wechat-notify-devops'
描述: 我们知道 Alertmanager 要进行警告必须需要编写对应的告警规则,然后以告警自定义模板文件进行通知接收者。
prometheus.yml
和rule.yml
文件后分别使用promtool check (config|rules) 进行检测。level:metric:operations
如是job_name:up:rate5m
Tips : 对于告警规则过滤是必不可少的,评估告警表达式返回空的瞬时向量不会触发任何告警规则,但如果任何样本返回每个都将成为告警。
基础告警规则配置:
groups:
- name: node-alert
rules:
- alert: "监控节点丢失或宕机"
expr: avg without()(up) < 1
for: 2m
labels:
severity: 'critical'
annotations:
message: "服务器实例 [{{ $labels.instance }}]节点丢失或宕机,"
description: "请系统管理员尽快进行人工干预处理!"
- alert: "L-五分钟内CPU使用率大于90%"
expr: (node_load5 /ignoring(mode) count without(cpu)(node_cpu_seconds_total{mode="idle"}) * 100) > 90
for: 3m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} CPU 使用率 告警通知"
description: "{{ $labels.instance }}CPU使用率已超过90%, 当前值: {{ $value }}%"
- alert: "L-内存可用容量小于 10%"
expr: ((node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / (node_memory_MemTotal_bytes )) * 100 > 80
for: 2m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} 内存不足 告警通知"
description: "{{ $labels.instance }} 内存可用资源已不足 10%,当前值: {{ $value }} %"
- alert: "L-磁盘可用容量小于 10%"
expr: round(100 - ((node_filesystem_avail_bytes{mountpoint=~".*",fstype=~"nfs|ext4|xfs|ext2|ext3"} * 100) / node_filesystem_size_bytes {mountpoint=~".*",fstype=~"nfs|ext4|xfs|ext2|ext3"}) > 90)
for: 3m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} 磁盘不足 告警通知"
description: "{{ $labels.instance }} 磁盘 {{ $labels.device }} 资源 已不足 10%, 当前值: {{ $value }}%"
- alert: "W-内存可用容量小于 10%"
expr: round((1 - (windows_os_physical_memory_free_bytes / windows_cs_physical_memory_bytes)) * 100) > 90
for: 2m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} 内存不足 告警通知"
description: "{{ $labels.instance }} 内存可用资源已不足 10%,当前值: {{ $value }}"
- alert: "W-磁盘可用容量小于 10%"
expr: round((1 - windows_logical_disk_free_bytes{volume=~"C:|D:|E:|F:"} / windows_logical_disk_size_bytes{volume=~"C:|D:|E:|F:"} ) * 100 > 90)
for: 3m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} 磁盘不足 告警通知"
description: "{{ $labels.instance }} 磁盘 {{ $labels.volume }} 资源 已不足 10%, 当前值: {{ $value }}%"
- alert: "W-五分钟内CPU使用率大于 90%"
expr: round(100 - ((avg without(core,mode)(irate(windows_cpu_time_total{mode="idle"}[5m]))) * 100) > 90)
for: 3m
labels:
severity: warning
annotations:
message: "服务器实例 {{ $labels.instance }} CPU 使用率 告警通知"
description: "{{ $labels.instance }}CPU使用率已超过90%, 当前值: {{ $value }}%"
- alert: "Website-网站服务访问状态异常"
expr: probe_success{job="HTTP-Check"} < 1
for: 5m
labels:
severity: warning
annotations:
message: "网站地址 {{ $labels.http }} ,无法正常提供服务"
description: "请检查并恢复网站名称为 {{ $labels.site }} 应用服务,当前值: {{ $value }}%"
描述: alertmanager带有默认模板同时支持我们编写自定义报警通知模板,并且发送给接收者的通知是通过模板构建。除了文本字段可以模板化以外,还可模板化通知的目的地,通过传递在告警规则中添加指定接受用户标签,便可以在模板总引用并发生(非常Nice)。
Tips : 注意 Alertmanager 模板与 Prometheus 中的模板不同, Prometheus 模板还包括警报规则标签/注释中的模板
。
参考地址: https://prometheus.io/docs/alerting/latest/notifications/
描述: 以下是警报和相应的 Alertmanager 配置文件设置 (alertmanager.yml) 的所有不同示例。
# 模板代码块必须使用 {{ var }} 包含
# 1.定义包含
{{ define "wechat.custom.message" }}
app: {{ .GroupLabels.app }}/{{ .GroupLabels.alertname }}
# 2.条件判断(运算符:gt/lt/eq/gte/lte)
{{- if gt (len .Alerts.Firing) 0 -}}
# 3.条件循环
{{- range $index, $alert := .Alerts -}}
告警序号: {{ $index }}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.summary }}
# 4.此处格式的时间字符串是Go诞生时间。
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间: {{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
{{ end }}
{{ end }}
{{ end}}
Tips : 更多语法请参照使用 Go 模板系统(https://golang.org/pkg/text/template)。
描述: 数据是传递给通知模板和 webhook 推送的结构。
Name | Type | Notes |
---|---|---|
Receiver | string | 定义通知将发送到的接收者名称(slack、电子邮件等)。 |
Status | string | 如果至少有一个警报被触发,则定义为触发,否则已解决。 |
Alerts | Alert | 该组中所有警报对象的列表:Alerts.Firing 返回该组中当前触发的警报对象的列表 Alerts.Resolved 返回此组中已解决警报对象的列表 |
GroupLabels | KV | 这些警报分组所依据的标签。 |
CommonLabels | KV | 所有警报通用的标签。 |
CommonAnnotations | KV | 所有警报的通用注释集,用于有关警报的更长的附加信息字符串。 |
ExternalURL | string | 反向链接到发送通知的 Alertmanager。 |
简单使用示例:
# 实例instance标签
{{ .GroupLabels.instance }}
# 告警数量
{{ .Alerts | len }}
{{ (len .Alerts.Firing) }}
Alert 包含一个通知模板的警报。
Name | Type | Notes |
---|---|---|
Status | string | 定义警报是否已解决或当前是否触发。 |
Labels | KV | 要附加到警报的一组标签。 |
Annotations | KV | 警报的一组注释。 |
StartsAt | time.Time | 警报开始触发的时间。 如果省略当前时间由 Alertmanager 分配。 |
EndsAt | time.Time | 仅在已知警报的结束时间时设置。 否则设置为自上次收到警报以来的可配置超时时间。 |
GeneratorURL | string | 标识此警报的原因实体的反向链接。 |
Fingerprint | string | 可用于识别警报的指纹。 |
{{- range $index, $alert := .Alerts -}}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.summary }}
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间: {{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
{{- end }}
描述: 请注意 Go 模板也提供的默认功能。
Name | Arguments | Returns | Notes |
---|---|---|---|
title | string | strings.Title,将每个单词的第一个字符大写。 | |
toUpper | string | strings.ToUpper,将所有字符转换为大写。 | |
toLower | string | strings.ToLower,将所有字符转换为小写。 | |
match | pattern, string | 正则表达式.MatchString。使用 Regexp 匹配字符串。 | |
reReplaceAll | pattern, replacement, text | Regexp.ReplaceAllString 正则表达式替换,未锚定。 | |
join | sep string, s []string | strings.Join,连接 s 的元素以创建单个字符串。 分隔符字符串 sep 放置在结果字符串中的元素之间。 (注意:参数顺序颠倒以便在模板中更容易流水线化。) | |
safeHtml | text string | html/template.HTML,将字符串标记为不需要自动转义的 HTML。 | |
stringSlice | …string | 将传递的字符串作为字符串切片返回。 |
描述: 在前面几章的学习中都没有讲解AlertManager报警管理系统的使用,博主专门把他放在本章进行讲解,因为其实现报警通知的方式有多种多样。
Email_config 配置参考: https://prometheus.io/docs/alerting/latest/configuration/#email_config
# - 注意此处非全局所以没有smtp前缀
# Whether or not to notify about resolved alerts.
[ send_resolved: <boolean> | default = false ]
# The email address to send notifications to.
to: <tmpl_string>
# The sender address.
[ from: <tmpl_string> | default = global.smtp_from ]
# The SMTP host through which emails are sent.
[ smarthost: <string> | default = global.smtp_smarthost ]
# The hostname to identify to the SMTP server.
[ hello: <string> | default = global.smtp_hello ]
# SMTP authentication information.
[ auth_username: <string> | default = global.smtp_auth_username ]
[ auth_password: <secret> | default = global.smtp_auth_password ]
[ auth_secret: <secret> | default = global.smtp_auth_secret ]
[ auth_identity: <string> | default = global.smtp_auth_identity ]
# The SMTP TLS requirement.
# Note that Go does not support unencrypted connections to remote SMTP endpoints.
[ require_tls: <bool> | default = global.smtp_require_tls ]
# TLS configuration.
tls_config:
[ <tls_config> ]
# The HTML body of the email notification.
[ html: <tmpl_string> | default = '{{ template "email.default.html" . }}' ]
# The text body of the email notification.
[ text: <tmpl_string> ]
# Further headers email header key/value pairs. Overrides any headers
# previously set by the notification implementation.
[ headers: { <string>: <tmpl_string>, ... } ]
实践目标:
Step 1.首先我们需要配置 Prometheus.yml 抓取目标、加载规则文件,并与Alertmanager通信设置。
global:
scrape_interval: 2m
scrape_timeout: 10s
# - 每分钟进行报警规则的评估 (建议根据实际情况进行修改)
evaluation_interval: 1m
external_labels:
monitor: 'prom-demo'
alerting:
# - 设置报警管理系统的目标地址 (可以配置多个AlertManager)
alertmanagers:
- scheme: http
static_configs:
- targets:
- '192.168.12.107:30093'
rule_files:
# - 指标监控告警规则 (可以根据不同的场景进行报警规则)
- /etc/prometheus/conf.d/rules/*.rules
# - 采集监控的静态目标和自动化发现目标
scrape_configs:
- job_name: 'prom-Server'
static_configs:
- targets: ['localhost:9090']
- job_name: 'cAdvisor'
static_configs:
- targets: ['192.168.12.111:9100']
- job_name: 'linux_exporter'
scrape_interval: 30s
file_sd_configs:
- files:
- /etc/prometheus/conf.d/discovery/k8s_nodes.yaml
# - 自动刷新自动发现配置文件
refresh_interval: 1m
Step 2.配置 Prometheus 报警规则此次判断采集节点的状态和节点主机负载情况
tee alert.rules <<'EOF'
groups:
- name: node-normal
rules:
- alert: service_down
expr: up {job="linux_exporter"} == 0
# - 对于持续时间的设置在实际环境中至少建议5min,以减少噪声从而减轻固有监控各种情况,此处设置为30s便于报警情况的观察。
for: 30s
labels:
severity: 'critical'
team: node
annotations:
summary: "主机 {{ $labels.instance }} 监控服务已停止运行超过 15s!"
description: "请系统管理员尽快进行人工干预处理!"
- alert: high_load
expr: node_load1 > 0.7
for: 5m
labels:
severity: 'warning'
team: node
annotations:
summary: "主机 {{ $labels.instance }} 高负载大于0.7以上运行超过 5m!"
EOF
Tips : 说明一下该 rules 目的是监测 node 是否存活 expr 为 PromQL 表达式验证特定节点 job=”linux_exporter” 是否活着,for 表示报警状态为 Pending 后等待 30s 变成 Firing 状态,一旦变成 Firing 状态则将报警发送到 AlertManager 并且 labels (标签
)和 annotations(注释
) 对该 alert 添加更多的标识和注解信息。
Step 3.配置 Alertmanager 报警通知,此时配置腾讯企业邮箱的方式进行邮件发送报警。
tee alertmanager.yaml <<'EOF'
# - 全局配置
global:
resolve_timeout: 5m
smtp_from: 'monitor@weiyigeek.top'
# - 企业邮箱 SMTP 服务地址
smtp_smarthost: 'smtp.exmail.qq.com:465'
smtp_auth_username: 'monitor@weiyigeek.top'
# - 第三方登录企业邮箱的授权码
smtp_auth_password: xxxxxxxxxxx'
smtp_require_tls: false
# smtp_hello: 'qq.com'
# - 设置报警的分发策略
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
# - 如果在10分钟内还未解除报警则进行发送告警
repeat_interval: 10m
receiver: 'default-email'
# - 配置告警消息接受者信息
receivers:
- name: 'default-email'
email_configs:
- to: 'master@weiyigeek.top'
send_resolved: true
# - 抑制规则配置
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']
EOF
Step 4.重启Prometheus和Alertmanager服务,同时关闭一台node进行触发报警发送 Email,上边我们定义的 rule 规则为监测 job=”linux_exporter” Node 是否活着,那么就可以停掉 node-exporter 服务来间接起到 Node Down 的作用,从而达到报警条件,触发报警规则。
# - 重启容器
docker restart prometheus_alertmanager prometheus_server
# - 关闭192.168.12.109机器的node_exporter服务
ssh -p 20211 weiyigeek@weiyigeek-109 "sudo -S systemctl stop node_exporter.service"
[sudo] password for weiyigeek:
Step 5.效果查看及报警流程说明,关闭后等待prometheus定时拉取各job的任务执行,其次我们可以在Targets
刷新查看linux_exporter
任务中状态为 unhealthy 192.168.12.109
的节点状态是否变成了DOWN,等待 30s 后,alert 页面由绿色 Service_down (0 active) Inactive 状态变成了黄色 Service_down (1 active) Pending 状态,继续等待 30s 后状态变成红色 Firing 状态,向 AlertManager 发送报警信息,此时 AlertManager 则按照配置规则向接受者发送邮件告警。
linux_exporter (5/6 up)
Endpoint State Error
http://192.168.12.109:9100/metrics DOWN Get "http://192.168.12.109:9100/metrics": dial tcp 192.168.12.109:9100: connect: connection refused
WeiyiGeek.Alert
Annotations
注释信息。 WeiyiGeek.AlertManager-Firing
Step 7.然后我们将192.168.12.109
机器的linux_exporter服务进行开启查看其恢复以及警报解除情况。在等待 30s 之后,Prometheus Alerts 页面变成绿色 Service_down (0 active) Inactive
状态,同时也收到了报警解除邮件提醒。
ssh -p 20211 weiyigeek@weiyigeek-109 "sudo -S systemctl start node_exporter.service"
WeiyiGeek.AlertManager-Resolved
Tips : 每次停止/恢复服务后 30s 之后才会发现 Alert 状态变化,是因为 prometheus.yml中 global -> scrape_interval: 30s 配置决定的,如果觉得等待 30s 时间太长,可以修改小一些可以全局修改,也可以局部修改。例如s上面就行采用局部修改 linux_exporter 等待时间为 30s。
描述: 虽然默认的邮件报警样式模板已经包含了所有核心的信息,但是邮件格式内容可以更优雅直观一些,同时AlertManager 也是支持自定义邮件模板配置的。
Step 1.首先新建一个模板文件 email.tmpl
tee email.tmpl<<'EOF'
{{ define "email.from" }}monitor@weiyigeek.top{{ end }}
{{ define "email.to" }}master@weiyigeek.top{{ end }}
{{ define "email.to.html" }}
{{ range .Alerts }}
<b>=========start==========</b><br>
告警程序: prometheus_alert <br>
告警级别: {{ .Labels.severity }} 级 <br>
告警类型: {{ .Labels.alertname }} <br>
故障主机: {{ .Labels.instance }} <br>
告警主题: {{ .Annotations.summary }} <br>
告警详情: {{ .Annotations.description }} <br>
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }} <br>
<b>=========end==========</b><br>
{{ end }}
{{ end }}
EOF
Tips : 注意上述的.StartsAt.Format
的格式化字符必须是"2006-01-02 15:04:05"
(Go 语言诞生的时间我,我们可以简约记2006 1 2 3 4 5
),否则报警的时间不对。
Step 2.其次在AlertManager主配置文件中引用模板及其定义
tee alertmanager.yaml <<'EOF'
global:
resolve_timeout: 5m
smtp_from: 'monitor@weiyigeek.top'
smtp_smarthost: 'smtp.exmail.qq.com:465'
smtp_auth_username: 'monitor@weiyigeek.top'
smtp_auth_password: 'xxxxxxxxxxxxxxx'
smtp_require_tls: false
# smtp_hello: 'qq.com'
# - Tips 上面的全局邮件参数无法从email.tmpl中读取{{ template "email.username" . }}坑(排错一下午)
templates:
- '/alertmanager/email.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 10m
receiver: 'default-email'
receivers:
- name: 'default-email'
email_configs:
- to: '{{ template "email.to" . }}'
html: '{{ template "email.to.html" . }}'
# 如果问题已解决将发送信息如设置false则不发送
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']
EOF
温馨提示:全局中的邮件参数无法从email.tmpl中读取定义的模板参数,例如{{ template "email.username" .}}坑(排错一下午)只有以下对象可以读取:
email_config:
- to: <tmpl_string>
from: <tmpl_string>
html: <tmpl_string> | text: <tmpl_string> {{ template "email.default.html" . }}
Tips:官方email_config配置参考地址(https://prometheus.io/docs/alerting/latest/configuration/#email_config)
docker restart prometheus_alertmanager
, 然后同样停止192.168.12.109
的node_exporter服务ssh -p 20211 weiyigeek@weiyigeek-109 "sudo -S systemctl stop node_exporter.service"
然后等待prometheus拉取的时间30s,此时为pending状态,再等待30s此时为Firing状态并发送告警邮件,并且在10分钟外如果还收到该报警信息便会再次进行发送。WeiyiGeek.自定义邮件模板
描述: Alertmanager 已经内置了对企业微信的支持,我们可以通过企业微信来管理报警,更进一步可以通过企业微信和微信的互通来直接将告警消息转发到个人微信上,在前面的Alertmanager.yaml配置文件参数进行了解也可以从prometheus的官网 中给出了企业微信的相关配置说明如下:
# Whether or not to notify about resolved alerts.
[ send_resolved: <boolean> | default = false ]
# The WeChat API URL.
[ api_url: <string> | default = global.wechat_api_url ]
# 企业微信账号唯一 ID, 可以在我的企业中查看。
[ corp_id: <string> | default = global.wechat_api_corp_id ]
# 第三方企业应用的密钥,可以在自己创建的第三方企业应用详情页面查看。
[ api_secret: <secret> | default = global.wechat_api_secret ]
# 第三方企业应用的 ID,可以在自己创建的第三方企业应用详情页面查看。
[ agent_id: <string> | default = '{{ template "wechat.default.agent_id" . }}' ]
# 在后台通讯录查看需要发送的组的部门ID ( PartyID1 | PartyID2)
[ to_party: <string> | default = '{{ template "wechat.default.to_party" . }}' ]
# 发送的成员 @all 表示所有的成员
[ to_user: <string> | default = '{{ template "wechat.default.to_user" . }}' ]
# 发送给特点 tag 标记的,
[ to_tag: <string> | default = '{{ template "wechat.default.to_tag" . }}' ]
#
[ message: <tmpl_string> | default = '{{ template "wechat.default.message" . }}' ]
Tips : 企业微信相关概念说明请参考企业微信API说明,可以在企业微信的后台中建立多个应用,每个应用对应不同的报警分组,由企业微信来做接收成员的划分。
操作流程步骤:
WeiyiGeek.创建自建应用
Step 2.查看的获得 AgentId 以及 Secret 将其记录下来以及部门ID:to_party
(需要发送的组),在后面的AlertManager.yml
配置文件中使用。
# - 例如:博主的AgentId和Secret的格式如下
企业ID: ww32cf0bf4e4b11487
agent_id: 1000002
api_secret: SYCdXbWj5SjdT9pOSQnjIZ4RF_SIRqERVuZNWE1yE5g
to_party: 1
WeiyiGeek.AgentId和Secret
Step 3.编辑Alertmanager.yaml主配置文件设置企业微信通知相关参数。
tee alertmanager.yaml <<'EOF'
global:
resolve_timeout: 2m
templates:
- '/alertmanager/*.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 1m
repeat_interval: 10m
receiver: 'wechat'
receivers:
- name: 'default-email'
email_configs:
- from: 'monitor@weiyigeek.top'
smarthost: 'smtp.exmail.qq.com:465'
auth_username: 'monitor@weiyigeek.top'
auth_password: 'xxxxxxxxxxxxxxx'
require_tls: false
# smtp_hello: 'qq.com'
to: '{{ template "email.to" . }}'
html: '{{ template "email.to.html" . }}'
send_resolved: true
- name: 'wechat'
wechat_configs:
- send_resolved: true
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
corp_id: 'ww32cf0bf4e4b11487'
agent_id: '1000002'
api_secret: 'SYCdXbWj5SjdT9pOSQnjIZ4RF_SIRqERVuZNWE1yE5g'
to_user: '@all'
to_party: '1'
message: '{{ template "wechat.default.message" . }}'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']
EOF
docker restart prometheus_alertmanager
以后,我们先来查看默认的企业微信报警信息通知。WeiyiGeek.Webchat报警查看
Step 5.采用自定义的Wechat报警模块(包括Firing和Resolved)的信息通知
tee wechat.tmpl <<'EOF'
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
=====================
{{- end }}
===告警详情===
告警详情: {{ $alert.Annotations.summary }}
告警描述: {{ $alert.Annotations.description }}
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
===参考信息===
{{ if gt (len $alert.Labels.instance) 0 -}}故障实例ip: {{ $alert.Labels.instance }};{{- end -}}
{{- if gt (len $alert.Labels.namespace) 0 -}}故障实例所在namespace: {{ $alert.Labels.namespace }};{{- end -}}
{{- if gt (len $alert.Labels.node) 0 -}}故障物理机ip: {{ $alert.Labels.node }};{{- end -}}
{{- if gt (len $alert.Labels.pod_name) 0 -}}故障pod名称: {{ $alert.Labels.pod_name }}{{- end }}
=====================
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 -}}
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
=====================
{{- end }}
===告警详情===
告警详情: {{ $alert.Annotations.summary }}
故障时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
恢复时间: {{ $alert.EndsAt.Format "2006-01-02 15:04:05" }}
===参考信息===
{{ if gt (len $alert.Labels.instance) 0 -}}故障实例ip: {{ $alert.Labels.instance }};{{- end -}}
{{- if gt (len $alert.Labels.namespace) 0 -}}故障实例所在namespace: {{ $alert.Labels.namespace }};{{- end -}}
{{- if gt (len $alert.Labels.node) 0 -}}故障物理机ip: {{ $alert.Labels.node }};{{- end -}}
{{- if gt (len $alert.Labels.pod_name) 0 -}}故障pod名称: {{ $alert.Labels.pod_name }};{{- end }}
=====================
{{- end }}
{{- end }}
{{- end }}
EOF
Step 6.将alertmanager主配置yaml文件下面的, 采用注释的#去掉即可启用自定义模板信息,将192.168.12.109
机器的node_exporter进行关闭测试模板情况,等待3m将把警告进行发送。
# message: '{{ template "wechat.default.message" . }}'
apt
# 重启
docker restart prometheus_alertmanager
# 日志查看
docker logs --tail 50 -f prometheus_alertmanager
WeiyiGeek.prometheus&alertmanager
(Alerts.Firing)
以及异常恢复(Alerts.Resolved)
通知发送结果查看。WeiyiGeek.Firing&Resolved
补充说明:
1.Wechat 模板示例学习与改进。
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
==========异常告警==========
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
{{- if gt (len $alert.Labels.namespace) 0 }}
命名空间: {{ $alert.Labels.namespace }}
{{- end }}
{{- if gt (len $alert.Labels.node) 0 }}
节点信息: {{ $alert.Labels.node }}
{{- end }}
{{- if gt (len $alert.Labels.pod) 0 }}
实例名称: {{ $alert.Labels.pod }}
{{- end }}
============END============
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
==========异常恢复==========
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
{{- if gt (len $alert.Labels.namespace) 0 }}
命名空间: {{ $alert.Labels.namespace }}
{{- end }}
{{- if gt (len $alert.Labels.node) 0 }}
节点信息: {{ $alert.Labels.node }}
{{- end }}
{{- if gt (len $alert.Labels.pod) 0 }}
实例名称: {{ $alert.Labels.pod }}
{{- end }}
============END============
{{- end }}
{{- end }}
{{- end }}
{{- end }}
描述: 由于 export
并没有提供任何认证支持,所需要借助 Nginx 作为反向代理服务器,添加 HTTP Basic Auth
功能,此时只有授权的用户才能采集监控指标, 可以极大避免未授权访问的情况出现。
操作流程
1.我们采用Nginx镜像作为演示搭建与.htpasswd配置生成。
# 镜像拉取与镜像运行
docker pull nginx:1.21.0
docker run --name auth -d nginx:1.21.0
docker exec -it auth bash
# 使用 `apache2-utils` 提供的 `htpasswd` 工具创建一个用户文件,该镜像中没自带所以我们下载即可
apt install apache2-utils
# 运行 htpasswd 生成一个或多个认证用户
htpasswd -bc htpasswd.auth weiyigeek password
Adding password for user weiyigeek
htpasswd -b htpasswd.auth prometheus password
Adding password for user prometheus
htpasswd -b htpasswd.auth monitor password
Adding password for user monitor
# 拷贝容器中nginx配置
docker cp auth:/etc/nginx /monitor/nginx
# 拷贝生成htpasswd.auth 到宿主机
docker cp auth:/tmp/htpasswd.auth /monitor/nginx
# Nginx 配置文件
root@prometheus:/monitor/nginx/conf# cat conf.d/default.conf
server {
listen 8080;
listen [::]:8080;
server_name monitor.weiyigeek.top;
#access_log /var/log/nginx/host.access.log main;
add_header X-Frame-Options SAMEORIGIN;
auth_basic "weiyigeek Prometheus Metrics";
auth_basic_user_file /etc/nginx/auth/htpasswd.auth;
#这里放的是认证文件位置
location / {
proxy_pass http://monitor.weiyigeek.top:9090;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
access_log /var/log/nginx/prometheus_access.log;
}
}
3.启动nginx反代容器的参数及状态查看
# - 容器启动
docker run -d --name=prometheus_proxy -p 8080:8080 -v /monitor/nginx/conf:/etc/nginx -v /monitor/nginx/logs:/var/log/nginx/ nginx:1.21.0
# - 容器状态
docker ps
<!-- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6347a6498e69 nginx:1.21.0 "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 80/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp prometheus_proxy -->
4.系统防火墙策略设置(安装最小访问权限设置)
# 启动防火墙 & 查看状态
systemctl enable ufw && systemctl restart ufw
ufw status && systemctl status ufw
# 允许所有的机器访问 80(Grafana),8080(Nginx Proxy Prometheus Server)
sudo ufw allow proto tcp to port 80,8080
# 可以通过ip addr查看网卡的网段以便后续docker或者本地访问。
ip addr
# 只允许从本地和docker0网卡访问 9090,9093,9094,9115 端口
sudo ufw allow proto tcp from 127.0.0.1 to any port 9090,9093,9094,9115
ufw delete allow proto tcp from 172.17.0.1/16 to any port 9090,9093,9094,9115
描述: 普罗米修斯监控系统的工具,包含在Prometheus安装包之中。我们可以使用amtool check-config
来检查alertmanager.yml文件以及警报查询和Silences。
语法参数:
usage: promtool [<flags>] <command> [<args> ...]
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
Commands:
help [<command>...] Show help.
check config <config-files>... # Check if the config files are valid or not.
check web-config <web-config-files>... # Check if the web config files are valid or not.
check rules <rule-files>... # Check if the rule files are valid or not.
check metrics # Pass Prometheus metrics over stdin to lint them for consistency and correctness.
query instant [<flags>] <server> <expr> # Run instant query.
query range [<flags>] <server> <expr> # Run range query.
query series --match=MATCH [<flags>] <server> # Run series query.
query labels [<flags>] <server> <name> # Run labels query.
debug pprof <server> # Fetch profiling debug information.
debug metrics <server> # Fetch metrics debug information.
debug all <server> # Fetch all debug information.
test rules <test-rule-file>... # Unit tests for rules.
tsdb bench write [<flags>] [<file>] # Run a write performance benchmark.
tsdb analyze [<flags>] [<db path>] [<block id>] # Analyze churn, label pair cardinality.
tsdb list [<flags>] [<db path>] # List tsdb blocks.
tsdb dump [<flags>] [<db path>] # Dump samples from a TSDB.
tsdb create-blocks-from openmetrics <input file> [<output directory>] # Import samples from OpenMetrics input and produce TSDB blocks. Please refer to the storage docs for more details.
tsdb create-blocks-from rules --start=START [<flags>] <rule-files>... # Create blocks of data for new recording rules.
基础示例:
# - 1.验证指标输出是否有效并执行格式检查。
$ cat metrics.prom | promtool check metrics
$ curl -s http://localhost:9090/metrics | promtool check metrics