掘金 后端 ( ) • 2024-06-20 17:34

theme: smartblue highlight: a11y-dark

原文链接:Learn Prometheus Architecture: A Complete Guide

image.png

在本指南中,我们将详细了解 Prometheus 的架构,以有效地理解、配置和利用 Prometheus 的架构。

Prometheus 是使用 Go 编写的流行的开源监控和告警系统,能够收集和处理来自各种目标(targets)的指标(metrics)。你还可以查询、查看、分析指标并根据阈值收到告警。

此外,在当今世界,可观测性对于每个组织都变得至关重要,而 Prometheus 是开源领域的关键的可观测工具之一。

什么是 Prometheus 架构?

以下是 Prometheus 的架构。

image.png

Prometheus 主要由以下部分组成。

  1. Prometheus Server
  2. Service Discovery
  3. Time-Series Database (TSDB)
  4. Targets
  5. Exporters
  6. Push Gateway
  7. Alert Manager
  8. Client Libraries
  9. PromQL

Prometheus Server

Prometheus Server 是基于指标的监控系统的大脑。Server 的主要工作是使用拉(pull)模型从各个目标收集指标。

目标只不过是 server、pod、端点等,我们将在下一个主题中详细介绍它们。

使用 Prometheus 从目标收集指标的通用术语称为抓取(scraping)。

image.png

Prometheus 根据我们在 Prometheus 配置文件中提到的抓取间隔定期抓取指标。

这是一个配置示例。

global:
  scrape_interval: 15s 
  evaluation_interval: 15s 
  scrape_timeout: 10s 

rule_files:
  - "rules/*.rules"

scrape_configs:
  - job_name: 'Prometheus'
    static_configs:
      - targets: ['localhost:9090'] 
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100'] 

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

时间序列数据库 (TSDB)

Prometheus 接收到的指标数据随着时间的推移而变化(CPU、内存、网络 IO 等)。它被称为时间序列数据。因此 Prometheus 使用时间序列数据库(TSDB)来存储其所有数据。

默认情况下,Prometheus 以有效的格式(块)将其所有数据存储在本地磁盘中。随着时间的推移,它会压缩所有旧数据以节省空间。它还具有删除旧数据的保留策略。

TSDB 具有内置的机制来管理长期保存的数据。你可以选择以下任意数据保留策略。

  1. 基于时间的保留:数据将保留指定的天数。默认保留期为 15 天
  2. 基于大小的保留:你可以指定 TSDB 可以容纳的最大数据量。一旦达到这个限制, Prometheus 将释放空间来容纳新数据

Prometheus 还提供远程存储选项。这主要是存储可扩展性、长期存储、备份和灾难恢复等所需要的。

Prometheus 目标

Target 是 Prometheus 抓取指标的来源。目标可以是 Server 、Service、Kubernetes Pod、应用程序端点等。

Prometheus targets

默认情况下,Prometheus 会在目标的 /metrics 路径下查找指标。可以在目标配置中更改默认路径。这意味着,如果你不指定自定义指标路径,Prometheus 会在 /metrics 下查找指标。

目标配置位于 Prometheus 配置文件中的 scrape_configs 下。这是一个配置示例。

scrape_configs:
  
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter1:9100', 'node-exporter2:9100']
 
  - job_name: 'my_custom_job'
    static_configs:
      - targets: ['my_service_address:port']
    metrics_path: '/custom_metrics'

  - job_name: 'blackbox-exporter'
    static_configs:
      - targets: ['blackbox-exporter1:9115', 'blackbox-exporter2:9115']
    metrics_path: /probe

  - job_name: 'snmp-exporter'
    static_configs:
      - targets: ['snmp-exporter1:9116', 'snmp-exporter2:9116']
    metrics_path: /snmp

Prometheus 需要来自目标端点的特定文本格式的数据。每个指标都必须换行。

通常,这些指标使用在目标上运行的 Prometheus 导出器在目标节点上公开。

Prometheus Exporters

Exporters 就像在目标上运行的代理。它将指标从特定系统转换为 Prometheus 可以理解的格式。

它可以是系统指标,例如 CPU、内存等,或者 Java JMX 指标、MySQL 指标等。

Prometheus exporters

默认情况下,这些转换后的指标由导出器在目标的 /metrics 路径(HTTPS 端点)上公开。

例如,如果要监控 Server 的 CPU 和内存,则需要在该 Server 上安装节点导出器,并且节点导出器以 Prometheus 指标格式在 /metrics 上公开 CPU 和内存指标。

一旦 Prometheus 提取指标,它将结合指标名称、标签、值和时间戳来为该数据提供结构。

社区有很多 Exporters 可用,但只有其中一些获得 Prometheus 官方认可。如果你需要更多自定义,则需要创建自己的导出器。

Prometheus 将导出器分为多类,例如数据库、硬件、问题跟踪器和持续集成、消息系统、存储、公开 Prometheus 指标的软件、其他第三方实用程序等。

在 Prometheus 配置文件中,所有导出器的详细信息将在 scrape_configs 下给出。

scrape_configs:
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter1:9100', 'node-exporter2:9100']

  - job_name: 'blackbox-exporter'
    static_configs:
      - targets: ['blackbox-exporter1:9115', 'blackbox-exporter2:9115']
    metrics_path: /probe

  - job_name: 'snmp-exporter'
    static_configs:
      - targets: ['snmp-exporter1:9116', 'snmp-exporter2:9116']
    metrics_path: /snmp

Prometheus 服务发现

Prometheus 使用两种方法从目标中获取指标。

  1. 静态配置:当目标具有静态 IP 或 DNS 端点时,我们可以使用这些端点作为目标。
  2. 服务发现:在大多数自动扩展系统和分布式系统(例如 Kubernetes)中,目标不会有静态端点。在这种情况下,使用 Prometheus 服务发现来发现目标端点,并且目标会自动添加到 Prometheus 配置中。

Prometheus service discovery

在进一步讨论之前,让我展示一个使用 kubernetes_sd_configs 的 Prometheus 配置文件的 Kubernetes 服务发现块的小示例。

scrape_configs:
      - job_name: 'kubernetes-apiservers'
        kubernetes_sd_configs:
        - role: endpoints
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        relabel_configs:
        - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
          action: keep
          regex: default;kubernetes;https

Kubernetes 是动态目标的完美示例。在这里,你不能使用静态目标方法,因为 Kubernetes 集群中的目标(pod)本质上是短暂的,并且可能很短暂。

Kubernetes 中还有基于文件的服务发现 file_sd_configs 。它适用于静态目标,但经典静态配置 static_configsfile_sd_configs 之间的主要区别在于,在这种情况下,我们创建单独的 JSON 或 YAML 文件并将目标信息保存在他们。 Prometheus 将读取文件来识别目标。

不仅这两种,还可以使用各种服务发现方法,例如 consul_sd_configs(Prometheus 从 consul 获取目标详细信息)、ec2_sd_configs 等。

如需了解更多配置细节,请访问官方文档。

Prometheus 推送网关

Prometheus 默认使用拉取机制来废弃指标。

然而,有些场景需要将指标推送到 Prometheus。

让我们举一个在 Kubernetes CronJob 上运行的批处理作业的示例,该作业每天根据某些事件运行 5 分钟。在这种情况下,Prometheus 将无法使用拉取机制正确抓取服务级别指标。

因此,我们需要将指标推送到 Prometheus,而不是等待 Prometheus 拉取指标。为了推送指标,Prometheus 提供了一个名为 Push Gateway 的解决方案。它是一种中间网关。

Push Gateway 需要作为独立组件运行。批处理作业可以使用 HTTP API 将指标推送到推送网关。然后 Push Gateway 在 /metrics 端点上公开这些指标。然后 Prometheus 从 Push Gateway 中抓取这些指标。

Prometheus push gateway

Push Gateway 将指标数据临时存储在内存中。它更像是一个临时缓存。

Push Gateway 配置也将在 Prometheus 配置中的 scrape_configs 部分下进行配置。

scrape_configs:
  - job_name: "pushgateway"
        honor_labels: true
        static_configs:
        - targets: [pushgateway.monitoring.svc:9091]

要将指标发送到 Push Gateways,你需要使用 Prometheus 客户端库并检测应用程序或脚本以公开所需的指标。

Prometheus 客户端库

Prometheus 客户端库是可用于检测应用程序代码的软件库,以 Prometheus 理解的方式公开指标。

如果你需要自定义工具或想要创建自己的导出器,则可以使用客户端库。

一个非常好的用例是需要将指标推送到 Push Gateway 的批处理作业。批处理作业需要使用客户端库进行仪器化(instrumented),以 Prometheus 格式公开需要的指标。

下面是一个示例 Python Client Library ,它公开了名为 batch_job_records_processed_total 的自定义指标。

from Prometheus_client import start_http_server, Counter
import time
import random

RECORDS_PROCESSED = Counter('batch_job_records_processed_total', 'Total number of records processed by the batch job')

def process_record():
    time.sleep(random.uniform(0.01, 0.1))
    RECORDS_PROCESSED.inc()

def batch_job():
   
    for _ in range(100):
        process_record()

if __name__ == '__main__':
 
    start_http_server(8000)
    print("Metrics server started on port 8000")

    batch_job()
    print("Batch job completed")

    while True:
        time.sleep(1)

此外,在使用客户端库时, Prometheus_client HTTP Server 会公开 /metrics 端点中的指标。

Prometheus 拥有几乎所有编程语言的客户端库,如果你想创建客户端库,你也可以这样做。

要了解更多创建指南和查看客户端库列表,你可以参考官方文档。

Prometheus 告警管理器

Alertmanager 是 Prometheus 监控系统的关键部分。它的主要工作是根据 Prometheus 告警配置中设置的指标阈值发送告警。

告警由 Prometheus 触发并发送到 Alertmanager。它反过来将告警发送到告警管理器配置中配置的相应通知系统 / 接收器(电子邮件、slack 等)。

此外,告警管理器还负责以下工作。

  1. Alert Deduplicating:消除重复告警的过程
  2. Grouping:将相关告警分组在一起的过程
  3. Silencing:静默维护或误报告警
  4. Routing:根据严重性将告警路由到适当的接收者
  5. Inhibition:当存在中高严重性告警时停止低严重性告警的过程

Prometheus Alert Manager

以下是告警规则的配置示例。

groups:
- name: microservices_alerts
  rules:
  - record: http_latency:average_latency_seconds
    expr: sum(http_request_duration_seconds_sum) / sum(http_request_duration_seconds_count)
  - alert: HighLatencyAlert
    expr: http_latency:average_latency_seconds > 0.5
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "High latency detected in microservices"
      description: "The average HTTP latency is high ({{ $value }} seconds) in the microservices cluster."

这是 Alertmanager 配置文件的路由配置示例

routes:
- match:
    severity: 'critical'
  receiver: 'pagerduty-notifications'

- match:
    severity: 'warning'
  receiver: 'slack-notifications'

告警管理器支持大多数消息和通知系统,例如 Discord、电子邮件、Slack 等,以将告警作为通知发送给接收者。

PromQL

PromQL 是一种灵活的查询语言,可用于从 Prometheus 查询时间序列指标。

我们可以直接从 Prometheus 用户界面使用查询,也可以使用 curl 命令通过命令行界面进行查询。

Prometheus 用户界面

PromQL on Prometheus UI

通过 CLI 查询

curl "http://54.186.154.78:30000/api/v1/query?query=$(echo 'up' | jq -s -R -r @uri)" | jq .

另外,当你将 Prometheus 作为数据源添加到 Grafana 时,你可以使用 PromQL 来查询和创建 Grafana 仪表板,如下所示。

Grafana Dashboard with promQL

结论

这解释了 Prometheus 架构的主要组件,并将给出 Prometheus 配置的基本概述,你还可以使用配置做很多事情。

每个组织的需求会有所不同,Prometheus 在不同环境(例如 VM 和 Kubernetes)中的实现也有所不同。如果你了解基础知识和关键配置,你就可以轻松地在任何平台上实现它。

此外,它还将帮助你准备 Prometheus 认证。

下一步,你可以尝试在 Kubernetes 上设置 Prometheus。