Prometheus

技术栈
工具链
监控时序数据库告警云原生Metrics

概览

Prometheus

Prometheus 是 SoundCloud 于 2012 年开源的系统监控和告警工具包,现为 CNCF 毕业项目。它已成为云原生监控的事实标准。

核心价值:基于多维时间序列数据的 Pull 模型监控。通过 PromQL 灵活查询,配合 Alertmanager 实现告警路由。

关键特性

  • 多维数据模型(Metric 名 + Key/Value 标签)
  • PromQL 强大查询语言
  • 不依赖分布式存储,单节点自治
  • Pull 模式采集 + Pushgateway 支持短生命周期
  • 服务发现(K8s、Consul、EC2 等)
  • 告警规则引擎 + Alertmanager 分组/抑制/静默

安装

1. 环境准备

  • 操作系统:Linux(推荐)、macOS、Docker
  • 端口:9090(Prometheus UI)、9093(Alertmanager)
  • 磁盘:时序数据持续写入,SSD 推荐,预留足够空间
  • 时间同步:NTP 时间同步非常重要

2. 安装命令

Docker 快速体验

# Prometheus
docker run -d --name prometheus -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

# Alertmanager(可选)
docker run -d --name alertmanager -p 9093:9093 \
  prom/alertmanager

Docker Compose(推荐)

version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.enable-lifecycle'
      - '--storage.tsdb.retention.time=15d'
    restart: unless-stopped

volumes:
  prometheus-data:

Linux 手动安装

# 下载解压
wget https://github.com/prometheus/prometheus/releases/download/v2.50.0/prometheus-2.50.0.linux-amd64.tar.gz
tar -xzf prometheus-2.50.0.linux-amd64.tar.gz
cd prometheus-2.50.0.linux-amd64

# 创建 systemd 服务
sudo cp prometheus /usr/local/bin/
sudo cp promtool /usr/local/bin/
sudo mkdir -p /etc/prometheus /var/lib/prometheus

sudo tee /etc/systemd/system/prometheus.service <;<EOF
[Unit]
Description=Prometheus
After=network-online.target

[Service]
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --web.enable-lifecycle
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now prometheus

macOS

brew install prometheus
prometheus --config.file=$(brew --prefix)/etc/prometheus.yml

3. 常见安装问题

问题 解决方案
err="opening storage failed" 存储目录权限不足:chown -R prometheus:prometheus /var/lib/prometheus
Target 状态 DOWN 检查 exporter 是否运行、防火墙规则、scrape_interval 太久
内存占用高 减少 storage.tsdb.retention.time,调整 --storage.tsdb.max-block-duration
配置热重载不生效 使用 --web.enable-lifecyclecurl -X POST http://localhost:9090/-/reload

示例

Prometheus + Node Exporter 主机监控

目标

使用 Node Exporter 采集主机指标,Prometheus 抓取并展示,配置 CPU 告警规则。

完整配置

prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: 'production'
    region: 'cn-east'

# 告警规则文件
rule_files:
  - 'alerts.yml'

# 抓取配置
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100', '192.168.1.11:9100', '192.168.1.12:9100']
        labels:
          env: 'production'
    # 抓取指标过滤(减少数据量)
    metric_relabel_configs:
      - source_labels: [__name__]
        regex: 'node_(cpu|memory|disk|network|filesystem).*'
        action: keep

alerts.yml

groups:
- name: host-alerts
  rules:
  - alert: HighCPUUsage
    expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) >; 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "主机 {{ $labels.instance }} CPU 使用率 > 80%"
      description: "当前值: {{ $value }}%,持续 5 分钟"

  - alert: HostOutOfMemory
    expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 >; 90
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "主机 {{ $labels.instance }} 内存不足"
      description: "可用内存仅 {{ $value | humanize }}%"

  - alert: DiskFull
    expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 <; 10
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "磁盘空间不足"

运行步骤

# 1. 启动 Node Exporter
docker run -d --name node-exporter -p 9100:9100 \
  -v /proc:/host/proc:ro -v /sys:/host/sys:ro \
  prom/node-exporter

# 2. 启动 Prometheus
docker run -d --name prometheus -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  -v $(pwd)/alerts.yml:/etc/prometheus/alerts.yml \
  prom/prometheus

# 3. 访问 Prometheus
# http://localhost:9090

# 4. PromQL 查询示例
# CPU 使用率:   100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 内存使用率:   (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 磁盘使用率:   (1 - node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100

预期输出

访问 http://localhost:9090/targets,所有 Target 状态应为 UP。在 Graph 页面执行 PromQL 可看到折线图。

教程

Prometheus 入门教程:PromQL 与告警体系

1. 监控哲学

Prometheus 的核心方法论:

  • 指标(Metrics) 优于日志(Logs)和追踪(Traces)
  • Pull 模型:Prometheus 主动去目标抓数据(而非被动接收)
  • 多维标签:同一个指标可通过标签区分不同维度

2. 四种指标类型

类型 说明 示例 典型函数
Counter 只增不减 HTTP 请求总数 rate() increase()
Gauge 可增可减 内存使用量 avg_over_time()
Histogram 分桶统计 请求延迟分布 histogram_quantile()
Summary 客户端分位数 P99 延迟 (自带 quantile)

3. PromQL 核心语法

基本查询

# 即时向量
node_cpu_seconds_total{mode="idle", instance="host1:9100"}

# 范围向量
node_cpu_seconds_total{mode="idle"}[5m]

# 时间偏移
node_memory_MemAvailable_bytes offset 1h

常用函数

# rate:计算每秒增长率(适合 Counter)
rate(http_requests_total[5m])

# avg by:按标签聚合
avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))

# topk:取前 k 个
topk(3, sum(rate(http_requests_total[5m])) by (endpoint))

# histogram_quantile:计算百分位数
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

4. 告警三件套

Prometheus(规则评估) → Alertmanager(分组/抑制/路由) → 通知渠道

Alertmanager 路由示例

route:
  receiver: 'default'
  routes:
  - match:
      severity: critical
    receiver: 'pagerduty'
  - match:
      severity: warning
    receiver: 'slack'
    continue: true
  - match_re:
      service: "^(db|redis)$"
    receiver: 'dba-team'

5. 高可用方案

  • Thanos / Cortex:长期存储 + 全局视图
  • 联邦:层次化 Prometheus 实例
  • Remote Write:将数据写入 InfluxDB / VictoriaMetrics

6. 思考题

  1. Counter 类型为什么用 rate() 而非直接差值?rate()irate() 的区别?
  2. Histogram 和 Summary 如何选择?各有什么优缺点?
  3. 如何设计告警抑制规则避免"告警风暴"?

参考资料

暂无参考文献