6

DockOne微信分享(二七五):基于Prometheus的云原生监控系统架构演进

 3 years ago
source link: http://dockone.io/article/450992
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【编者的话】Prometheus作为云原生时代最流行的监控组件,已然成为社区监控的实际标准,拥有活跃的社区和丰富的周边项目。但在多集群,大集群等场景下,Prometheus由于没有分片能力和多集群支持,难以满足生产需求。本文从Prometheus的单集群监控开始,介绍包括Prometheus的基本概念,基本原理,基于联邦架构的多集群监控,基于Thanos的多集群监控,及基于Kvass的大集群监控等内容。

另外本文中的 Kvass 项目是我们团队近期开源的Prometheus分片技术,目前已被Thanos社区作为Thanos推荐的使用案例加入到官网文档中。欢迎大家给项目点赞,参与开发,或者提Issue给我们。

Prometheus基本原理

简介

大家应该对Prometheus或多或少有点了解,这里简单介绍一下, Prometheus 是当前最流行的开源多维监控解决方案,集采集,存储,查询,告警于一身。其拥有强大的PromSQL语句,可进行非常复杂的监控数据聚合计算,甚至支持关系型聚合。其基本架构如下图所示。

bInAFf2.png!mobile

图可能有点复杂,我简单总结如下:

  • 从配置文件加载采集配置
  • 通过服务发现探测有哪些需要抓取的对象
  • 周期性得往抓取对象发起抓取请求,得到数据
  • 将数据写入本地盘或者写往远端存储

基本概念

为了大家阅读后面的内容,这里介绍一些基本的概念术语。

  • Job :Prometheus的采集任务由配置文件中一个个的Job组成,一个Job里包含该Job下的所有监控目标的公共配置,比如使用哪种服务发现去获取监控目标,比如抓取时使用的证书配置,请求参数配置等等。
  • Target :一个监控目标就是一个Target,一个Job通过服务发现会得到多个需要监控的Target,其包含一些label用于描述Target的一些属性。
  • relabel_configs :每个Job都可以配置一个或多个relabel_config,relabel_config会对Target的label集合进行处理,可以根据label过滤一些Target或者修改,增加,删除一些label。 relabel_config过程发生在Target开始进行采集之前,针对的是通过服务发现得到的label集合
  • metrics_relabel_configs :每个Job还可以配置一个或者多个metrics_relabel_config,其配置方式和relabel_configs一模一样, 但是其用于处理的是从Target采集到的数据中的label
  • Series :一个Series就是指标名 label集合,在面板中,表现为一条曲线。
  • head series :Prometheus会将近2小时的Series缓存在内测中,称为head series。

特别注意relable和metrics_relable的区别,前者在抓取前进行,是Target的属性。

基本原理

有些小伙伴可能对Prometheus原理不太了解,这节简单介绍其核心原理。

  • 服务发现 :Prometheus周期性得以pull的形式对target进行指标采集,而监控目标集合是通过配置文件中所定义的服务发现机制来动态生成的。
  • relabel :当服务发现得到所有target后,Prometheus会根据job中的relabel_configs配置对target进行relabel操作,得到target最终的label集合。
  • 采集 :进行完上述操作后,Prometheus为这些target创建采集循环,按配置文件里配置的采集间隔进行周期性拉取,采集到的数据根据Job中的metrics_relabel_configs进行relabel,然后再加入上边得到的target最终label集合,综合后得到最终的数据。
  • 存储 :Prometheus不会将采集到的数据直接落盘,而是会将近2小时的series缓存在内测中,2小时后,Prometheus会进行一次数据压缩,将内存中的数据落盘。

服务发现 ==> targets ==> relabel ==> 抓取 ==> metrics_relabel ==> 缓存 ==> 2小时落盘。

单集群监控方案

我们先从单个小集群的监控方案开始,这也是绝大多数Prometheus的使用场景。

主流的指标

对于单个集群,社区主流的指标来源于以下几个组件,Prometheus将从他们获取数据。

  • Kube-state-metrics:这个组件用于监控Kubernetes资源的状态,比如Pod的状态。原理是将Kubernetes中的资源,转换成Prometheus的指标,让Prometheus来采集。比如Pod的基本信息,Serivce的基本信息。
  • Node-exporter:用于监控Kubernetes节点的基本状态,这个组件以DeamonSet的方式部署,每个节点一个,用于提供节点相关的指标,比如节点的cpu使用率,内存使用率等等。
  • cAdvisor:这个组件目前已经整合到kubelet中了,它提供的是每个容器的运行时指标,比如一个容器的CPU使用率,内存使用率等等。
  • Kubernetes相关组件:比如apiserver,controller-manager,scheduler,kubelet等,主要提供每个组件核心功能相关的指标,比如QPS等等。

部署架构

单集群架构非常简单,如图所示。使用这种方式,就可以将集群的节点,组件,资源状态,容器运行时状态都给监控起来。

jaaquu7.png!mobile

多集群场景的特点

如果我们现在有多个集群,并希望他们的监控数据存储到一起,可以进行聚合查询,用上述部署方案显然是不够的,因为上述方案中的Prometheus只能识别出本集群内的被监控目标,即服务发现无法跨集群。另外就是网络限制,多个集群之间的网络有可能是不通的,这就使得即使在某个集群中知道另一个集群的Target地址,也没法去抓取数据。总结多集群的特点主要有:

  • 服务发现隔离
  • 网络隔离

只用Prometheus能解决吗?

答案其实是能,用联邦。

Prometheus支持拉取其他Prometheus的数据到本地,称为联邦机制。这样我们就可以在每个集群内部署一个Prometheus,再在他们之上部署一个Top Prometheus,用于拉取各个集群内部的Prometheus数据进行汇总。

2yqAvqa.png!mobile

联邦的问题在哪?

联邦的方案也是社区所认可的,在集群规模普遍较小,整体数据量不大的情况下,联邦的方案部署简单,理解成本低,没有其他组件的引入,是一个很不错的选择。

但是联邦也有其问题。由于所有数据最终都由Top Prometheus进行存储,当总数据量较大的时候,Top Prometheus的压力将增大,甚至难抗重负,另外,每个集群中的Prometheus实际上也会保存数据(Prometheus2.x 不支持关闭本地存储),所以实际上出现了数据无意义冗余。总结而言,联邦的问题主要是:

  • Top Prometheus压力大
  • 数据有无意义冗余

使用Thanos实现多集群监控

Thanos简介

Thanos 是一款开源的Prometheus 高可用解决方案,其支持从多个Prometheus中查询数据并进行汇总和去重,并支持将Prometheus本地数据传送到云上对象存储进行长期存储。官方架构图太复杂,不便于理解,这里给一个简化版本。

ZziMZf.png!mobile

  • Query:Query代理Prometheus作为查询入口,它会去所有Prometheus,Store以及Ruler查询数据,汇总并去重。
  • Sidecar:将数据上传到对象存储,也负责接收Thanos Query的查询请求。
  • Ruler:进行数据的预聚合及告警。
  • Store:负责从对象存储中查询数据。

部署方案

使用Thanos来替代联邦方案,我们只需要将上图中的Prometheus和Thanos sidecar部署到Kubernetes集群中,将Thano Query等组件部署在原来Top Prometheus的位置即可。

Y7vAnuj.png!mobile

相比联邦的优势

使用Thanos相比于之前使用联邦,拥有一些较为明显的优势:

  • 由于数据不再存储在单个Prometheus中,所以整体能承载的数据规模比联邦大。
  • 数据不再有不必要的冗余。
  • 由于Thanos有去重能力,实际上可以每个集群中部署两个Prometheus来做数据多副本。
  • 可以将数据存储到对象存储中,相比存储在本地,能支持更长久的存储。

大集群场景的特点

上边我们介绍了基于Thanos的监控系统,那如果不是多集群,而是单个大集群的场景怎么办?

大集群场景的特点很明显,那就是数据规模大,无论是target的规模,还是数据量,都是一个Prometheus无法采集的,得分片。

只用Thanos能解决吗

答案还是能,用hasmod。

Prometheus支持在配置文件中加入hashmod,通过某个label的值来进行hash,让每个Prometheus只采集部分target,例如按target的地址进行hashmod,让target采集任务分散到3个Prometheus中。这样每个Prometheus就只会采集部分target,从而达到分片效果。由于每个分片的hashmod取值不一样,所以每个分片需要使用单独的配置文件。

rmMbaur.png!mobile

hashmod的方案有什么问题

虽然使用hashmod的方式在一定程度上可以将负载分散到多个Prometheus中,但是其至少存在以下问题:

  • 配置管理复杂:由于每个分片都要有单独的配置文件,需要维护多份配置文件
  • 配置项有侵入:需要为每个Job考虑hashmod的方式,而且需要清楚所采集数据根据那个label来hash才可能平均,对使用者相当不友好。
  • 可能出现热点:hashmod是不保证负载一定均衡的,因为如果多个数据规模较大的target被hashmod到一个分片,这个分片就有可能OOM。

Thanos没解决的问题

虽然Thanos提供了统一查询和高可用的支持,但是其并没有提供Prometheus分片方案,而是由使用者自行分片,例如使用上边介绍的hashmod。

那能不能只使用一个配置文件还不需要hashmod呢,这就需要使用Kvass项目提供的能力。

加入Kvass实现大集群监控

Kvass简介

Kvass是一个Prometheus横向扩缩容解决方案,他使用Sidecar动态得根据Coordinator分配下来的target列表来为每个Prometheus生成只含特定target的配置文件,从而将采集任务分散到各个Prometheus分片。Coordinator用于服务发现,target分配和分片扩缩容管理。Thanos(或者其他TSDB)用来将分片数据汇总成全局数据是官方文档中Thanos的典型用法: https://thanos.io/tip/operating/use-cases.md/

rARRBrm.png!mobile

简单来说,就是由独立组件(Coordinator)做服务发现,并把target集合及数据规模提前探测出来,直接分配给几个Prometheus去抓,分片不再进行服务发现了。

部署方案

我们在Thanos方案中加入Kvass,就可以使用原来的配置文件去监控大集群,而不需要加入任何hashmod相关的东西吗,配置文件也不需要多个。

rEjeE3N.png!mobile

相比hashmod的优势

使用Kvass方案,相比于hashmod有明显的优势:

  • 配置管理简单:无需针对配置文件做任何特殊工作,单一小集群时候怎么用,现在就怎么用。
  • 负载可控:由于Kvass在向分片配置target的时候,会根据target的实际规模来,而不是通过hashmod来,所以每个分片的总负载会被控制在一个阈值以下,不会出现某个分片OOM的情况。
  • 自动扩缩容:Kvass会根据当前集群的规模,动态调整分片个数。

总结

刚才我们首先介绍了Prometheus的基本原理,并介绍了最为常用的使用Prometheus监控单一小集群的方案。

随后,针对多集群场景,我们还谈了联邦方式与Thanos方式各有什么优缺点。

面对大集群场景时,我们谈了Thanos未解决的问题,并介绍如何用hashmod的方案来监控大集群。最后,我们使用Kvass弥补了Thanos的不足,不需要hashmod就能将Prometheus进行了分片。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK