app开发者平台在数字化时代的重要性与发展趋势解析
1167
2022-08-30
prometheus学习笔记(2)
目录
PromQL 1
聚合运算: 1
二元运算: 2
向量匹配: 3
service_discovery(文件|DNS|consule) 6
重新打标签 7
对target重新打标: 8
对抓取到的metric重新打标: 11
基于文件的服务发现 12
基于DNS的服务发现 13
基于consul的服务发现 14
基于kubernetesAPI的服务发现 16
grafana 19
alertmanager 21
PromQL
聚合运算:
一般,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标,这种联合机制即聚合操作,如将计数、求和、平均值、分位数、标准差、方差等统计函数应用于时间序列的样本之上生成具有统计学意义的结果等;
对查询结果事先按某种分类机制进行groupby分组,并将查询结果按组进行聚合计算是常见的需求,如分组统计、分组求平均值、分组求和等;
聚合操作由聚合函数针对一组值进行计算并返回单个值或少量几个值作为结果;
prometheus内置提供的11个聚合函数也称为聚合运算符,这些运算符仅支持应用于单个即时向量的元素,其返回值也是具有少量元素的新向量或标量,这些聚合运算符既可以基于向量表达式返回结果中的时间序列的所有标签维度进行分组聚合,也可仅基于指定的标签维度分组后再进行分组聚合;
聚合函数仅用于即时向量;
聚合表达式:
PromQL中的聚合操作语法格式可采用2种格式之一:
分组聚合:先分组,后聚合;
without,从结果向量中删除由without子句指定的标签,未指定的那部分标签则用作分组标准;
by,功能与without刚好相反,它仅使用by子句中指定的标签进行聚合,结果向量中出现但未被by子句指定的标签则会被忽略,为保留上下文信息使用by子句时需要显式指定其结果中原本出现的job|instance等一类标签;
事实上,各函数工作机制的不同之处在仅在于计算操作本身,PromQL对于它们的执行逻辑相似;
aggr-op操作符即sum|avg|count等;
by以指定的标签进行聚合,without除指定的标签外以剩余的标签进行聚合;
11个聚合函数:
sum(),对样本值求和;在实际工作中cpu大多是多核心,而node_cpu_seconds_total会将每个核的数据都单独显示出来,但我们关心的是cpu总的使用情况,因此使用此函数求和后得出一条总的数据,如sum(increase(node_cpu_seconds_total{nodename=~”monitor01”,mode=”user”}[1m])/60)获取实例在1min内user在所有cpu上的使用百分比之和;
avg(),对样本值求平均值,这是进行指标数据分析的标准方法;
count(),对分组内的时间序列进行数量统计;该函数用于进行统计,或用来做一些模糊判断,如判断服务器连接数大于某个值,为真则返回1否则返回null,如count(node_cpu_seconds_total{nodename=~”monitor01”,mode=”idle”})统计vCPU数,如count(node_netstat_Tcp_CurrEstab{nodename=~”monitor01”}>200)统计当前tcp建立连接数是否>200;
stddev(),对样本值求标准差,以帮助用户了解数据的波动大小(或波动程度);
stdvar(),对样本值求方差,它是求取标准差过程中的中间状态;
min(),求样本值中的最小值;
max(),求样本值中的最大值;
topk(),逆序返回分组内的样本值最大的前k个时间序列及其值;该函数可从大量数据中取出排行前N的数值,N可自定义,如topk(3, rate(node_network_receive_bytes_total{device=~”ens.*”}[5m]))或用topk(3, increase(node_network_receive_bytes_total{device=~”ens.*”}[5m])/300),如topk(3, increase(node_netstat_Tcp_CurrEstab))从所有主机中找出连接数前3的主机(Gauge类型数据);
bottomk(),顺序返回分组内的样本值最小的前k个时间序列及其值;
quantile(),分位数用于评估数据的分布状态,该函数会返回分组内指定的分位数的值,即数值落在<=指定的分位区间的比例;
count_values(),对分组内的时间序列的样本值进行数量统计;
二元运算:
binary operators二元运算符:
PromQL支持基本的自述运算和逻辑运算,这类运算支持使用操作符连接 两个操作数,因而也称二元运算符或二元操作符;
支持的运算,两个标量间运算,即时向量和标量间的运算(将运算符应用于向量上的每个样本),两个即时向量间的运算(遵循向量匹配机制);
将运算符用于两个即时向量间的运算时,可基于vector matching向量匹配模式定义其运算机制;
算术运算,+-*/%^;
比较运算,==|!=|>|<|>=|<=;
逻辑|集合运算,and|or|unless除了,目前这些仅允许在2个即时向量间进行,不支持标量间参与运算;
优先级:
prometheus的复杂运算中,二元运算符存在如下给定次序中所示的由高到低的优先级:
^
*/%
+-
==|!=|<=|<|>=|>
and|unless
or
具有想同优先级的运算符满足结合律(左结合),但幂运算除外,因为它是右结合机制;
可使用()改变运算次序;
向量匹配:
即时向量间的运算是PromQL的特色之一,运算时,PromQL会为左侧向量中的每个元素找到匹配的元素,其匹配行为有2种基本类型:
one-to-one一对一;
many-to-one|one-to-many多对一或一对多;
向量一对一匹配:
即时向量一对一匹配,从运算符的两边表达式所获取的即时向量间依次比较,并找到唯一匹配(标签完全一致)的样本值,找不到匹配项的值则不会出现在结果中;
匹配表达式语法:
ignoring,定义匹配检测时要忽略的标签;
on,定义匹配检测时只使用的标签;
如rate(> 0.1*rate(expr>
PromQL的解析过程:
PromQL的表达式是一段文本,prometheus会解析这段文本,将它转化为一个结构化的语法树对象,进而实现相应的数据计算逻辑;
调用prometheus restful api查询表达式计算工作流如图;
请求数据的时候给出的step参数就是interval,它设定结果中相领2个点的间隔,对PromQL的每次evaluation都是针对某个确定的时间点和statement来计算的,得到一个vector(时间戳相同的向量);
prometheus可将异构(时间戳不一致)的多维时间序列经过计算转化为同构(时间戳一致)的多维时间序列;
service_discovery(文件|DNS|consule)
静态配置方式:
默认会在target后自动加/metrics获取指标监控数据,如果不是/metrics得用metrics_path指定;
变动很小才用此种,这种方式是prmetheus最不希望看到的;
prometheus为何要进行服务发现?
prometheus server的数据抓取工作是pull模型,因而它必须事先知道各target的位置,然后才能从相应的exporter或instrumentation中抓取数据;
对于小型系统环境,通过static_config指定各target便能解决问题,这也是最简单的配置方法,每个target用一个网络端点ip:port进行标识;
对于中大型系统环境或具有较强动态性的云计算环境来说,静态配置显然难以适用,因此,prometheus为此专门设计了一组服务发现机制,以便于能够基于服务注册中心(服务总线)自动发现、检测、分类可被监控的各target,及更新发生了变动的target;
prometheus可集成的服务发现机制?
不同场景中,服务注册中心的指代也会有所不同:
公有或私有IaaS云自身保存有平台上的所有资源信息,其API server便可作为prometheus的服务发现媒介,azure|ec2|digitalocean|gce|hetzner;
prometheus也可集成到多种不同的开源服务发现工具上,以动态发现需要监控的目标,consul|Eureka Zookeeper Serverset|Airbnb Nerve等;
prometheus也可以很好地集成到kubernetes平台上,通过其api server动态发现各类被监控的pod容器集、service、endpoint、ingress、node对象,它也支持基于dockerswarm|marathon两款编排工具进行服务发现;
prometheus还支持基于DNS或文件的动态发现机制;
重新打标签
重新打标至关重要;
指标抓取的生命周期:
服务发现-->配置-->relabel_config重新标记-->抓取-->metric_relabel_configs重新标记;
在每个scrape_interval期间,prometheus都会检查执行的job;
这些作业首先会根据job上指定的发现配置生成target列表,此即服务发现过程,服务发现会返回一个target列表,其中包含一组称为元数据的标签,这些标签都以__meta__为前缀,服务发现还会根据目标配置来设置其它标签,这些标签都带有__前缀和后缀,包括__scheme__|__address__|__metric_path__,分别保存target支持使用协议job_name: 'nodes'
file_fd_config:
- files:
- targets/prometheus/node*.yaml
replace_configs:
- source_labels:
- __scheme__
- __address__
- __metric_path__
regex: "(""
target_label: "endpoint"
replacement: "${1}://${2}"
action: replace
例:
将regex指定的模式对target上的所有标签进行匹配判定,对于匹配到的标签名,它将以该标签名中匹配的部分为前缀,指定的_name为后缀生成新的标签名,而新标签的值与其原标签的值相同,job="nodes", job_name="nodes";
- job_name: 'nodes'
file_sd_configs:
- files:
- targets/prometheus/node*.yaml
relabel_configs:
- regex: "(job|app)"
replacement: ${1}_name
action: labelmap
对抓取到的metric重新打标:
对metric重新打标是在数据抓取之后动态重写metric标签的工具,在每个数据抓取配置中,可以定义多个metric relabel的步骤,它们将按定义的顺序依次执行,删除不必要的指标|从指标中删除敏感或不需要的标签|添加编辑修改指标的标签值或标签格式;
对metric重新打标(定义在metric_relabel_configs字段中)的配置格式与target重新打标(定义在relabel_configs字段中)的格式相同;
注意1,更改或添加标签会创建新的时间序列,应该明确地使用各个标签,并尽可能保持不变,以避免创建出一个动态的数据环境;
注意2,标签是时间序列的唯一性约束,删除标签并导致时间序列重复时,可能会导致系统出现问题;
例,删除go_info版本信息:
在source_labels字段上,通过指标上元标签__name__引用指标名称,而后由regex进行匹配判定,可使用drop删除匹配的指标或使用keep保留匹配的指标;
该示例用在job上,在发现的各target之上删除以go_info为前缀的指标;
基于文件的服务发现
--config.file=./file-sd/prometheus.yml
基于DNS的服务发现
基于/etc/resolve.conf中配置的NS;
基于consul的服务发现
consul默认8500;
unzip consul_1.9.2_linux_adm64.zip -d /usr/local/bin
consul --help
/etc/consul/{nodes.json,prometheus-servers.json} # 单个service多个services,生产中不用文件配置这种方式而是用consulAPI接口
consul agent -dev -ui -data-dir=/consul/data/ -config-dir=/etc/consul -client=0.0.0.0
reload
consul services deregister -id="node_exporter-node02"
consule services register /etc/consul/nodes.json
/usr/local/prometheus/consul-sd/prometheus.yml
./prometheus --config.file=.consul-sd/prometheus.yml
基于kubernetesAPI的服务发现
-y install grafana-7.3.7-1.x86_64.rpm
rpm -ql grafana # /etc/grafana/grafana.ini
systemctl start grafana-server # 3000port admin/admin
# 导入别人写好的面板,只用填id导入即可
alertmanager
prometheus对指标的收集、存储在prometheus server上,告警能力在AlertManager上,两者是独立的组件,前者仅负责基于告警规则生成告警通知,具体的告警操作则由后者完成;
alertmanager负责处理由客户端发来的告警通知,客户端通常是prometheus server,但它也支持接收来自其它工具的告警,alertmanager对告警通知进行分组、去重后,根据路由规则将其路由到不同的receiver,如email|sms|pagerduty等;
prometheus监控系统的告警逻辑:
首先要配置prometheus成为alertmanager的告警客户端,反过来alertmanager也是应用程序,它自身同样应该纳入prometheus的监控目标;
配置逻辑:
在alertmanager上定义receiver,他们通常是能够基于某个媒介接收告警消息的特定用户,email|wechat|pagerduty|slack|webhook等为常见的发送告警信息的媒介,在不同的媒介上,代表告警消息接收人的地址表示方式也会有所不同;
在alertmanager上定义route路由规则,以便将收到的告警通知按需分别进行处理;
在prometheus上定义告警规则生成告警通知,发送给alertmanager;
alertmanager
除基本的告警通知能力外,altermanager还支持对告警进行deduplicating去重、grouping分组、inhibition抑制、silencing静默、aggregation聚合、最终通过email|webhook等方式将告警通知route路由给对应的联系人;
grouping分组,将相似告警合并为单个告警通知的机制,在系统因大面积故障而触发告警潮时,分组机制能避免用户被大量的告警噪声淹没,进而导致关键信息的隐没(将具有相同性质的告警先分类,然后当作单个通知发送出来,比如A和B两台主机的磁盘使用率都在告警,则磁盘的告警就可以合并在一个通知中发送出来,可以想像某个服务部署了100个节点,在一次升级后因为bug日志中均报同样一类错误,如果不合并这类通知就是报警风暴);
inhibition抑制,系统中某个组件或服务故障而触发告警通知后,那些依赖于该组件或服务的其它组件或服务可能也会因此而触发告警,抑制便是避免类似的级联告警的一种特性,从而让用户能将精力集中于真正的故障所在(某些告警触发后,则抑制(禁止)另一些告警,如收到一条告警提示集群故障无法访问,那么在该集群上的所有其它告警应该被抑制);
silent静默,指在一个特定的时间窗口内,即便接收到告警通知,alertmanager也不会真正向用户发送告警信息的行为,通常在系统例行维护期间,需要激活告警系统的静默特性;
route路由,用于配置alertmanager如何处理传入的特定类型的告警通知,其基本逻辑是根据路由匹配规则的匹配结果来确定处理当前告警通知的路径和行为(将某些预期内的告警设置为静音(即不发送告警),静默是基于配置匹配规则,alertmanager会检查从prometheus推送过来的告警事件,看这些告警事件是否与配置的静默规则能匹配上,如果匹配则不发送任何通知,配置静默方法是在alertmanager的web界面中(小喇叭),也可使用amtool工具);
总之,alertmanager制定这一系列规则目的只有一个,提高告警质量;
抑制,只发一次不重发,告警收敛;
静默,维护时间不发;
部署alertmanager
alertmanager是一个独立的go二进制程序,需要独立部署及维护;
tar xf alertmanager-0.21.0.linux-amd64.tar.gz -C /usr/local/
ln -sv alertmanager-0.21.0.linux-amd64/ alertmanager
默认监听9093,9094内部集群使用的端口;
配置:
alertmanager的配置文件遵循yaml格式;
通常给予一个如下的基础配置即可启动,示例中仅定义了基本的路由信息(默认路由),注意安装postfix服务;
global段,全局配置,主要配置告警方式,如email|webhook等;
templates段,负责定义告警模板文件;
route段,prometheus的告警先到达aletmanager的根路由,根路由不能包含任何匹配项(因为根路由是所有告警的入口点),根路由需要配置一个receiver接收器用来处理那些没有匹配到任何子路由的告警(如果没有配置子路由,则全部由根路由发送告警);route用于指定如何处理传入的告警,支持定义树状路由表,入口位置称为根节点,每个子节点可基于匹配条件定义出一个独立的路由分支,所有告警都将进入路由根节点而后进行子节点遍历,若路由上的continue字段值为false则遇到第一个匹配的路由分支后即终止,否则将继续匹配后续的子节点;
receiver段,定义了告警信息的接收器,每个接收器都应该有具体的定义;
route段指令:
group_by,用于分组聚合,对告警通知按label标签进行分组,将具有相同标签或相同alertname告警名称的告警通知聚合在一个组作为一个通知发送,如果想完全禁用聚合设置为group_by: [...];
group_wait,当一个新的告警组被创建时,需要等待group_wait后才发送初始通知,这样可确保在发送等待前能收集更多具有相同label的告警,最后合并为一个通知发送;
group_interval,当第一次告警通知发出后,等待group_interval时间后,开始发送为该组触发的新告警,可理解为group就相当于一个channel通道;
repeat_interval,告警通知成功发送后,若问题一起未恢复,需再次重复发送的间隔;
prometheus.io/webtools/alerting/routing-tree-editor/ # 查看配置的告警路由树,将alertmanager.yml内容复制到该对话框点Draw Routing Tree
alertmanager样例:
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.163.com:465'
smtp_from: 'src@163.com'
smtp_auth_username: 'src@163.com'
smtp_auth_password: 'xxxxx'
smtp_require_tls: false
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 30s
repeat_interval: 10m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'dest@163.com'
inhibit_rules: # 当critical和waring同时出现时抑制warning告警
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
prometheus样例:
global:
scrape_insterval: 15s
多久查一次记录规则
scrape_timeout: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- 127.0.0.1:9093
rule_files:
记录规则(生成新的时间序列,用于不能直接查出所要的值,需要单独统计或计算才有结果,如cpu利用率需要计算出结果才能用,此处规则可在页面查询)
告警规则
./promtool check config prometheus.yml
curl -XPOST /usr/local/alertmanager/alertmanager.yml
global:
resolve_timeout: 5m异常解决的时间
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 10s
receiver: 'email-me'
receivers:
- name: 'email-me'
email_configs:
- to: 'devops@magedu.com'
from: 'devops@magedu.com'
smarthost: 'smtp.exmail.qq.com:465'
auth_username: 'devops@magedu.com'
auth_identity: 'devops@magedu.com'
auth_password: 'Mage123'
require_tls: false
cd /usr/local/alertmanager/
./alertmanager
组合prometheus与alertmanager
调用alertmanager实例的配置信息定义在顶级的alerting配置段中,它同样支持静态配置和动态发现,其配置方式类似于被监控的target的定义;
添加告警规则:
vim /usr/local/prometheus/alert-config-1/prometheus.yml
# Alertmanager configuration
alerting:
alertmanagers:
- file_sd_configs:
- files:
- "targets/alertmanagers*.yaml"
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "rules/*.yaml"
- "alert_rules/*.yaml" 根据配置,当前目录下alert_rules目录下的所有文件均被识别为告警规则
vim /usr/local/prometheus/alert-config-1/alert_rules/instance_down.yaml # 另可基于记录规则生成告警规则;
groups:
- name: AllInstances
rules:
- alert: InstanceDown
# Condition for alerting
expr: up == 0 # 1up 0down
for: 1m
# Annotation - additional informational labels to store more information
annotations:
title: 'Instance down'
description: Instance has been down for more than 1 minute.'
# Labels - additional labels to be attached to the alert
labels:
severity: 'critical'
cd /usr/local/prometheus
./prometheus --config.file=./alert-config-1/prometheus.yml
告警模板:
prometheus支持在告警中使用模板;
告警模板是指在告警中的标签和注解上引用时间序列的标签和样本值的方法,使用标签的go语法,并暴露一些包含时间标签和值的变量,标签引用{{$label.
若要在description注解中引用触发告警的时间序列上的instance和job标签的值,可分别使用{{$label.instance}}和{{$label.job}},如可以把告警规则改为如下:
alertmanager上的告警信息
告警被触发后,便可在alertmanager的webUI上看到相关信息,且将信息发送到目标端;
告警抑制:
inhibition机制可以避免当某种问题告警产生后,用户连续接收到大量的由此问题导致的告警通知;
在有新的告警通知匹配到target_match和target_match_re规则时,若存在已经发送的告警通知满足source_match或source_match_re的匹配条件,且已发送的告警与新的告警中由equal定义的标签完全相同,则启动抑制机制,新的告警不会发送;
global:
resolve_timeout: 5m
route:
#group_by: ['alertname']
#group_wait: 30s
#group_interval: 30s
repeat_interval: 10s
receiver: 'email-me'
receivers:
- name: 'email-me'
email_configs:
- to: 'devops@magedu.com'
from: 'devops@magedu.com'
smarthost: 'smtp.exmail.qq.com:465'
auth_username: 'devops@magedu.com'
auth_identity: 'devops@magedu.com'
auth_password: 'Mage123'
require_tls: false
inhibit_rules:
- source_match:
alertname: InstanceDown
severity: critical
target_match:
alertname: InstanceDown
severity: critical
equal:
- instance
https://github.com/timonwong/prometheus-webhook-dingtalk/
alertmanager痛点:
无法动态加载监控规则,需要修改配置文件;
在使用时,需要修改prometheus的配置文件将altermanager与prometheus相关联;
无法实现报警升级,不支持获取动态值班组,标签匹配不能动态配置(需要修改配置文件);
总而言之,配置不够灵活,需要频繁修改配置文件,学习成本高;
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~