如何将 Prometheus 与 Grafana 集成?有哪些最佳实践和常见坑点?
Prometheus 与 Grafana 集成的架构原理
Prometheus 负责时序数据的采集、存储和告警,Grafana 负责数据的可视化呈现。两者通过 HTTP API 交互:Grafana 作为客户端向 Prometheus 发起 PromQL 查询请求,Prometheus 返回时间序列数据,Grafana 再将数据渲染为图表。理解这个数据流是做好集成的前提。
核心数据链路:应用暴露 /metrics 接口 → Prometheus 通过 pull 模型定时抓取 → 数据存入 TSDB → Grafana 通过 PromQL 查询 → 仪表盘可视化 + 告警。
集成配置详解
添加 Prometheus 数据源
在 Grafana 中进入 Configuration → Data Sources → Add data source,选择 Prometheus 类型,填写以下关键配置:
json{ "name": "Prometheus", "type": "prometheus", "url": "http://prometheus:9090", "access": "proxy", "isDefault": true, "jsonData": { "httpMethod": "POST", "timeInterval": "15s", "customQueryParameters": "" } }
关键参数说明:
- httpMethod: 推荐设为 POST,对于大范围查询性能更好
- timeInterval: 与 Prometheus 的 scrape_interval 保持一致,避免数据对齐问题
- access: 生产环境建议用 proxy 模式,由 Grafana 后端代理请求,避免暴露 Prometheus 地址
也可以通过 provisioning 配置文件自动注册数据源:
yamlapiVersion: 1 datasources: - name: Prometheus type: prometheus url: http://prometheus:9090 access: proxy isDefault: true jsonData: httpMethod: POST timeInterval: 15s editable: true
验证数据源连通性
添加完成后,点击 Save & Test,Grafana 会发送一个查询请求验证连通性。如果报错,排查以下常见问题:
- 网络不通:检查 Prometheus 是否可达(curl http://prometheus:9090/api/v1/status/config)
- 跨域问题:proxy 模式下由 Grafana 后端代理,不存在跨域;direct 模式下需浏览器直连,需配置 CORS
- 认证问题:如果 Prometheus 启用了 basic auth 或 TLS,需要在数据源配置中补充凭证
常用 PromQL 查询示例
CPU 使用率
promql100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
内存使用率
promql(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
磁盘使用率
promql(1 - (node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes)) * 100
网络流量
promqlrate(container_network_receive_bytes_total[5m])
Kubernetes Pod 重启次数
promqlsum by (namespace, pod) (increase(kube_pod_container_status_restarts_total[1h]))
HTTP 请求错误率(5xx 占比)
promqlsum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100
变量与模板配置
变量是构建可复用仪表盘的核心能力,避免为每个实例、命名空间重复创建面板。
常用变量定义
| 变量名 | 类型 | Query | 说明 |
|---|---|---|---|
| instance | Query | label_values(up, instance) | 选择监控实例 |
| namespace | Query | label_values(kube_pod_info, namespace) | 选择 K8s 命名空间 |
| interval | Interval | 30s,1m,5m,15m,1h | 控制查询步长 |
| datasource | Datasource | Prometheus | 支持多数据源切换 |
在面板查询中使用变量语法:
promql# 按 instance 变量过滤 rate(node_cpu_seconds_total{instance="$instance", mode!="idle"}[5m]) # 按 namespace 变量过滤 sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="$namespace"}[5m]))
$__rate_interval 的使用
Grafana 7.2+ 推荐使用 $__rate_interval 替代手动指定区间:
promqlrate(node_cpu_seconds_total{mode="idle"}[$__rate_interval]) * 100
$__rate_interval 会自动计算为 max(scrape_interval * 4, dashboard_refresh_interval),确保 rate 函数始终有足够的数据点,避免断图。
仪表盘设计与组织
仪表盘分层
生产环境建议采用三层仪表盘架构:
- 概览层(Overview):展示系统全局健康状态,使用 Stat 面板 + 红黄绿阈值,一眼发现问题
- 服务层(Service):按服务/应用维度展开,包含请求量、延迟分布、错误率等 SLI 指标
- 实例层(Instance):下钻到具体实例,展示 CPU、内存、磁盘 IO、网络等资源详情
面板类型选择
| 场景 | 推荐面板类型 | 说明 |
|---|---|---|
| 时间序列趋势 | Time Series | 默认首选,支持多条线叠加 |
| 当前值/状态 | Stat | 显示最新值,配合阈值变色 |
| 百分位分布 | Heatmap | 适合延迟分布可视化 |
| 排行/Top N | Bar Chart | 展示资源占用 Top 排名 |
| 表格数据 | Table | 适合多维指标对比 |
告警面板配置
在面板下方添加 Alert 区域,设置 Evaluate every(评估频率)和 For(持续时间),避免瞬时抖动触发告警。
Recording Rules 优化查询性能
当仪表盘中存在耗时较长的聚合查询时,Recording Rules 可以预先计算并存储结果,大幅降低查询延迟。
yamlgroups: - name: cpu_rules interval: 30s rules: - record: job:cpu_usage:rate5m expr: 100 - (avg by (job) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) - name: http_rules interval: 30s rules: - record: job:http_error_rate:rate5m expr: sum by (job) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) * 100
在 Grafana 中直接查询预计算指标:
promqljob:cpu_usage:rate5m{job="my-service"}
Recording Rules 命名规范建议:level:metric:operations,例如 job:cpu_usage:rate5m,便于识别层级和计算逻辑。
告警配置与集成
Grafana Alerting vs Prometheus Alertmanager
两者可以独立使用,也可以组合:
- Grafana Alerting:配置简单,直接在仪表盘上设置,支持 Unified Alerting 统一管理多数据源告警,适合简单场景
- Prometheus Alertmanager:功能更强大,支持告警分组(group_by)、抑制(inhibit_rules)、静默(silences)、路由(routes),适合大规模告警管理
Prometheus 告警规则示例
yamlgroups: - name: node_alerts rules: - alert: HighCpuUsage expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85 for: 5m labels: severity: warning annotations: summary: "High CPU usage on {{ $labels.instance }}" description: "CPU usage is {{ $value }}% (threshold: 85%)" - alert: DiskSpaceLow expr: (1 - (node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes)) * 100 > 90 for: 10m labels: severity: critical annotations: summary: "Disk space low on {{ $labels.instance }}" description: "Disk usage is {{ $value }}% (threshold: 90%)"
Alertmanager 路由配置
yamlroute: group_by: [alertname, cluster] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: default-slack routes: - match: severity: critical receiver: pagerduty-critical repeat_interval: 1h - match: severity: warning receiver: default-slack receivers: - name: default-slack slack_configs: - channel: #monitoring send_resolved: true - name: pagerduty-critical pagerduty_configs: - service_key: <your-key>
Grafana 告警通知渠道
Grafana 支持多种通知渠道:邮件、Slack、Webhook、钉钉、企业微信、PagerDuty 等。在 Alerting → Contact Points 中配置,并在 Notification Policies 中设置路由规则。
高可用与生产级部署
Prometheus 高可用方案
单点 Prometheus 存在单点故障风险,生产环境常见两种高可用方案:
- 多实例并行:部署两个以上相同配置的 Prometheus 实例,各自独立抓取和存储数据,Grafana 配置多个数据源并用 Load Balance 模式查询
- 远程写入(Remote Write):Prometheus 将数据远程写入 Thanos / Cortex / Mimir 等长期存储后端,Grafana 从统一存储查询
Grafana 高可用
Grafana 本身无状态,多个实例共享同一个数据库(MySQL/PostgreSQL)即可实现高可用。注意关闭告警的 HA 降级(设置 ha_peer_name)。
数据保留策略
yaml# prometheus.yml global: scrape_interval: 15s evaluation_interval: 15s # 启动参数 --storage.tsdb.retention.time=30d --storage.tsdb.retention.size=50GB
短期数据保留在 Prometheus 本地 TSDB,长期数据通过 Remote Write 归档到对象存储。
导入社区仪表盘
Grafana 官方维护了大量开源仪表盘模板:
- 访问 grafana.com/grafana/dashboards 搜索
- 常用 ID:Node Exporter Full(1860)、Kubernetes 集群监控(7249)、Spring Boot Statistics(12900)
- 在 Grafana 中通过 Dashboards → Import → 输入 ID 即可导入
导入后需要根据实际环境调整变量和查询,避免指标名称不匹配导致面板无数据。
常见坑点与排障
- rate 函数区间过短:scrape_interval 为 15s 时,rate(xxx[1m]) 可能因数据点不足出现断图,建议区间至少为 4 倍 scrape_interval 或使用 $__rate_interval
- 时区不一致:Prometheus 使用 UTC,Grafana 默认跟随浏览器时区,告警时间判断需注意转换
- 标签冲突:不同 job 采集的相同指标可能标签不一致,导致查询结果缺失,建议统一标签规范
- 大范围查询超时:查询 30 天以上数据时容易超时,应使用 Recording Rules 预聚合,或配置 Prometheus 的 --query.timeout 参数
- Dashboard JSON 版本不兼容:Grafana 大版本升级后,旧仪表盘 JSON 格式可能变化,升级前做好备份