prometheus学习笔记
Posted chaijowin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了prometheus学习笔记相关的知识,希望对你有一定的参考价值。
目录
PromQL 1
聚合运算: 1
二元运算: 2
向量匹配: 3
service_discovery(文件|DNS|consule) 6
重新打标签 7
grafana 19
PromQL
聚合运算:
一般,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标,这种联合机制即聚合操作,如将计数、求和、平均值、分位数、标准差、方差等统计函数应用于时间序列的样本之上生成具有统计学意义的结果等;
对查询结果事先按某种分类机制进行groupby分组,并将查询结果按组进行聚合计算是常见的需求,如分组统计、分组求平均值、分组求和等;
聚合操作由聚合函数针对一组值进行计算并返回单个值或少量几个值作为结果;
prometheus内置提供的11个聚合函数也称为聚合运算符,这些运算符仅支持应用于单个即时向量的元素,其返回值也是具有少量元素的新向量或标量,这些聚合运算符既可以基于向量表达式返回结果中的时间序列的所有标签维度进行分组聚合,也可仅基于指定的标签维度分组后再进行分组聚合;
聚合函数仅用于即时向量;
聚合表达式:
PromQL中的聚合操作语法格式可采用2种格式之一:
<aggr-op>([parameter,] <vector expression>) [without | by (<label list>)]
<aggr-op> [without | by (<label list>)] ([parameter,] <vector expression>)
分组聚合:先分组,后聚合;
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_totalnodename=~”monitor01”,mode=”user”[1m])/60)获取实例在1min内user在所有cpu上的使用百分比之和;
avg(),对样本值求平均值,这是进行指标数据分析的标准方法;
count(),对分组内的时间序列进行数量统计;该函数用于进行统计,或用来做一些模糊判断,如判断服务器连接数大于某个值,为真则返回1否则返回null,如count(node_cpu_seconds_totalnodename=~”monitor01”,mode=”idle”)统计vCPU数,如count(node_netstat_Tcp_CurrEstabnodename=~”monitor01”>200)统计当前tcp建立连接数是否>200;
stddev(),对样本值求标准差,以帮助用户了解数据的波动大小(或波动程度);
stdvar(),对样本值求方差,它是求取标准差过程中的中间状态;
min(),求样本值中的最小值;
max(),求样本值中的最大值;
topk(),逆序返回分组内的样本值最大的前k个时间序列及其值;该函数可从大量数据中取出排行前N的数值,N可自定义,如topk(3, rate(node_network_receive_bytes_totaldevice=~”ens.*”[5m]))或用topk(3, increase(node_network_receive_bytes_totaldevice=~”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多对一或一对多;
向量一对一匹配:
即时向量一对一匹配,从运算符的两边表达式所获取的即时向量间依次比较,并找到唯一匹配(标签完全一致)的样本值,找不到匹配项的值则不会出现在结果中;
匹配表达式语法:
<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>
ignoring,定义匹配检测时要忽略的标签;
on,定义匹配检测时只使用的标签;
如rate(http_requests_totalstatus_code=~"5.*"[5m]) > 0.1*rate(http_request_total[5m])
左侧会生成一个即时向量,它计算出5xx响应码的各类请求的增长率,除status_code标签外,该指标通常还有其它标签,于是status_code的值为500的标签同其它标签的每个组合将代表一个时间序列,其相应的即时样本即为结果向量的一个元素;
右侧会生成一个即时向量,它计算出所有标签组合所代表的各类请求的增长速率;
计算时,PromQL会在操作符左右两侧的结果元素中找到标签完全一致的元素进行比较;
其意义为,计算出每类请求中的500响应码在该类请求中所占的比例;
ignore类似黑名单;
on白名单;
向量一对多|多对一匹配:
一侧的每个元素,可与多侧的多个元素进行匹配;
必须使用group_left或group_right明确指定哪侧为多侧;
匹配表达式语法:
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) grou_right(<label list>) <vector 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支持使用协议http或https|target的地址|target的uri路径,这些目标列表和标签会返回给prometheus,其中的一些标签也可在配置中被覆盖;
配置标签会在抓取的生命周期中被重复利用以生成其他标签,如指标上的instance标签的默认值就来自于__address__标签的值;
relabel_configs给target重新打标;
metric_relabel_configs给metric重新打标;
不能动态改标签;
蓝色的为重新打标后的标签;
对于发现的各目标,prometheus提供了可以relabel重新标记目标的机会,它定义在job配置段的relabel_config配置中,常用于实现:将来自服务发现的元数据标签中的信息附加到指标的标签上;过滤目标;
这之后,便是数据抓取、及指标返回的过程;
抓取而来的指标在保存之前,还允许用户对指标重新打标并过滤的方式,它定义在job配置段的metric_relabel_configs配置中,常用于实现:删除不必要的指标;从指标中删除敏感或不需要的标签;添加、编辑或修改指标的标签值或标签格式;
对target重新打标:
是在数据抓取之前动态重写target标签的强大工具,在每个数据抓取配置中,可定义多个relabel步骤,它们将按定义的顺序依次执行;
对于发现的每个target,prometheus默认会执行如下操作:
job的标签设定为其所属的job_name的值;
__address__标签的值为该target的套接字地址host:port;
instance标签的值为__address__的值;
__scheme__标签的值为抓取该target上指标时使用的协议http|https;
__metrics_path__标签的值为抓取该target上的指标时使用uri路径,默认为/metrics;
__param_<name>标签的值为传递的url参数中第一个名称为<name>的参数的值;
重新标记完成后,该target上以__开头的所有标签都会被移除,若在relabel过程中需要临时存储标签值,则要使用__tmp标签名为前缀进行保存,以避免同prometheus的内建标签冲突;
source_labels,源标签,已有标签;
separator,源标签若为多个,默认用分号串连;
regex,用正则匹配串连的源标签,符合条件的赋值给target_label;
action,默认replace;
action字段用于定义重新标记的行为,其可用取值有:
替换标签值(replace|hashmod)、删除指标(keep|drop)、创建或删除标签(labelmap|labeldrop|labelkeep);
替换标签值:
replace,首先将source_labels中指定的各标签的值进行串连,而后将regex字段中的正则表达式对源标签值进行匹配判定,若匹配则将target_label字段中指定的标签的值替换为replacement字段中保存的值,replacement可按需引用保存regex中的某个分组模式匹配到的值,默认保存整个regex匹配到的内容,进行值替换时,replacement字段中指定标签的值也支持以分组格式进行引用;
hashmod,将target_label的值设置为一个hash值,该hash由modules字段指定的hash模块对soruce_labels上各标签的串连值进行hash计算生成;
删除指标(该处的每个指标名称对应一个target):
keep,regex不能匹配到target上的source_labels上的各标签的串连值时,则删除该target;
drop,regex能够匹配到target上的source_labels上的各标签的串连值时,则删除该target;
创建或删除标签:
labelmap,将regex对所有的标签名进行匹配判定,而后将匹配到的标签的值赋给replacement字段指定的标签名之上,通常用于取出匹配的标签名的一部分生成新标签;
labeldrop,将regex对所有的标签名进行匹配判定,能够匹配到的标签将从该target的标签集中删除;
labelkeep,将regex对所有的标签名进行匹配判定,不能匹配到的标签将从该taget的标签集中删除;
要确保在labeldrop|labelkeep操作后,余下的标签集依然能唯一标识该指标;
例:
将3个源标签的值按顺序串联后,由指定的正则进行模式匹配,而后由replacement引用模式匹配的结果,并加以改造后,将其赋值给endpoint标签,endpoint="http://localhost:9100/metrics";
- job_name: nodes
file_fd_config:
- files:
- targets/prometheus/node*.yaml
replace_configs:
- source_labels:
- __scheme__
- __address__
- __metric_path__
regex: "(http|https)(.*)"
seperator: ""
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为前缀的指标;
基于文件的服务发现
http://gitlab.magedu.com/MageEdu
/usr/local/prometheus/files-sd/prometheus.yml,targets/nodes-linux.yml,prometheus-servers.yml
./prometheus --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
http://172.29.1.11:8500/ui/
consul 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的服务发现
https://github.com/kubernetes/kube-state-metrics
grafana
yum -y install grafana-7.3.7-1.x86_64.rpm
rpm -ql grafana # /etc/grafana/grafana.ini
systemctl start grafana-server # 3000port admin/admin
https://grafana.com/grafana/dashboards # 导入别人写好的面板,只用填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的告警,最后合并为一个通知发送;以上是关于prometheus学习笔记的主要内容,如果未能解决你的问题,请参考以下文章
企业运维实战-k8s学习笔记17.k8s集群+Prometheus监控部署基于prometheus实现k8s集群的hpa动态伸缩虚拟机部署prometheus监控