本文共 6856 字,大约阅读时间需要 22 分钟。
监控系统的历史悠久,是一个非常成熟的领域,而 Prometheus 作为新生代的开源监控系统,逐渐成为云原生生态系统的事实标准,展现出其广泛的受欢迎程度。本文将分享在 Prometheus 实践中遇到的问题和思考。
监控是基础设施
监控的目的是为了解决问题,不要仅仅追求大而全的方案,尤其是不必要的指标采集,否则会浪费人力和存储资源(To B 商业产品例外)。告警的处理流程
只有处理告警的通知才会发出,发出后必须得到及时处理。简洁的架构更好
业务系统都挂上监控,监控系统也不能挂。Google SRE 中提到避免使用“Magic”系统,如机器学习报警阈值或自动修复等,这一点见仁见智,许多公司都在尝试智能化运维。基于 Metric 的监控
Prometheus 不适用于日志(Logs)、事件(Event)或调用链(Tracing)。默认是 Pull 模型
合理规划网络,尽量不要进行数据转发。集群化和水平扩展
对于集群化和水平扩展,官方和社区没有一键解决方案,需要合理选择 Federate、Cortex、Thanos 等方案。可用性优先于一致性
监控系统通常更注重可用性,容忍部分副本数据丢失,保证查询请求成功。后面会提到 Thanos 去重时的相关内容。数据准确性
Prometheus 不一定保证数据的准确性。一是 rate、histogram_quantile 等函数会进行统计和推断,可能产生反直觉的结果;二是查询范围过长时会进行降采样,导致数据精度丢失,这与时序数据的特点有关,与日志系统不同。Prometheus 属于 CNCF 项目,拥有丰富的 exporter 来满足各种需求。你可以在官方和非官方资源中找到 exporter。如果仍然无法满足需求,可以编写自定义 exporter,简单方便且自由开放,但这也带来了选型和试错的成本。
K8S 生态中的组件都提供 /metric 接口以进行自监控。以下是一些我们正在使用的 exporter:
在 K8S 集群运行中,需要关注核心组件的状态和性能,如 kubelet、apiserver 等。基于上述 exporter 的指标,可以在 Grafana 中绘制相关图表。
Prometheus 的 exporter 是独立的,各司其职。但是 exporter 越多,运维压力越大,尤其是对 Agent 做资源控制和版本升级。我们尝试对一些 exporter 进行组合,方案有二:
通过主进程启动多个 exporter 进程
仍然可以跟随社区版本进行更新和 bug 修复。使用 Telegraf 支持多种类型的 Input
将 Node-Exporter、Process-Exporter 等指标统一通过 Telegraf 进行采集。采集的指标有很多,我们应该关注哪些?Google 的“SRE Handbook”中提出了“四个黄金信号”:延迟、流量、错误数、饱和度。实际操作中可以使用 Use 或 Red 方法作为指导,Use 用于资源,Red 用于服务。
Prometheus 采集中常见的服务分为三种类型:
在 K8S 1.16 版本中,Cadvisor 的指标去掉了 pod_Name 和 container_name 的 label,替换为 pod 和 container。如之前依赖这两个 label 进行查询或 Grafana 绘图,需更改 Sql 配置。
如果 Prometheus 部署在集群外,需要采集多个 K8S 集群的数据。以 Pod 方式运行在集群内是不需要证书的(In-Cluster 模式),但集群外需要声明 token 证书,并替换 address。以 Cadvisor 为例,Job 配置可以参考以下示例:
Nvidia-smi 可以查看机器上的 GPU 资源,而 Cadvisor 实际上暴露了容器使用 GPU 情况的 Metric。如果需要更详细的 GPU 数据,可以安装 dcgm exporter(从 K8S 1.13 开始支持)。
Prometheus 为避免时区混乱,专门使用 Unix Time 和 Utc 进行显示。不支持在配置文件中设置时区,也不能读取本机 /etc/timezone 时区。实际上这个限制不影响使用:
假如你有一个负载均衡 LB,但网络上 Prometheus 只能访问到 LB 本身,无法访问后面的 RS,如何采集 RS 暴露的 Metric?可以采取以下措施:
RS 的服务加 Sidecar Proxy
或者在本机增加 Proxy 组件,确保 Prometheus 能访问到。LB 增加转发规则
将 /backend1 和 /backend2 请求转发到两个单独的后端,再由 Prometheus 访问 LB 采集。Prometheus 当前最新版本为 2.16,尽量使用最新版本,1.X 版本不再支持。
随着规模的变大,Prometheus 需要的 CPU 和内存都会升高,内存通常会成为瓶颈。内存消耗主要是因为每隔 2 小时 Prometheus 会将已缓冲在内存中的数据压缩到磁盘上。以下是一些优化方案:
除了内存规划,还需要考虑磁盘存储。Prometheus 每 2 小时将已缓冲数据压缩到磁盘上,包括 Chunks、Indexes、Tombstones 和 Metadata。以下是一些规划建议:
如果使用 kubernetes_sd_config 进行服务发现,请求会经过集群的 Apiserver。随着规模的变大,需要评估对 Apiserver 性能的影响,尤其是在 Proxy 失败时,可能导致 CPU 升高。建议直接拉取节点端口,减少对 Apiserver 的负载。
Prometheus 中的 rate 函数用于计算速率,主要用于 Counter 类型的指标。rate 会自动处理 Counter 重置的问题,避免了手动计算元数据。以下是一些关键点:
histogram_quantile 函数用于计算百分位数,P95 表示 95% 的请求时间小于该值。P95 的含义是 5% 的请求大于该值,95% 的请求小于该值。与平均值的关系不明确,可能会出现反直觉的结果。
Prometheus 提供的 Promql 查询语句可能会导致慢查询。以下是一些常见原因和解决方案:
高基数是时序数据库的热点问题,尤其是在标签(labels)中。高基数会导致索引失效,影响查询性能。以下是一些建议:
Prometheus 重启时需要加载 Wal 文件到内存中,保留时间越久,Wal 文件越大,重启时间越长。以下是一些优化建议:
在开发服务时,需要决定暴露多少 Metric。Brian Brazil 的建议指出,简单服务如缓存等大约暴露 120 个指标,Prometheus 本身暴露了 700 多个指标。如果应用很大,也尽量不要超过 10000 个指标。
不支持进程监控
Node-Exporter 不支持进程指标采集,可以使用 Process-Exporter 或 Telegraf。仅支持 Unix 系统
对于 Windows 机器,使用 wmi_exporter。版本问题
node-exporter 是较为老旧的组件,建议使用 0.16 或 0.17 版本。relabel_config 发生在采集之前,metric_relabel_configs 发生在采集之后,合理搭配可以满足多种场景配置。
Prometheus 提供了 deriv 和 predict_linear 函数,基于当前数据预测未来值。以下是一些示例:
Prometheus 部署后,报警配置是很频繁的操作。alertmanager 提供了丰富的报警能力,如分组、抑制等。但对业务部门用户来说,直接使用 alertmanager 的配置可能不够友好。建议进行封装,如通过表单化配置或 webhook 集成到现有的报警平台。
有些人提出过将 Metric 推到消息队列,再通过 Exposer 中转再由 Prometheus 拉取的方案,但这种方案存在以下问题:
Prometheus-operator 提供了 CRD 封装,便于扩展 Prometheus 实例,同时提供了丰富的 Grafana 模板。但也有一些局限:
Prometheus 高可用的方案包括:
本文主要是 Prometheus 监控内容,以下是日志和事件处理的简单介绍:
作者:徐亚松
来源:http://www.xuyasong.com/?p=1921转载地址:http://pcqfk.baihongyu.com/