Prometheus 入门与部署

概述

Prometheus 是 CNCF 旗下的开源监控系统,以多维时间序列数据模型为核心,支持灵活的 PromQL 查询语言,广泛用于 Kubernetes 环境的指标采集与告警。

核心特性:

  • 多维数据模型(metric + label)
  • PromQL 强大查询能力
  • 不依赖分布式存储,单节点即可支撑大规模指标
  • 支持服务发现(Kubernetes、Consul、DNS 等)
  • 社区生态丰富,Exporter 覆盖几乎所有主流组件

架构

┌─────────────┐     scrape      ┌──────────────┐

│ Exporter │◄────────────────│ Prometheus │

│ (node_exp) │ │ Server │

└─────────────┘ └──────┬───────┘

┌─────────────▼───────────┐

│ TSDB │

│ (时序数据库/本地存储) │

└─────────────┬───────────┘

│ query

┌─────────────▼───────────┐

│ Grafana │

│ (可视化展示) │

└────────────────────────┘

组件说明:

  • Prometheus Server — 核心组件,负责抓取、存储、查询指标
  • Exporters — 被监控端的 HTTP 端点,暴露指标
  • Alertmanager — 告警触发后的路由、去重、抑制、通知
  • Pushgateway — 支持短生命周期任务的指标推送

快速部署(Docker Compose)

version: '3.8'

services:

prometheus:

image: prom/prometheus:v2.47.0

container_name: prometheus

restart: unless-stopped

volumes:

  • ./prometheus.yml:/etc/prometheus/prometheus.yml
  • ./prometheus_data:/prometheus

command:

  • '--config.file=/etc/prometheus/prometheus.yml'
  • '--storage.tsdb.path=/prometheus'
  • '--web.console.libraries=/usr/share/prometheus/console_libraries'
  • '--web.console.templates=/usr/share/prometheus/consoles'
  • '--web.enable-lifecycle'

ports:

  • "9090:9090"

alertmanager:

image: prom/alertmanager:v0.26.0

container_name: alertmanager

restart: unless-stopped

volumes:

  • ./alertmanager.yml:/etc/alertmanager/alertmanager.yml

ports:

  • "9093:9093"

command:

  • '--config.file=/etc/alertmanager/alertmanager.yml'
  • '--storage.path=/alertmanager'

配置文件解析

# prometheus.yml

global:

scrape_interval: 15s # 全局抓取间隔(默认 1m)

evaluation_interval: 15s # 规则评估间隔

external_labels:

cluster: 'prod'

env: 'production'

alerting:

alertmanagers:

  • static_configs:
  • targets:
  • 'alertmanager:9093'

rule_files:

  • "rules/*.yml"

scrape_configs:

# Prometheus 自身监控

  • job_name: 'prometheus'

static_configs:

  • targets: ['localhost:9090']

# Kubernetes Node Exporter

  • job_name: 'kubernetes-nodes'

kubernetes_sd_configs:

  • role: node

relabel_configs:

  • source_labels: [__address__]

regex: '(.*):10250'

replacement: '${1}:9100'

target_label: __address__

# Kubernetes Pods(自动发现)

  • job_name: 'kubernetes-pods'

kubernetes_sd_configs:

  • role: pod

relabel_configs:

  • source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]

action: keep

regex: true

服务发现配置

Kubernetes SD

# 自动发现集群内所有 Pod

  • job_name: 'kubernetes-pods'

kubernetes_sd_configs:

  • role: pod

api_server: "https://kubernetes.default.svc:443"

tls_config:

ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

relabel_configs:

# 只保留带有 prometheus.io/scrape=true 注解的 Pod

  • source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]

action: keep

regex: true

# 从注解中覆盖抓取路径

  • source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]

action: replace

target_label: __metrics_path__

regex: (.+)

# 从注解中提取端口

  • source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]

action: replace

regex: '([^:]+):(\d+)'

replacement: '${1}:${2}'

target_label: __address__

Consul SD

- job_name: 'consul-services'

consul_sd_configs:

  • server: 'consul.service.consul:8500'

datacenter: dc1

relabel_configs:

  • source_labels: [__meta_consul_service]

target_label: service

  • source_labels: [__meta_consul_tags]

regex: ',production,'

action: keep

常用 PromQL 示例

# CPU 使用率(每核平均)

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

内存使用率

100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))

请求率(按服务聚合)

sum by (service) (rate(http_requests_total[5m]))

P99 延迟

histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

5xx 错误率

sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100

活跃连接数

sum by (instance) (node_network_receive_bytes_total{device!="lo"})

告警规则示例

# rules/node.yml

groups:

  • name: node-alerts

interval: 30s

rules:

  • alert: HighCPU

expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80

for: 5m

labels:

severity: warning

team: ops

annotations:

summary: "实例 {{ $labels.instance }} CPU 使用率超过 80%"

description: "当前 CPU 使用率:{{ $value | printf \"%.2f\" }}%"

  • alert: MemoryHigh

expr: 100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) > 85

for: 5m

labels:

severity: critical

annotations:

summary: "内存压力告警 {{ $labels.instance }}"

  • alert: DiskSpaceLow

expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes < 0.1

for: 10m

labels:

severity: warning

数据保留策略

# 启动参数设置保留时间

prometheus --storage.tsdb.retention.time=15d --storage.tsdb.retention.size=10GB --storage.tsdb.wal-compression

升级与维护

# 热重载配置(无需重启)

curl -X POST http://localhost:9090/-/reload

查看_targets 健康状态

curl -s http://localhost:9090/api/v1/targets | jq '.data.activeTargets'

检查规则语法

promtool check rules rules/*.yml

快照备份

curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot

性能调优

参数 默认值 建议值 说明
scrape_interval 1m 15s~30s 抓取间隔,越短存储越大
evaluation_interval 1m 15s~30s 规则评估间隔
query_timeout 2m 10m 查询超时时间
max_samples 5000万 按需调整 单次查询最大样本数

常见问题

Q: Prometheus OOM?

A: 减少 scrape_interval,或启用 query_timeout 限制长时间查询。检查是否有大量高 cardinality 标签(如 user_id、request_id)。

Q: Target 显示 DOWN?

A: 检查网络连通性、防火墙、目标服务是否正常运行,确认 /metrics 端点可访问。

Q: 查询缓慢?

A: 使用 rate() 替代 increase(),避免大时间范围的 sum() 无标签聚合。