Prometheus:云原生时代的监控与告警基石
在当今复杂的分布式系统环境中,对系统进行有效监控和快速告警至关重要。一个强大的监控系统能够帮助我们理解应用程序和基础设施的运行状态,及时发现问题、定位故障,并为容量规划和性能优化提供数据支持。在众多的监控解决方案中,Prometheus 以其独特的设计理念、强大的功能以及在云原生领域的广泛应用,脱颖而出,成为事实上的标准。
本文将深入介绍 Prometheus 的官方定义、核心概念、架构设计,并提供一份详尽的快速入门指南,帮助您从零开始搭建并体验 Prometheus 的强大能力。
第一部分:Prometheus 官方介绍与核心概念
Prometheus 起源于 SoundCloud,于 2012 年开始构建,灵感来自于 Google 的 Borgmon 监控系统。自 2015 年开源以来,它凭借其强大的功能和灵活的设计,迅速在云原生社区流行起来。2016 年,Prometheus 成为继 Kubernetes 之后,第二个加入云原生计算基金会(CNCF)的项目,并于 2018 年成功从 CNCF 毕业,标志着其成熟度和稳定性。
Prometheus 是一个开源的系统监控和告警工具包。它以拉取(pull)方式工作,定期从配置好的目标(target)收集指标数据,并将其存储在一个时间序列数据库(Time Series Database, TSDB)中。它提供强大的查询语言 PromQL,用于分析和聚合这些数据,并通过 Alertmanager 处理告警。
Prometheus 的核心设计哲学和特点:
- 多维数据模型 (Multi-dimensional Data Model): 这是 Prometheus 最具辨识度的特点。所有采集到的指标数据都以时间序列的形式存储,每个时间序列由一个指标名称(metric name)和一组键值对(labels)唯一标识。例如,
http_requests_total{method="POST", handler="/api/users"}
表示 HTTP POST 请求到/api/users
路径的总数。Labels 允许您在不改变指标名称的情况下,对同一指标进行多维度的细分和过滤,这极大地提高了查询和分析的灵活性。 - 拉取模型 (Pull Model): Prometheus Server 定期主动从目标 endpoint(通常是应用程序或服务的
/metrics
HTTP 端点)拉取指标数据。这种模式简化了目标的配置,无需目标主动向监控系统推送数据。同时,拉取模型也更容易处理目标短暂离线的情况。当然,对于一些短暂的或无法暴露 HTTP 端点批处理作业,Prometheus 也提供了 Pushgateway 来配合使用。 - 强大的查询语言 (PromQL): Prometheus Query Language (PromQL) 是一门灵活的功能性查询语言,允许用户对时间序列数据进行选择和聚合。无论是简单的指标值查询,还是复杂的计算(如比率、增长率、平均值),或是对多个时间序列进行关联操作,PromQL 都能胜任。
- 自治的服务端 (Autonomous Server): Prometheus Server 是一个独立的组件,不依赖于分布式存储或其他复杂的外部服务。这使得它易于部署和管理。
- 时间序列数据库 (Time Series Database – TSDB): Prometheus 内建了一个高效的时间序列数据库,优化了时间序列数据的存储和查询。数据按时间排序,查询速度快。
- 告警 (Alerting): Prometheus 支持基于 PromQL 定义告警规则。当规则表达式的结果满足特定条件时,Prometheus 会将告警发送到 Alertmanager。
- 多种服务发现方式 (Service Discovery): Prometheus 可以集成多种服务发现机制(如 Kubernetes, Consul, EC2 等),自动发现需要监控的目标,无需手动配置每个实例的地址。
- 易于操作和维护 (Easy to Operate and Maintain): 得益于其简单的架构和单一的二进制文件,Prometheus Server 的部署和维护相对简单。
Prometheus 架构概览:
Prometheus 的架构由多个组件组成,它们协同工作:
- Prometheus Server: 这是核心组件,包含:
- Retrieval Component (Scraper): 负责根据配置发现目标,并定期从目标的
/metrics
endpoint 拉取数据。 - Time Series Database (TSDB): 负责存储采集到的时间序列数据。
- HTTP Server: 提供 Web UI 和 API 接口,用于查询数据、管理配置和规则。
- Rule Manager/Evaluator: 负责评估告警规则和记录规则,并将触发的告警发送给 Alertmanager。
- Retrieval Component (Scraper): 负责根据配置发现目标,并定期从目标的
- Client Libraries: 用于应用程序代码中,方便开发者暴露符合 Prometheus 格式的指标。支持多种编程语言。
- Exporters: 这是一个重要概念。由于并非所有系统都能直接暴露 Prometheus 格式的指标,Exporters 充当翻译器的角色。它们采集第三方系统的指标(如主机操作系统、数据库、消息队列等),并将其转换为 Prometheus 可以拉取的格式。常见的 Exporters 包括:
node_exporter
: 采集主机操作系统(Linux/Unix)的硬件和操作系统指标。mysqld_exporter
: 采集 MySQL 数据库指标。blackbox_exporter
: 用于对端点(HTTP, TCP, ICMP, DNS)进行黑盒探测。kube-state-metrics
(Kubernetes): 采集 Kubernetes API 对象的指标。
- Pushgateway: 用于处理那些生命周期短暂、无法等待 Prometheus 来拉取指标的批处理作业或服务。作业将指标推送到 Pushgateway,然后 Prometheus 再从 Pushgateway 拉取。
- Alertmanager: 独立于 Prometheus Server 运行。负责接收来自 Prometheus Server 的告警,并进行分组、去重、静默,最后路由到接收方(如邮件、Slack、PagerDuty 等)。
- Visualization & Dashboards: Prometheus 内建了一个简单的 Web UI 用于查询和图形化展示。但更常见的是与 Grafana 集成,利用 Grafana 丰富的 Dashboard 功能来构建专业的监控面板。
指标类型 (Metric Types):
Prometheus 定义了几种核心的指标类型:
- Counter (计数器): 一种单调递增的累计指标,只能增加,不能减少。常用于统计请求总数、完成的任务总数、错误总数等。
- 示例:
http_requests_total
- 示例:
- Gauge (仪表盘): 表示一个可以任意上下波动的指标值。常用于度量当前值,如内存使用量、CPU 使用率、队列长度、温度等。
- 示例:
node_memory_MemAvailable_bytes
- 示例:
- Histogram (直方图): 对观测值(如请求耗时、响应大小)进行采样,并将其分布在可配置的桶(buckets)中。它会暴露
_bucket
,_sum
, 和_count
三个时间序列,可以用来计算分位数 (quantiles)。- 示例:
http_request_duration_seconds
- 示例:
- Summary (摘要): 类似于 Histogram,也对观测值进行采样。但它在客户端计算可配置的分位数,并暴露
_count
,_sum
, 以及计算出的分位数(如_0.99
)。相比 Histogram,Summary 的分位数计算在客户端完成,消耗更多客户端资源,且不适用于聚合不同实例的数据。通常推荐使用 Histogram。- 示例:
rpc_durations_seconds
- 示例:
理解这些核心概念和架构组件,是有效使用 Prometheus 的基础。接下来,我们将进入快速入门部分,通过实际操作来体验 Prometheus。
第二部分:Prometheus 快速入门指南
本部分将指导您在 Linux 或 macOS 环境下,下载、安装、配置并运行 Prometheus Server,并添加一个简单的监控目标(Node Exporter),最后使用 PromQL 进行简单的查询。
前提条件:
- 一台运行 Linux 或 macOS 的计算机。
- 具备基本的命令行操作能力。
- 稳定的网络连接用于下载文件。
步骤 1:下载 Prometheus 和 Node Exporter
访问 Prometheus 官方下载页面 (https://prometheus.io/download/)。找到最新版本的 Prometheus 和 Node Exporter。
以下以 Linux 为例进行操作,版本号可能需要根据官网最新版本进行调整(这里使用示例版本号):
“`bash
创建一个工作目录
mkdir prometheus_quickstart
cd prometheus_quickstart
下载 Prometheus (请替换为官网提供的最新版本链接)
例如:wget https://github.com/prometheus/prometheus/releases/download/v2.47.1/prometheus-2.47.1.linux-amd64.tar.gz
wget
下载 Node Exporter (请替换为官网提供的最新版本链接)
例如:wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
wget
解压 Prometheus
tar -xvf prometheus-*.tar.gz
进入解压后的 Prometheus 目录
cd prometheus-.-amd64/
返回工作目录
cd ..
解压 Node Exporter
tar -xvf node_exporter-*.tar.gz
进入解压后的 Node Exporter 目录
cd node_exporter-.-amd64/
返回工作目录
cd ..
现在 prometheus_quickstart 目录下应该有两个解压后的目录:
一个是 prometheus-X.Y.Z.linux-amd64
一个是 node_exporter-X.Y.Z.linux-amd64
ls
“`
步骤 2:配置 Prometheus
Prometheus 的核心配置文件是 prometheus.yml
。在解压后的 Prometheus 目录中已经有一个默认的 prometheus.yml
文件。我们将基于此文件进行修改。
进入 Prometheus 解压后的目录:
bash
cd prometheus-*.*-amd64/
使用文本编辑器打开 prometheus.yml
文件(例如 nano
或 vim
):
bash
nano prometheus.yml
默认的 prometheus.yml
文件通常包含以下基本结构:
“`yaml
global:
scrape_interval: 15s # 默认的抓取间隔
evaluation_interval: 15s # 默认的规则评估间隔
alerting:
alertmanagers:
– static_configs:
– targets:
# – alertmanager:9093 # 默认 Alertmanager 地址,这里先注释掉
rule_files:
# – “first_rules.yml” # 默认的规则文件,这里先注释掉
scrape_configs:
# Prometheus 自身监控
– job_name: “prometheus”
static_configs:
– targets: [“localhost:9099”] # Prometheus 默认暴露指标的端口是 9090,这里需要修改
# 添加 Node Exporter 监控任务
– job_name: “node_exporter”
static_configs:
– targets: [“localhost:9100”] # Node Exporter 默认暴露指标的端口是 9100
“`
修改 prometheus.yml
:
- 找到
job_name: "prometheus"
的配置块。Prometheus 自身会暴露其内部指标在默认端口 9090 上。将targets
修改为["localhost:9090"]
。 - 添加一个新的
scrape_configs
配置块,用于监控 Node Exporter。将job_name
设置为"node_exporter"
,static_configs
中的targets
设置为 Node Exporter 默认暴露指标的端口["localhost:9100"]
。
修改后的 prometheus.yml
示例:
“`yaml
global:
scrape_interval: 15s # 每隔 15 秒抓取一次目标
evaluation_interval: 15s # 每隔 15 秒评估一次告警规则
alerting:
alertmanagers:
– static_configs:
– targets:
# – alertmanager:9093
rule_files:
# – “first_rules.yml”
scrape_configs:
# 监控 Prometheus 自身
– job_name: “prometheus”
# metrics_path defaults to /metrics
# scheme defaults to http.
static_configs:
– targets: [“localhost:9090”] # Prometheus 默认端口
# 监控 Node Exporter
– job_name: “node_exporter”
static_configs:
– targets: [“localhost:9100”] # Node Exporter 默认端口
“`
保存并关闭 prometheus.yml
文件。
步骤 3:运行 Node Exporter
在启动 Prometheus Server 之前,先运行 Node Exporter,让它开始暴露主机的指标。
返回到 prometheus_quickstart
目录,进入 Node Exporter 解压后的目录:
bash
cd ../node_exporter-*.*-amd64/
运行 Node Exporter:
bash
./node_exporter
Node Exporter 启动后,会在终端打印日志,其中会显示它监听的地址和端口(默认为 0.0.0.0:9100
)。保持这个终端窗口开启,或者在后台运行 Node Exporter。
您可以通过浏览器访问 http://localhost:9100/metrics
来查看 Node Exporter 暴露的原始指标数据。
步骤 4:运行 Prometheus Server
现在 Node Exporter 已经在运行并暴露指标了,我们可以启动 Prometheus Server 来抓取这些指标。
返回到 prometheus_quickstart
目录,进入 Prometheus 解压后的目录:
bash
cd ../prometheus-*.*-amd64/
运行 Prometheus Server,并指定我们刚刚修改过的配置文件:
bash
./prometheus --config.file=prometheus.yml
Prometheus Server 启动后,会在终端打印大量的日志。您会看到它加载配置、发现目标、开始抓取等信息。
保持这个终端窗口开启,或者在后台运行 Prometheus Server。
步骤 5:访问 Prometheus Web UI
Prometheus Server 启动后,您可以通过浏览器访问其 Web UI,默认地址是 http://localhost:9090
。
在浏览器中输入 http://localhost:9090
,您将看到 Prometheus 的 Web 界面。
Web UI 主要包含以下几个部分:
- Graph (图形): 这是最常用的部分,用于输入 PromQL 查询表达式并可视化结果。
- Alerts (告警): 显示当前的告警规则状态和已触发的告警。
- Status (状态): 显示 Prometheus Server 的运行状态信息,如命令行参数、配置、运行时信息、抓取目标列表等。
- Configuration (配置): 显示 Prometheus 当前加载的配置内容。
- TSDB Status: 显示时间序列数据库的状态和信息。
步骤 6:验证抓取目标和进行查询
在 Prometheus Web UI 中,导航到 Status -> Targets 页面。
您应该会看到两个抓取任务(jobs):prometheus
和 node_exporter
。每个任务下面应该有一个目标实例(localhost:9090
和 localhost:9100
)。如果一切正常,它们的状态应该是 UP,表示 Prometheus 成功地从这些目标拉取到了数据。
现在,我们回到 Graph 页面,尝试进行一些 PromQL 查询。
简单的 PromQL 查询示例:
- 查询 Prometheus 自身的 UP 状态:
- 在表达式输入框中输入
up{job="prometheus"}
- 点击 “Execute” 按钮。
- 结果应该显示一个时间序列,其值为
1
,表示 Prometheus 目标是健康的(UP)。
- 在表达式输入框中输入
- 查询 Node Exporter 的 UP 状态:
- 在表达式输入框中输入
up{job="node_exporter"}
- 点击 “Execute” 按钮。
- 结果应该显示一个时间序列,其值为
1
,表示 Node Exporter 目标是健康的(UP)。
- 在表达式输入框中输入
- 查询主机的可用内存 (bytes): Node Exporter 暴露的指标之一是
node_memory_MemAvailable_bytes
。- 在表达式输入框中输入
node_memory_MemAvailable_bytes
- 点击 “Execute” 按钮。
- 切换到 “Graph” 标签页,可以看到可用内存随时间变化的曲线图。
- 在表达式输入框中输入
- 查询 CPU 使用率 (近似值): CPU 时间通常以 Counter 类型暴露,需要使用
rate()
函数计算其增长率来近似表示使用率。- Node Exporter 暴露的 CPU 指标是
node_cpu_seconds_total
,它带有mode
label (如 idle, user, system) 和cpu
label (如 0, 1, all)。 - 查询所有 CPU 的非空闲使用时间增长率:
rate(node_cpu_seconds_total{mode!="idle"}[5m])
rate()
: 计算时间序列在时间窗口内的平均每秒增长率。[5m]
: 表示时间窗口为过去 5 分钟。mode!="idle"
: 过滤掉空闲模式的 CPU 时间。
- 查询所有 CPU 的总使用率:
1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
mode="idle"
: 只选择空闲模式的 CPU 时间。rate(...[5m])
: 计算空闲时间每秒增长率。avg by (instance)
: 对所有 CPU 的空闲时间增长率求平均,得到整个 instance(即这台主机)的平均空闲时间增长率。1 - ...
: 用 1 减去空闲率,得到忙碌率(近似使用率)。
- 在表达式输入框中输入
1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
- 点击 “Execute”,切换到 “Graph” 查看图形。
- Node Exporter 暴露的 CPU 指标是
步骤 7:初步了解告警规则 (Optional)
虽然完整的 Alertmanager 配置超出了快速入门的范围,但我们可以简单了解如何在 Prometheus 中定义告警规则。
回到 Prometheus 解压后的目录。创建一个名为 alert.rules.yml
的文件:
bash
nano alert.rules.yml
在 alert.rules.yml
中添加一个简单的规则,例如当 Node Exporter 目标宕机时触发告警:
yaml
groups:
- name: example
rules:
- alert: NodeExporterDown
expr: up{job="node_exporter"} == 0
for: 1m # 持续 1 分钟满足条件才触发告警
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} of job {{ $labels.job }} is down"
description: "{{ $labels.instance }} has been down for more than 1 minute."
这个规则定义了一个名为 NodeExporterDown
的告警。当 PromQL 表达式 up{job="node_exporter"} == 0
持续满足 1 分钟时,告警就会被触发。labels
和 annotations
提供了关于告警的元数据和描述信息。
修改 prometheus.yml
文件,取消 rule_files
的注释,并指定刚刚创建的规则文件:
“`yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
– static_configs:
– targets: [] # 这里暂时不配置 Alertmanager
rule_files:
– “alert.rules.yml” # 指定规则文件
scrape_configs:
– job_name: “prometheus”
static_configs:
– targets: [“localhost:9090”]
- job_name: “node_exporter”
static_configs:- targets: [“localhost:9100”]
“`
- targets: [“localhost:9100”]
保存并关闭 prometheus.yml
。重启 Prometheus Server 使配置生效。
“`bash
在 Prometheus 目录下
pkill prometheus # 杀死正在运行的 Prometheus 进程
./prometheus –config.file=prometheus.yml # 重新启动
“`
在 Prometheus Web UI 中,导航到 Status -> Rules 页面,您应该能看到刚刚加载的 NodeExporterDown
告警规则。导航到 Alerts 页面,如果 Node Exporter 正在运行,这个告警的状态应该是 Inactive。如果您停止 Node Exporter,稍等一分钟,这个告警的状态就会变成 Pending 或 Firing。
步骤 8:清理
完成实验后,您可以停止 Prometheus Server 和 Node Exporter 进程,并删除创建的文件和目录:
“`bash
在终端中,找到运行 Prometheus 和 Node Exporter 的窗口,按下 Ctrl+C 停止它们。
如果在后台运行,可以使用 pkill 命令:
pkill prometheus
pkill node_exporter
返回工作目录并删除文件
cd .. # 返回到 prometheus_quickstart 目录
rm -rf prometheus-.-amd64/ node_exporter-.-amd64/ prometheus-.tar.gz node_exporter-.tar.gz
“`
总结与展望
通过这篇详细的官方介绍和快速入门指南,您应该对 Prometheus 的核心概念、架构以及基本使用方法有了初步的了解。您学会了如何:
- 理解 Prometheus 的多维数据模型和拉取模型。
- 下载和安装 Prometheus Server 和 Node Exporter。
- 配置
prometheus.yml
来指定监控目标。 - 运行 Prometheus Server 和 Node Exporter。
- 访问 Prometheus Web UI 并验证抓取目标。
- 使用 PromQL 进行简单的指标查询和可视化。
- 初步了解告警规则的定义。
这只是 Prometheus 功能的冰山一角。要充分发挥 Prometheus 的能力,您还需要进一步学习:
- 更高级的 PromQL 函数和表达式。
- 如何编写自定义 Exporter 来监控自己的应用程序。
- 更深入地理解和配置 Alertmanager,实现灵活的告警路由和处理。
- 集成 Grafana 构建功能强大的监控面板。
- 使用服务发现机制自动管理监控目标。
- Prometheus 的存储扩展(如远程存储)。
Prometheus 凭借其简洁高效的设计和强大的功能,已经成为云原生监控领域的首选工具。投入时间学习和掌握 Prometheus,将极大地提升您在构建、维护和排查现代分布式系统时的效率和能力。
希望这篇指南能为您探索 Prometheus 的旅程提供一个坚实的基础!