云原生监控系统Prometheus——Prometheus入门
Prometheus入门
一、Prometheus 的介绍:
Prometheus 和 Kubernetes 不仅在使用过程中紧密相关,而且在历史上也有很深的渊源。在加利福尼亚州山景城的 Google 公司里曾经有两款系统——Borg 系统和它的监控系统 Borgmon系统。Borg系统是 Google 内部用来管理来自不同应用、不同作业的集群的管理器,每个集群都会拥有数万台服务器及上万个作业;Borgmon 系统则是与 Borg 系统配套的监控系统。Borg 系统和 Borgmon 系统都没有开源,但是目前开源的 Kubernetes、Prometheus 的理念都是对它们的理念的传承。
Kubernetes 系统传承于 Borg 系统,Prometheus 则传承于 Borgmon 系统。Google SRE 的书内也曾提到,与 Borgmon 监控系统相似的实现是 Prometheus。现在最常见的 Kubernetes 容器调度管理系统中,通常会搭配 Prometheus 进行监控。
Prometheus 官网首页对 Prometheus 介绍如下图所示:
二、 Prometheus 的主要特点:
Prometheus 官网上的自述是: "From metrics to insight. Power your metrics and alerting with a leading open-source monitoring solution.”谷歌中文翻译过来意思是:"从指标到洞察力。Prometheus 通过用领先的开源监控解决方案为用户的指标和告警提供强大的支持。”
相比互联网主流的监控系统,和它们相比,Prometheus 最主要的特点有 8 个:
1、Dimensional data (多维度数据)
Prometheus implements a highly dimensional data model. Time series are identified by a metric name and a set of key-value pairs.
Prometheus 实现了一个高维数据模型。时间序列由指标名称和一组键值对标识。
2、Powerful queries (强大的查询能力)
PromQL allows slicing and dicing of collected time series data in order to generate ad-hoc graphs, tables, and alerts.
PromQL 允许对收集的时间序列数据进行切片和切块,以生成临时图形、表格和警报。
3、Great visualization (伟大的可视化)
Prometheus has multiple modes for visualizing data: a built-in expression browser, Grafana integration, and a console template language.
Prometheus 具有多种可视化数据模式:内置表达式浏览器、Grafana 集成和控制台模板语言。
4、Efficient storage(高效存储)
Prometheus stores time series in memory and on local disk in an efficient custom format. Scaling is achieved by functional sharding and federation.
Prometheus 以高效的自定义格式将时间序列存储在内存和本地磁盘中。扩展是通过功能分片和联合来实现
5、Simple operation(操作简单)
Each server is independent for reliability, relying only on local storage. Written in Go, all binaries are statically linked and easy to deploy.
每台服务器独立于可靠性,仅依赖本地存储。用 Go 编写,所有二进制文件都是静态链接的,易于部署。
6、Precise alerting(精准告警)
Alerts are defined based on Prometheus's flexible PromQL and maintain dimensional information. An alertmanager handles notifications and silencing.
警报基于 Prometheus 灵活的 PromQL 定义并维护维度信息。警报管理器处理通知和静音。
7、Many client libraries(许多客户端库)
Client libraries allow easy instrumentation of services. Over ten languages are supported already and custom libraries are easy to implement.
客户端库允许轻松检测服务。已经支持十多种语言,自定义库很容易实现。
8、Many integrations(许多集成)
Existing exporters allow bridging of third-party data into Prometheus. Examples: system statistics, as well as Docker, HAProxy, StatsD, and JMX metrics.
现有的出口商允许将第三方数据桥接到 Prometheus。示例:系统统计信息,以及 Docker、HAProxy、StatsD 和 JMX 指标。
三、 Prometheus 的主要局限性:
Prometheus 固然强大,但它还是有不少局限性的。
- Prometheus 是基于度量的监控系统,主要针对性能和可用性监控,不适用于针对日志(Log)、事件(event)、调用链(Tracing)等的监控。
- Prometheus 关注的是近期发生的事情,而不是跟踪数周或数月的数据。因为大多数监控查询及告警都针对的是最近(通常不到一天)的数据。Prometheus 认为最有用的数据是最近的数据,监控数据默认保留 15 天。
- 本地存储有限,存储大量的历史数据需要对接第三方远程存储。
- 采用联邦集群的方式,并没有提供统一的全局视图。
- Prometheus 的监控数据并没有对单位进行定义。
- Prometheus 对数据的统计无法做到 100% 准确,如订单、支付、计量计费等精确数据监控场景。
- Prometheus 默认是拉模式,建议合理规划网络,尽量不要转发。
四、Prometheus 架构剖析
Prometheus 的架构图如下图所示,它展现了 Prometheus 内部模块及相关的外围组件之间的关系。
Prometheus 主要由 Prometheus Server、Pushgateway、Job/Exporter、Service Discovery、Alertmanager、Dashboard 这 6 个核心模块构成。Prometheus 通过服务发现机制发现 target,这些目标可以是长时间执行的 Job,也可以是短时间执行的 Job,还可以是通过 Exporter 监控的第三方应用程序。被抓取的数据会存储起来,通过 PromQL 语句在仪表盘等可视化系统中供查询,或者向 Alertmanager 发送告警信息,告警会通过页面、电子邮件、钉钉或者其他形式呈现。
很多企业自己研发的监控系统中往往会使用消息队列 Kafka 和 Metrics parser、Metrics process server 等 Metrics 解析处理模块,再辅以 Spark 等流失处理方式。应用程序将 Metrics 推送到消息队列(如 Kafka ),然后经过 Expoter 中转,再被 Prometheus 拉取。之所以会产生这钟方案,是因为考虑到现有历史包袱、复用现有组件、通过 MQ(消息队列)来提高扩展性等因素。
但是这个方案也有新的问题:
- 增加了查询组件,比如基础的 sum、count、average 函数都需要额外进行计算。这一方面多了一层依赖,在查询模块连接失败的情况下会多提供一层故障风险;另一方面,很多基本的查询功能的实现都需要消耗资源。而在 Prometheus 的架构里,上述这些功能都是得到支持的。
- 抓取时间可能会不同步,延迟的数据将会被标记为陈旧数据。也可以通过添加时间戳来表示标识数据,但是会失去对陈旧数据的处理逻辑。
- Prometheus 适用于监控大量小目标的场景,而不是监控一个大目标,如果将所有数据都放在 Expoter,那么 Prometheus 的单个 Job 拉取就会成为 CPU 的瓶颈。因此如果不是特别必要的场景,官方不建议适用。
- 缺少服务发现和拉取控制机制,Prometheus 只能识别 Exporter 模块,不知道具体是哪些 target,也不知道每个 target 的 UP 时间,所以无法使用 Scrape_* 等指标做查询,也无法使用 scrape_limit 做限制。
对于以上这些重度依赖的场景,可以考虑将其优化掉,而 Prometheus 这种采用以拉模式为主架构,在这方面的实现是一个很好的参考方向。同理,很多企业的监控系统对于 cmdb 有强依赖,通过 Prometheus 这种架构也可以消除标签对 cmdb 的依赖。
4.1 Job/Exporter
Job/Exporter 属于 Prometheus target,是 Prometheus 监控的对象。
Job 分为长时间执行和短时间执行两种。对于长时间执行的 Job,可以使用 Prometheus Client 集成进行监控;对于短时间执行的 Job,可以将监控数据推送到 Pushgateway 中缓存。
Prometheus 收录的 Exporter 有上千种,它可以用于第三方系统的监控。Exporter 的机制是将第三方系统的监控数据按照 Prometheus 的格式暴露出来,没有 Exporter 的第三方系统可以主机定制 Exporter。Prometheus 是一个白盒监控系统,它会对应用程序内部公开的指标进行采集。假如用户想从外部检查,它就会涉及黑盒监控,Prometheus 中常用的黑盒 Exporter 就是 blackbox_exporter。blackbox_exporter 包括一些现成的模块,例如 HTTP、TCP、POP3S、IRC 和 ICMP。blackbox.yml 可以扩展其中的配置,以添加其他模块来满足用户的需求。blackbox_exporter 一个令人满意的功能是,如果模块使用了 TLS/SSL,则 Exporter 将在证书链到期时自动公开,这样可以很容易地对即将到期的 SSL 证书发出告警。
Export 局限性:Export 种类繁多既是优点也是缺点,因为每个 Exporter 彼此都是独立的,每个 Exporter 各司其职。随着 Exporter 越多,维护压力就越大,尤其是内部自行开发的 Agent 等工具需要大量人力来完成资源控制、特性添加、版本升级等工作,可以考虑替换为 Influx Data 公司开源的 Telegraf 统一进行管理。Telegraf 是一个用 Golang 编写的用于数据收集的开源 Agent,其基于插件驱动。Telegraf 提供的输入和输出插件非常丰富,当用户有特殊需求时,也可以自行编写插件(需要重编译)。
4.2 Pushgateway
Prometheus 是拉模式为主的监控系统,它的推模式就是通过 Pushgateway 组件实现的。Pushgateway 是支持临时性 Job 主动推送指标的中间网关,它本质上是一种用于监控 Prometheus 服务器无法抓取的资源的解决方案。它也是用 Go 语言编写的,在 Apache 2.0 许可证下开源。
Pushgateway 作为一个独立的服务,位于被采集监控指标的应用程序和 Prometheus 服务器之间。应用程序主动推送指标到 Pushgateway,Pushgateway 接收指标,然后 Pushgateway也作为 target 被 Prometheus 服务器抓取。它的使用场景主要有如下几种:
-
- 临时Job/短Job
- 批处理Job
- 应用程序与 Prometheus 服务器之间无法直连,中间有譬如防火墙?
Pushgateway 局限性:
-
- 在 Prometheus 中被建议作为临时性解决方案,主要是一些无法直连访问的 target 监控资源。使用 Pushgateway,它会失去很多 Prometheus 服务器提供的功能,比如 UP 指标和指标过期时进行实例状态监控。
- Pushgateway 的一个常见的问题是,它存在单点故障问题。如果 Pushgateway 从许多不同的来源收集指标时宕机,用户将时区对所有这些来源的监控,可能会触发许多不必要的告警。
- Pushgateway 不会自动删除推送给它的任何指标数据。因此,必须使用 Pushgateway 的 API 从推送网关中删除过期的指标。
4.3 服务发现(Service Discovery)
作为下一代监控系统的首选解决方案,Prometheus 通过服务发现机制对云以及容器环境下的监控场景提供了完善的支持。
除了支持文件的服务发现(Prometheus 会周期性地从文件中读取最新的 target 信息)外,Prometheus 还支持多种常见的服务发现组件,如 Kubernetes、DNS、Zookeeper等。例如,Prometheus 可以使用 Kubernetes 的 API 获取容器信息的变化(如容器的创建和删除)来动态更新监控对象。
对于支持文件的服务发现,实践场景下可以衍生为与自动化配置管理工具(Ansible、Cron Job、Saltstack等)结合使用。
通过服务发现的方式,管理员可以在不重启 Prometheus 服务的情况下动态发现需要监控的 target实例信息。服务发现中有一个高级操作,就是 Relabeling 机制。Relabeling 机制会从 Prometheus 包含的 target 实例中获取默认的元标签信息,从而对不同开发环境(测试、预发布、线上)、不同业务团队、不同组织等按照某些规则(比如标签)从服务发现注册中心返回的 target 实例中有选择地采集某些 Exporter 实例的监控数据。
相比于直接使用文件配置,在云环境以及容器环境下,我们更多的监控对象都是动态的。实际场景下,Prometheus 作为下一代监控解决方案,更适合云及容器环境下的监控需求,在服务发现过程中也有很多工作(如 Relabeling机制)可以加持。
4.4 Prometheus 服务器(Prometheus Server)
Prometheus 服务器 是 Prometheus 最核心的模块。它主要包含抓取、存储和查询这 3 个功能。
1) 抓取:Prometheus Server 通过服务发现组件,周期性地从上面介绍的 Job、Exporter、Pushgateway 这 3 个组件中通过 HTTP 轮询的形式拉取监控指标数据。
2) 存储:抓取到的监控数据通过一定的规则清理和数据整理(抓取前使用服务发现提供的 relabel_configs 方法,抓取后使用作业内的 metrics_relabel_configs方法),会把得到的结果存储到新的时间序列中进行持久化。
Prometheus 的存储分为 本地存储 和 远程存储。
-
- 本地存储:会直接保留到本地磁盘,性能上建议使用 SSD 且不要保存超过一月的数据。记住,任何版本的 Prometheus 都不支持 NFS。一些实际生产案例告诉我们 Prometheus 存储文件如果使用 NFS,则有损坏或丢失历史数据的可能。
- 远程存储:适用于存储大量的监控数据。Prometheus 支持的远程存储包括 OpenTSDB、InfluxDB、Elastichsearch、Graphite、CrateDB、Kafka、PostgreSQL、TimescaleDB等等。
3) 查询:Prometheus 持久化数据后以后,客户端就可以通过 PromQL 语句对数据进行查询了。
4.5 Dashboard
在Prometheus 架构图中, Web UI、Grafana、API client 可以统一理解为 Prometheus 的 Dashboard。Prometheus 服务器除了内置查询语言 PromQL 以外,还支持表达式浏览器及表达式浏览器上的数据图形界面。实际工作中使用 Grafana 等作为前端展示界面,用户也可以直接使用 Client 向 Prometheus Server 发送请求以获取数据。
4.6 Alertmanager
Alertmanager 是独立于 Prometheus 的一个告警组件,需要单独安装部署。Prometheus 可以将多个 Alertmanager 配置为一个集群,通过服务发现动态发现告警集群中节点的上下线从而避免单点故障,Alertmanager 也支持集群内多个实例之间的通信。
Alertmanager 接收 Prometheus 推送过来的告警,用于管理、整合和分发告警到不同的目的地。Alertmanager 提供了多种内置的第三方告警通知方式,同时还提供了对 Webhook 提供基本的告警通知能力以外,还提供了如分组、抑制以及静默等告警特性。