导航:这里主要是列出一个prometheus一些系统的学习过程,最后按照章节顺序查看,由于写作该文档经历了不同时期,所以在文中有时出现
的云环境不统一,但是学习具体使用方法即可,在最后的篇章,有一个完整的腾讯云的实战案例。
参考:
本章我们将探索Prometheus的告警处理机制,告警能力在Prometheus的架构中被划分为两个部分,在PrometheusServer中定义告警规则以及产生告警,Alertmanager组件则用于处理这些由Prometheus产生的告警。Alertmanager即Prometheus体系中告警的统一处理中心。Alertmanager提供了多种内置第三方告警通知方式,同时还提供了对Webhook通知的支持,通过Webhook用户可以完成对告警更多个性化的扩展。
本章主要内容:
告警能力在Prometheus的架构中被划分成两个独立的部分。如下所示,通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向Alertmanager发送告警信息。
Prometheus告警处理
在Prometheus中一条告警规则主要由以下几部分组成:
Alertmanager作为一个独立的组件,负责接收并处理来自PrometheusServer(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方,Prometheus内置了对邮件,Slack等多种通知方式的支持,同时还支持与Webhook的集成,以支持更多定制化的场景。例如,目前Alertmanager还不支持钉钉,那用户完全可以通过Webhook与钉钉机器人进行集成,从而通过钉钉接收告警信息。同时AlertManager还提供了静默和告警抑制机制来对告警通知行为进行优化。
Alertmanager除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性:
分组机制可以将详细的告警信息合并成一个通知。在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。
例如,当集群中有数百个正在运行的服务实例,并且为每一个实例设置了告警规则。假如此时发生了网络故障,可能导致大量的服务实例无法连接到数据库,结果就会有数百个告警被发送到Alertmanager。
而作为用户,可能只希望能够在一个通知中中就能查看哪些服务实例收到影响。这时可以按照服务所在集群或者告警名称对告警进行分组,而将这些告警内聚在一起成为一个通知。
抑制是指当某一告警发出后,可以停止重复发送由此告警引发的其它告警的机制。
例如,当集群不可访问时触发了一次告警,通过配置Alertmanager可以忽略与该集群有关的其它所有告警。这样可以避免接收到大量与实际问题无关的告警通知。
抑制机制同样通过Alertmanager的配置文件进行设置。
静默提供了一个简单的机制可以快速根据标签对告警进行静默处理。如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知。
静默设置需要在Alertmanager的Werb页面上进行设置。
Prometheus中的告警规则允许你基于PromQL表达式定义告警触发条件,Prometheus后端对这些触发规则进行周期性计算,当满足触发条件后则会触发告警通知。默认情况下,用户可以通过Prometheus的Web界面查看这些告警规则以及告警的触发状态。当Promthues与Alertmanager关联之后,可以将告警发送到外部服务如Alertmanager中并通过Alertmanager可以对这些告警进行进一步的处理。
一条典型的告警规则如下所示:
为了能够让Prometheus能够启用定义的告警规则,我们需要在Prometheus全局配置文件中通过rule_files指定一组告警规则文件的访问路径,Prometheus启动后会自动扫描这些路径下规则文件中定义的内容,并且根据这些规则计算是否向外部发送通知:
rule_files:[-
global:[evaluation_interval:
一般来说,在告警规则文件的annotations中使用summary描述告警的概要信息,description用于描述告警的详细信息。同时Alertmanager的UI也会根据这两个标签值,显示告警信息。为了让告警信息具有更好的可读性,Prometheus支持模板化label和annotations的中标签的值。
通过$labels.
#Toinsertafiringelement'slabelvalues:{{$labels.
如下所示,用户可以通过PrometheusWEB界面中的Alerts菜单查看当前Prometheus下的所有告警规则,以及其当前所处的活动状态。
告警活动状态
可以通过表达式,查询告警实例:
ALERTS{alertname="
修改Prometheus配置文件prometheus.yml,添加以下配置:
rule_files:-/etc/prometheus/rules/*.rules在目录/etc/prometheus/rules/下创建告警文件hoststats-alert.rules内容如下:
告警规则
此时,我们可以手动拉高系统的CPU使用率,验证Prometheus的告警流程,在主机上运行以下命令:
cat/dev/zero>/dev/null运行命令后查看CPU使用率情况,如下图所示:
如果1分钟后告警条件持续满足,则会实际触发告警并且告警状态为FIRING,如下图所示:
在这一小节中介绍了如何配置和使用Prometheus提供的告警能力,并且尝试实现了对主机CPU以及内存的告警规则设置。目前为止,我们只能通过PrometheusUI查看当前告警的活动状态。接下来,接下来我们将尝试利用Prometheus体系中的另一个组件Alertmanager对这些触发的告警进行处理,实现告警通知。
Alertmanager和PrometheusServer一样均采用Golang实现,并且没有第三方依赖。一般来说我们可以通过以下几种方式来部署Alertmanager:二进制包、容器以及源码方式安装。
获取并安装软件包
创建alertmanager配置文件
Alertmanager解压后会包含一个默认的alertmanager.yml配置文件,内容如下所示:
在Alertmanager中可以定义一组接收器,比如可以按照角色(比如系统运维,数据库管理员)来划分多个接收器。接收器可以关联邮件,Slack以及其它方式接收告警信息。
当前配置文件中定义了一个默认的接收者default-receiver由于这里没有设置接收方式,目前只相当于一个占位符。关于接收器的详细介绍会在后续章节介绍。
在配置文件中使用route定义了顶级的路由,路由是一个基于标签匹配规则的树状结构。所有的告警信息从顶级路由开始,根据标签匹配规则进入到不同的子路由,并且根据子路由设置的接收器发送告警。目前配置文件中只设置了一个顶级路由route并且定义的接收器为default-receiver。因此,所有的告警都会发送给default-receiver。关于路由的详细内容会在后续进行详细介绍。
启动Alertmanager
Alermanager会将数据保存到本地中,默认的存储路径为data/。因此,在启动Alertmanager之前需要创建相应的目录:
查看运行状态
Alertmanager页面
Alert菜单下可以查看Alertmanager接收到的告警内容。Silences菜单下则可以通过UI创建静默规则,这部分我们会在后续部分介绍。进入Status菜单,可以看到当前系统的运行状态以及配置信息。
编辑Prometheus配置文件prometheus.yml,并添加以下内容
此时,再次尝试手动拉高系统CPU使用率:
cat/dev/zero>/dev/null等待Prometheus告警进行触发状态:
查看AlertmanagerUI此时可以看到Alertmanager接收到的告警信息。
目前为止,已经成功安装部署了Alertmanager并且与Prometheus关联,能够正常接收来自Prometheus的告警信息。接下来将详细介绍Alertmanager是如何处理这些接收到的告警信息的。
Alertmanager主要负责对Prometheus产生的告警进行统一处理,因此在Alertmanager配置中一般会包含以下几个主要部分:
其完整配置格式如下:
在Alertmanager的配置中会定义一个基于标签匹配规则的告警路由树,以确定在接收到告警后Alertmanager需要如何对其进行处理:
route:
[receiver:
每一个告警都会从配置文件中顶级的route进入路由树,需要注意的是顶级的route必须匹配所有告警(即不能有任何的匹配设置match和match_re),每一个路由都可以定义自己的接受人以及匹配规则。默认情况下,告警进入到顶级route后会遍历所有的子节点,直到找到最深的匹配route,并将告警发送到该route定义的receiver中。但如果route中设置continue的值为false,那么告警在匹配到第一个子节点之后就直接停止。如果continue为true,报警则会继续进行后续子节点的匹配。如果当前告警匹配不到任何的子节点,那该告警将会基于当前路由节点的接收器配置方式进行处理。
其中告警的匹配有两种方式可以选择。一种方式基于字符串验证,通过设置match规则判断当前告警中是否存在标签labelname并且其值等于labelvalue。第二种方式则基于正则表达式,通过设置match_re验证当前告警标签的值是否满足正则表达式的内容。
在之前的部分有讲过,Alertmanager可以对告警通知进行分组,将多条告警合合并为一个通知。这里我们可以使用group_by来定义分组规则。基于告警中包含的标签,如果满足group_by中定义标签名称,那么这些告警将会合并为一个通知发送给接收器。
例如,当使用Prometheus监控多个集群以及部署在集群中的应用和数据库服务,并且定义以下的告警处理路由规则来对集群中的异常进行通知。
route:receiver:'default-receiver'group_wait:30sgroup_interval:5mrepeat_interval:4hgroup_by:[cluster,alertname]routes:-receiver:'database-pager'group_wait:10smatch_re:service:mysql|cassandra-receiver:'frontend-pager'group_by:[product,environment]match:team:frontend默认情况下所有的告警都会发送给集群管理员default-receiver,因此在Alertmanager的配置文件的根路由中,对告警信息按照集群以及告警的名称对告警进行分组。
前上一小节已经讲过,在Alertmanager中路由负责对告警信息进行分组匹配,并将像告警接收器发送通知。告警接收器可以通过以下形式进行配置:
receivers:-
name:
[send_resolved:
如果所有的邮件配置使用了相同的SMTP配置,则可以直接定义全局的SMTP配置。
这时如果手动拉高主机CPU使用率,使得监控样本数据满足告警触发条件。在SMTP配置正确的情况下,可以接收到如下的告警内容:
Slack作为一款即时通讯工具,协作沟通主要通过Channel(平台)来完成,用户可以在企业中根据用途添加多个Channel,并且通过Channel来集成各种第三方工具。
例如,我们可以为监控建立一个单独的Channel用于接收各种监控信息:
创建Channel
Monitoring
Slack的强大之处在于在Channel中添加各种第三方服务的集成,用户也可以基于Slack开发自己的聊天机器人来实现一些更高级的能力,例如自动化运维,提高开发效率等。
为了能够在Monitoring中接收来自Alertmanager的消息,我们需要在Channel的设置选项中使用"AddanApp"为Monitoringchannel添加一个名为IncomingWebHooks的应用:
添加IncommingWebhooks
添加成功后Slack会显示IncomingWebHooks配置和使用方式:
IncommingWebhhook配置
IncommingWebhook的工作方式很简单,Slack为当前Channel创建了一个用于接收消息的API地址:
测试消息
除了发送纯文本以外,slack还支持在文本内容中添加链接,例如:
例如,使用以上参数发送一条更有趣的消息:
自定义消息
在了解了Slack以及IncommingWebhhook的基本使用方式后,在Alertmanager中添加Slack支持就非常简单了。
在Alertmanager的全局配置中,将IncommingWebhhook地址作为slack_api_url添加到全局配置中即可:
receivers:-name:slackslack_configs:-channel:'#monitoring'send_resolved:true这里如果我们手动拉高当前主机的CPU利用率,在#Monitoring平台中,我们会接收到一条告警信息如下所示:
告警信息
而当告警项恢复正常后,则可以接收到如下通知:
告警恢复信息
对于IncommingWebhhook支持的其它自定义参数,也可以在slack_config中进行定义,slack_config的主要配置如下:
channel:
color:'{{ifeq.Status"firing"}}danger{{else}}good{{end}}'
告警
1.企业ID获取
2.部门ID获取
在通讯录中,添加一个子部门,用于接收告警信息,后面把人加到该部门,这个人就能接收到告警信息了。
可以看到部门id为2
3.告警AgentId和Secret获取
点击这个应用,可以看到我们想要的AgentId和Secret
以上步骤完成后,我们就得到了配置Alertmanager的所有信息,包括:企业ID,AgentId,Secret和接收告警的部门id
4.配置Alertmanager服务
主配置文件
对应配置文件中message字段引用。
通过钉钉客户端(如:桌面或者手机)进入到群设置后选择“群机器人”。将显示如下界面:
群机器人
选择“自定义机器人”,并且按照提示填写机器人名称,获取机器人webhook地址,如下所示:
获取webhook地址
webhook机器人创建成功后,用户就可以使用任何方式向该地址发起HTTPPOST请求,即可实现向该群主发送消息。目前自定义机器人支持文本(text),连接(link),markdown三种消息类型。
但是由于使用钉钉的方式是使用基于webhook的方式来扩展的,所以直接把告警消息发送到钉钉告警机器人做不到,所以需要一个转换器.
首先有两种转换器,第一种,别人开发好的,但是消息不好自定义,另一种是自己写的,告警格式可以自定义.
首先讲解github上面的项目,优点是拿过来就可以用,缺点是消息无法自定义.
二进制部署
docker部署
alert配置
自定义是本人使用python的flask框架自己写的,可以自定义告警格式,以下就贴出代码
第一种,基于模板字符串。用户可以直接在Alertmanager的配置文件中使用模板字符串,例如:
#Filesfromwhichcustomnotificationtemplatedefinitionsareread.#Thelastcomponentmayuseawildcardmatcher,e.g.'templates/*.tmpl'.templates:[-
receivers:-name:'slack-notifications'slack_configs:-channel:'#alerts'text:'{{template"slack.myorg.text".}}'templates:-'/etc/alertmanager/templates/myorg.tmpl'
Alertmanager提供了方式可以帮助用户控制告警通知的行为,包括预先定义的抑制机制和临时定义的静默规则。
Alertmanager的抑制机制可以避免当某种问题告警产生之后用户接收到大量由此问题导致的一系列的其它告警通知。例如当集群不可用时,用户可能只希望接收到一条告警,告诉他这时候集群出现了问题,而不是大量的如集群中的应用异常、中间件服务异常的告警通知。
在Alertmanager配置文件中,使用inhibit_rules定义一组告警的抑制规则:
inhibit_rules:[-
target_match:[
例如,定义如下抑制规则:
-source_match:alertname:NodeDownseverity:criticaltarget_match:severity:criticalequal:-node例如当集群中的某一个主机节点异常宕机导致告警NodeDown被触发,同时在告警规则中定义了告警级别severity=critical。由于主机异常宕机,该主机上部署的所有服务,中间件会不可用并触发报警。根据抑制规则的定义,如果有新的告警级别为severity=critical,并且告警中标签node的值与NodeDown告警的相同,则说明新的告警是由NodeDown导致的,则启动抑制机制停止向接收器发送通知。
除了基于抑制机制可以控制告警通知的行为以外,用户或者管理员还可以直接通过Alertmanager的UI临时屏蔽特定的告警通知。通过定义标签的匹配规则(字符串或者正则表达式),如果新的告警通知满足静默规则的设置,则停止向receiver发送通知。
进入AlertmanagerUI,点击"NewSilence"显示如下内容:
创建静默规则
通过"PreviewAlerts"可以查看预览当前匹配规则匹配到的告警信息。静默规则创建成功后,Alertmanager会开始加载该规则并且设置状态为Pending,当规则生效后则进行到Active状态。
活动的静默规则
当静默规则生效以后,从Alertmanager的Alerts页面下用户将不会看到该规则匹配到的告警信息。
对于已经生效的规则,用户可以通过手动点击”Expire“按钮使当前规则过期。
通过PromQL可以实时对Prometheus中采集到的样本数据进行查询,聚合以及其它各种运算操作。而在某些PromQL较为复杂且计算量较大时,直接使用PromQL可能会导致Prometheus响应超时的情况。这时需要一种能够类似于后台批处理的机制能够在后台完成这些复杂运算的计算,对于使用者而言只需要查询这些运算结果即可。Prometheus通过RecodingRule规则支持这种后台计算的方式,可以实现对复杂查询的性能优化,提高查询效率。
在Prometheus配置文件中,通过rule_files定义recodingrule规则文件的访问路径。
rule_files:[-
groups:[-
#Thenameofthegroup.Mustbeuniquewithinafile.name:
这些规则文件的计算频率与告警规则计算频率一致,都通过global.evaluation_interval定义: