首页 >> 大全

Prometheus “活学活用”,大牛总结了一套避坑指南

2023-08-31 大全 48 作者:考证青年

监控系统的历史悠久,是一个很成熟的方向,而 作为新生代的开源监控系统,慢慢成为了云原生体系的事实标准,也证明了其设计很受欢迎。

本文主要分享在 实践中遇到的一些问题和思考,如果你对 K8S 监控体系或 的设计还不太了解,可以先看下容器监控系列。

容器监控系列:

几点原则

的局限

K8S 集群中常用的 一级标题

属于 CNCF 项目,拥有完整的开源生态,与 这种传统 agent 监控不同,它提供了丰富的 来满足你的各种需求。

你可以在这里看到官方、非官方的 。如果还是没满足你的需求,你还可以自己编写 ,简单方便、自由开放,这是优点。

但是过于开放就会带来选型、试错成本。之前只需要在 agent里面几行配置就能完成的事,现在你会需要很多 搭配才能完成。还要对所有 维护、监控。尤其是升级 版本时,很痛苦。非官方 还会有不少 bug。这是使用上的不足,当然也是 的设计原则。

K8S 生态的组件都会提供/接口以提供自监控,这里列下我们正在使用的:

: kube-state-:

node-:

还有各种场景下的自定义 ,如日志提取后面会再做介绍。

自定义 :

K8S 核心组件监控与 面板

k8s 集群运行中需要关注核心组件的状态、性能。如 、 等,基于上面提到的 的指标,可以在 中绘制如下图表:

模板可以参考-for--,根据运行情况不断调整报警阈值。

-for--:

这里提一下 虽然支持了 能力,可以很方便地做多级下拉框选择,但是不支持 模式下配置报警规则,相关issue

issue:

官方对这个功能解释了一堆,可最新版本仍然没有支持。借用 issue 的一句话吐槽下:

关于 的基础用法,可以看看《容器监控实践—》。

容器监控实践—:

采集组件 All IN One

体系中 都是独立的,每个组件各司其职,如机器资源用 Node-,Gpu 有 等等。但是 越多,运维压力越大,尤其是对 Agent做资源控制、版本升级。我们尝试对一些进行组合,方案有二:

另外,Node- 不支持进程监控,可以加一个-,也可以用上边提到的,使用 的 input来采集进程指标。

合理选择黄金指标

采集的指标有很多,我们应该关注哪些? 在“Sre ”中提出了“四个黄金信号”:延迟、流量、错误数、饱和度。实际操作中可以使用 Use 或 Red 方法作为指导,Use 用于资源,Red 用于服务。

采集中常见的服务分三种:

对 Use 和 Red 的实际示例可以参考容器监控实践—K8S常用指标分析这篇文章。

容器监控实践—K8S常用指标分析:

K8S 1.16中 的指标兼容问题

在 K8S 1.16版本, 的指标去掉了 和 的 label,替换为了pod 和 。如果你之前用这两个 label 做查询或者 绘图,需要更改下 Sql 了。因为我们一直支持多个 K8S 版本,就通过 配置继续保留了原来的**_name。

注意要用 gs,不是 ,采集后做的。

采集外部K8S集群、多集群

如果部署在K8S集群内采集是很方便的,用官方给的Yaml就可以,但我们因为权限和网络需要部署在集群外,二进制运行,采集多个 K8S 集群。

以 Pod 方式运行在集群内是不需要证书的(In- 模式),但集群外需要声明 token之类的证书,并替换,即使用 Proxy采集,以 采集为例,Job 配置为:

需要提前生成,这个参考官方文档即可。记得 解码。

对于 来说,可以转换为/api/v1/nodes/${1}/proxy//,代表 proxy 到 ,如果网络能通,其实也可以直接把 的10255作为 ,可以直接写为:

${1}:10255//,代表直接请求,规模大的时候还减轻了 的压力,即服务发现使用 ,采集不走 。

因为 是暴露主机端口,配置相对简单,如果是 kube-state- 这种 ,以 形式暴露,写法应该是:

对于 类型,需要转换为/api/v1//${1}//${2}:${3}/proxy/,需要替换 、svc 名称端口等,这里的写法只适合接口为/的,如果你的 不是/接口,需要替换这个路径。或者像我们一样统一约束都使用这个地址。

这里的来源就是 部署时写的那个 ,大多数文章中只提到.io/: 'true',但也可以定义端口、路径、协议。以方便在采集时做替换处理。

其他的一些 如 是为了保留原始信息,方便做 查询时的筛选条件。

如果是多集群,同样的配置多写几遍就可以了,一般一个集群可以配置三类job:

GPU 指标的获取

-smi可以查看机器上的 GPU 资源,而 其实暴露了来表示容器使用 GPU 情况,

如果要更详细的 GPU 数据,可以安装dcgm ,不过K8S 1.13 才能支持。

更改 的显示时区

为避免时区混乱,在所有组件中专门使用 Unix Time 和 Utc 进行显示。不支持在配置文件中设置时区,也不能读取本机 /etc/ 时区。

其实这个限制是不影响使用的:

2.16 版本:

修改源码更改的时区问题:

关于 的讨论,可以看这个issue。

issue:

如何采集 LB 后面的 RS 的

假如你有一个负载均衡 LB,但网络上 只能访问到 LB 本身,访问不到后面的 RS,应该如何采集 RS 暴露的 ?

版本的选择

当前最新版本为 2.16, 还在不断迭代,因此尽量用最新版,1.X版本就不用考虑了。

2.16 版本上有一套实验 UI,可以查看 TSDB 的状态,包括Top 10的 Label、。

大内存问题

随着规模变大, 需要的 CPU 和内存都会升高,内存一般先达到瓶颈,这个时候要么加内存,要么集群分片减少单机指标。这里我们先讨论单机版 的内存问题。

原因:

我的指标需要多少内存:

_学点法律避点坑txt_学点法律避点坑txt下载

计算公式:

以我们的一个 为例,本地只保留 2 小时数据,95 万 ,大概占用的内存如下:

有什么优化方案:

内存占用分析:

相关 issue:

容量规划

容量规划除了上边说的内存,还有磁盘存储规划,这和你的 的架构方案有关。

每2小时将已缓冲在内存中的数据压缩到磁盘上的块中。包括、、、,这些占用了一部分存储空间。一般情况下,中存储的每一个样本大概占用1-2字节大小(1.7Byte)。可以通过来查看每个样本平均占用多少空间:

“`bash

rate([1h])

rate(_sum[1h]){="0.0.0.0:8890", job=""}

1.

“`

如果大致估算本地磁盘大小,可以通过以下公式:

保留时间(ds)和样本大小()不变的情况下,如果想减少本地磁盘的容量需求,只能通过减少每秒获取样本数()的方式。

查看当前每秒获取的样本数:

有两种手段,一是减少时间序列的数量,二是增加采集样本的时间间隔。考虑到 会对时间序列进行压缩,因此减少时间序列的数量效果更明显。

举例说明:

以上磁盘容量并没有把 wal 文件算进去,wal 文件(Raw Data)在 官方文档中说明至少会保存3个 Write-Ahead Log Files,每一个最大为128M(实际运行发现数量会更多)。

因为我们使用了 的方案,所以本地磁盘只保留2H 热数据。Wal 每2小时生成一份Block文件,Block文件每2小时上传对象存储,本地磁盘基本没有压力。

关于 存储机制,可以看《容器监控实践—存储机制》。

容器监控实践—存储机制:

对 的性能影响

如果你的 使用了 做服务发现,请求一般会经过集群的 ,随着规模的变大,需要评估下对 性能的影响,尤其是Proxy失败的时候,会导致CPU 升高。当然了,如果单K8S集群规模太大,一般都是拆分集群,不过随时监测下 的进程变化还是有必要的。

在监控、、Kube-Proxy 的 时,我们一开始选择从 Proxy 到节点的对应端口,统一设置比较方便,但后来还是改为了直接拉取节点, 仅做服务发现。

Rate 的计算逻辑

中的 类型主要是为了 Rate 而存在的,即计算速率,单纯的 计数意义不大,因为 一旦重置,总计数就没有意义了。

Rate 会自动处理 重置的问题, 一般都是一直变大的,例如一个 启动,然后崩溃了。本来以每秒大约10的速率递增,但仅运行了半个小时,则速率( [1h])将返回大约每秒5的结果。另外, 的任何减少也会被视为 重置。例如,如果时间序列的值为[5,10,4,6],则将其视为[5,10,14,16]。

Rate 值很少是精确的。由于针对不同目标的抓取发生在不同的时间,因此随着时间的流逝会发生抖动, 计算时很少会与抓取时间完美匹配,并且抓取有可能失败。面对这样的挑战,Rate 的设计必须是健壮的。

Rate 并非想要捕获每个增量,因为有时候增量会丢失,例如实例在抓取间隔中挂掉。如果 的变化速度很慢,例如每小时仅增加几次,则可能会导致【假象】。比如出现一个 时间序列,值为100,Rate 就不知道这些增量是现在的值,还是目标已经运行了好几年并且才刚刚开始返回。

建议将 Rate 计算的范围向量的时间至少设为抓取间隔的四倍。这将确保即使抓取速度缓慢,且发生了一次抓取故障,您也始终可以使用两个样本。此类问题在实践中经常出现,因此保持这种弹性非常重要。例如,对于1分钟的抓取间隔,您可以使用4分钟的 Rate 计算,但是通常将其四舍五入为5分钟。

如果 Rate 的时间区间内有数据缺失,他会基于趋势进行推测,比如:

反直觉的 P95 统计

是 常用的一个函数,比如经常把某个服务的 P95 响应时间来衡量服务质量。不过它到底是什么意思很难解释得清,特别是面向非技术的同学,会遇到很多“灵魂拷问”。

我们常说 P95(P99,P90都可以) 响应延迟是 100ms,实际上是指对于收集到的所有响应延迟,有 5% 的请求大于 100ms,95% 的请求小于 100ms。 里面的 函数接收的是 0-1 之间的小数,将这个小数乘以 100 就能很容易得到对应的百分位数,比如 0.95 就对应着 P95,而且还可以高于百分位数的精度,比如 0.9999。

当你用 画出响应时间的趋势图时,可能会被问:为什么P95大于或小于我的平均值?

正如中位数可能比平均数大也可能比平均数小,P99 比平均值小也是完全有可能的。通常情况下 P99 几乎总是比平均值要大的,但是如果数据分布比较极端,最大的 1% 可能大得离谱从而拉高了平均值。一种可能的例子:

服务 X 由顺序的 A,B 两个步骤完成,其中 X 的 P99 耗时 100Ms,A 过程 P99 耗时 50Ms,那么推测 B 过程的 P99 耗时情况是?

直觉上来看,因为有 X=A+B,所以答案可能是 50Ms,或者至少应该要小于 50Ms。实际上 B 是可以大于 50Ms 的,只要 A 和 B 最大的 1% 不恰好遇到,B 完全可以有很大的 P99:

所以我们从题目唯一能确定的只有 B 的 P99 应该不能超过 100ms,A 的 P99 耗时 50Ms 这个条件其实没啥用。

类似的疑问很多,因此对于 函数,可能会产生反直觉的一些结果,最好的处理办法是不断试验调整你的 的值,保证更多的请求时间落在更细致的区间内,这样的请求时间才有统计意义。

慢查询问题

提供了自定义的 作为查询语句,在 Graph 上调试的时候,会告诉你这条 Sql 的返回时间,如果太慢你就要注意了,可能是你的用法出现了问题。

慢查询:

评估 的整体响应时间,可以用这个默认指标:

一般情况下响应过慢都是 使用不当导致,或者指标规划有问题,如:

step:

部分数据:

高基数问题

高基数是数据库避不开的一个话题,对于 Mysql 这种 DB 来讲,基数是指特定列或字段中包含的唯一值的数量。基数越低,列中重复的元素越多。对于时序数据库而言,就是 tags、label 这种标签值的数量多少。

比如 中如果有一个指标 {="get",path="/abc",="1.1.1.1"}表示访问量, 表示请求方法, 是客户端 IP,的枚举值是有限的,但 却是无限的,加上其他 label 的排列组合就无穷大了,也没有任何关联特征,因此这种高基数不适合作为 的 label,真要的提取,应该用日志的方式,而不是 监控。

时序数据库会为这些 Label 建立索引,以提高查询性能,以便您可以快速找到与所有指定标签匹配的值。如果值的数量过多,索引是没有意义的,尤其是做 P95 等计算的时候,要扫描大量 数据。

官方文档中对于Label 的建议

如何查看当前的Label 分布情况呢,可以使用 提供的Tsdb工具。可以使用命令行查看,也可以在 2.16 版本以上的 Graph 查看

top10 高基数的

高基数的 label

找到最大的 或 job

top10的 数量:按 名字分

top10的 数量:按 job 名字分

重启慢与热加载

重启的时候需要把 Wal 中的内容 Load 到内存里,保留时间越久、Wal 文件越大,重启的实际越长,这个是 的机制,没得办法,因此能 的就不要重启,重启一定会导致短时间的不可用,而这个时候高可用就很重要了。

学点法律避点坑txt下载_学点法律避点坑txt_

也曾经对启动时间做过优化,在 2.6 版本中对于Wal的 Load 速度就做过速度的优化,希望重启的时间不超过 1 分钟。

1分钟:

提供了热加载能力,不过需要开启web.-配置,更改完配置后,curl 下 接口即可。- 中更改了配置会默认触发 ,如果你没有使用,又希望可以监听 配置变化来 服务,可以试下这个简单的脚本。

使用时和 挂载同一个 ,传入如下参数即可:

你的应用需要暴露多少指标

当你开发自己的服务的时候,你可能会把一些数据暴露 出去,比如特定请求数、 数等,指标数量多少合适呢?

虽然指标数量和你的应用规模相关,但也有一些建议(Brian ),比如简单的服务如缓存等,类似 ,大约 120 个指标, 本身暴露了 700 左右的指标,如果你的应用很大,也尽量不要超过 10000 个指标,需要合理控制你的 Label。

建议(Brian ):

node- 的问题

命名规范:

一些指标名字的变化:

如果你之前用的旧版本 ,在绘制 的时候指标名称就会有差别,解决方法有两种:

指标转换器:

kube-state- 的问题

除了文章中提到的作用,kube-state-还有一个很重要的使用场景,就是和 指标组合,原始的 中只有 pod 信息,不知道属于哪个 或者 sts,但是和kube-state- 中的 做 join 查询之后就可以显示出来,kube-state-的元数据指标,在扩展 的 label 中起到了很多作用,- 的很多 rule 就使用了 kube-state- 做组合查询。

容器监控实践—kube-state-:

kube-state- 中也可以展示 pod 的 label 信息,可以在拿到 数据后更方便地做 group by,如按照 pod 的运行环境分类。但是 kube-state- 不暴露 pod 的 ,原因是下面会提到的高基数问题,即 的内容太多,不适合作为指标暴露。

与 gs

发生在采集之前,gs 发生在采集之后,合理搭配可以满足很多场景的配置。

如:

的预测能力

场景1:你的磁盘剩余空间一直在减少,并且降低的速度比较均匀,你希望知道大概多久之后达到阈值,并希望在某一个时刻报警出来。

场景2:你的 Pod 内存使用率一直升高,你希望知道大概多久之后会到达 Limit 值,并在一定时刻报警出来,在被杀掉之前上去排查。

的 Deriv 和 方法可以满足这类需求, 提供了基础的预测能力,基于当前的变化速度,推测一段时间后的值。

以 为例,最近一小时的 free 值一直在下降。

deriv函数可以显示指标在一段时间的变化速度:

方法是预测基于这种速度,最后可以达到的值:

你可以基于设置合理的报警规则,如小于 10 时报警:

与 deriv 的关系: 含义上约等于如下表达式,不过 稍微准确一些。

如果你要基于 做模型预测,可以参考下-。

-:

的上层封装

部署之后很少会改动,尤其是做了服务发现,就不需要频繁新增 。但报警的配置是很频繁的,如修改阈值、修改报警人等。 拥有丰富的报警能力如分组、抑制等,但如果你要想把他给业务部门使用,就要做一层封装了,也就是报警配置台。用户喜欢表单操作,而非晦涩的 yaml,同时他们也并不愿意去理解 。而且大多数公司内已经有现成的监控平台,也只有一份短信或邮件网关,所以最好能使用 直接集成。

例如: 机器磁盘使用量超过 90% 就报警,rule 应该写为:/ > 0.9

如果不加 label 筛选,这条报警会对所有机器生效,但如果你想去掉其中几台机器,就得在和后面加上{ != “”}。这些操作在 中是很简单的,但是如果放在表单里操作,就得和内部的 cmdb 做联动筛选了。

对于用户来说,封装 yaml 会变的易用,但也会限制其能力,在增加报警配置时,研发和运维需要有一定的配合。如新写了一份自定义的 ,要将需要的指标供用户选择,并调整好展示和报警用的 。还有报警模板、原生 暴露、用户分组等,需要视用户需求做权衡。

错误的高可用设计

有些人提出过这种类型的方案,想提高其扩展性和可用性。

应用程序将 推到到消息队列如 ,然后经过 消费中转,再被 拉取。产生这种方案的原因一般是有历史包袱、复用现有组件、想通过 Mq 来提高扩展性。

这种方案有几个问题:

处理逻辑:

如果你的架构和 的设计理念相悖,可能要重新设计一下方案了,否则扩展性和可靠性反而会降低。

- 的场景

如果你是在 K8S 集群内部署 ,那大概率会用到 -,他对 的配置做了 CRD 封装,让用户更方便的扩展 实例,同时 - 还提供了丰富的 模板,包括上面提到的 组件监控的 视图, 启动之后就可以直接使用,免去了配置面板的烦恼。

的优点很多,就不一一列举了,只提一下 的局限:

高可用方案

高可用有几种方案:

就算使用官方建议的多副本 + 联邦,仍然会遇到一些问题:

本质原因是, 的本地存储没有数据同步能力,要在保证可用性的前提下,再保持数据一致性是比较困难的,基础的 HA Proxy 满足不了要求,比如:

因此解决方案是在存储、查询两个角度上保证数据的一致:

存储方案:

我们采用了 来支持多地域监控数据。

高可用 : 实践:

容器日志与事件

本文主要是 监控内容, 这里只简单介绍下 K8S 中的日志、事件处理方案,以及和 的搭配。

日志处理:

日志采集方案:

需要注意的点:对于容器标准输出,默认日志路径是/var/lib///xxx, 会将改日志软链到/var/log/pods,同时还有一份/var/log/ 是对/var/log/pods的软链。不过不同的 K8S 版本,日志的目录格式有所变化,采集时根据版本做区分:

事件:在这里特指 K8S , 在排查集群问题时也很关键,不过默认情况下只保留 1h,因此需要对 做持久化。一般 处理方式有两种:

kube- :

event-:

来源 |

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了