前言
“没有监控的运维等于裸奔”。Prometheus + Grafana 是云原生时代监控的事实标准,这篇从架构到实操搭一套最小可用体系。
一、架构与核心概念
┌─ 被监控目标 ────────────┐
│ node_exporter (主机) │ ┌─────────────┐ ┌───────────┐
│ mysqld_exporter (DB) │◄────┤ Prometheus │───►│ Alertmanager ─► 钉钉/邮件
│ 应用 /metrics 端点 │ 拉取 │ (TSDB+采集) │ └───────────┘
└─────────────────────────┘ └──────┬──────┘
│ PromQL 查询
┌────▼─────┐
│ Grafana │ ── 可视化大盘
└──────────┘
关键设计:Pull 模型——Prometheus 主动周期性抓取目标的 /metrics 端点,数据存本地时序库(TSDB)。
指标四类型:
| 类型 | 语义 | 示例 |
|---|---|---|
| Counter | 只增不减的计数器 | http_requests_total |
| Gauge | 可增可减的瞬时值 | memory_usage_bytes |
| Histogram | 分桶统计分布 | 请求耗时分布(P99 就靠它) |
| Summary | 分位数 | 直接给 P50/P99 |
指标命名惯例:<namespace>_<name>_<unit>,如 http_requests_total。
二、快速搭建(Docker Compose)
# docker-compose.yml
services:
prometheus:
image: prom/prometheus:v2.53.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./rules/:/etc/prometheus/rules/
ports: ["9090:9090"]
node-exporter:
image: prom/node-exporter:v1.8.1
pid: "host"
command:
- --path.rootfs=/host
volumes:
- /:/host:ro,readonly
alertmanager:
image: prom/alertmanager:v0.27.0
ports: ["9093:9093"]
grafana:
image: grafana/grafana:11.1.0
ports: ["3000:3000"]
volumes:
- grafana-data:/var/lib/grafana
volumes:
grafana-data:
prometheus.yml:
global:
scrape_interval: 15s
rule_files:
- /etc/prometheus/rules/*.yml
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs:
- job_name: "prometheus"
static_configs: [{targets: ["localhost:9090"]}]
- job_name: "node"
static_configs: [{targets: ["node-exporter:9100"]}]
docker compose up -d
# 验证: 浏览器开 http://服务器IP:9090/targets —— 两个 job 都是 UP
三、PromQL 入门(核心中的核心)
# 在 Prometheus Web UI (9090) 的 Graph 里练习
# 1. 即时查询
node_cpu_seconds_total # 原始序列(按 cpu/mode 多条)
# 2. 过滤标签 {}
node_cpu_seconds_total{mode="idle"}
# 3. rate(): Counter 必须配 rate 才有意义(每秒增长率)
rate(node_cpu_seconds_total{mode="idle"}[5m])
# 4. 聚合
avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
# 5. 运算: CPU 使用率 = 1 - 空闲率
100 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
# 6. 常用函数
node_memory_MemAvailable_bytes / 1024 / 1024 / 1024 # 可用内存(GB)
100 - node_filesystem_avail_bytes{mountpoint="/"}
/ node_filesystem_size_bytes{mountpoint="/"} * 100 # 根盘使用率%
# 7. histogram 的 P99(假设暴露了 http_request_duration_seconds)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
# 8. 一分钟增量
increase(node_network_receive_bytes_total[1m])
四、告警规则
rules/host.yml:
groups:
- name: host-alerts
rules:
- alert: HostDown
expr: up{job="node"} == 0
for: 1m
labels: {severity: critical}
annotations:
summary: "主机 {{ $labels.instance }} 宕机"
description: "已失联超过 1 分钟"
- alert: HighCPU
expr: 100 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 85
for: 5m # 持续 5 分钟才报(防毛刺)
labels: {severity: warning}
annotations:
summary: "{{ $labels.instance }} CPU 过高"
description: "当前使用率 {{ $value | printf \"%.1f\" }}%"
- alert: DiskWillFull
expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[1h], 4*3600) < 0
for: 10m
annotations:
summary: "{{ $labels.instance }} 根盘预计 4 小时内写满"
for 的意义:条件先持续满足一段时间才触发,大幅减少误报。
Alertmanager 路由(分组/抑制/静默):
route:
group_by: ["alertname", "instance"]
group_wait: 30s
receiver: dingtalk
receivers:
- name: dingtalk
webhook_configs:
- url: "http://dingtalk-webhook/..." # 或用 prometheus-webhook-dingtalk
五、Grafana 出图
1. 打开 http://IP:3000 (admin/admin 首次改密)
2. Connections → Data source → Prometheus → URL: http://prometheus:9090
3. Dashboards → Import → 输入 1860(Node Exporter Full 官方大盘)
4. 秒得一张专业主机监控大屏
自建 Panel 的查询示例——“各实例内存使用率”:
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
六、应用侧暴露指标
Go 应用一行接入:
import "github.com/prometheus/client_golang/prometheus/promhttp"
http.Handle("/metrics", promhttp.Handler())
四个黄金指标(Google SRE):延迟、流量、错误率、饱和度——给自己的服务都暴露这四类,监控就及格了。
七、常见坑
| 现象 | 原因 |
|---|---|
| targets 显示 DOWN | 网络不通/端口错;点开 error 看具体原因 |
| 图表没数据 | Counter 没 rate;时间范围/步长不合理 |
| 告警风暴 | 没配 for、没分组 |
| 长期存储 | 本地 TSDB 有限;上 VictoriaMetrics/Thanos(进阶) |
| 容器里看不到主机指标 | node-exporter 要挂载宿主 / 且 pid: host |
小结
| 组件 | 职责 |
|---|---|
| exporter | 把系统/应用状态翻译成 /metrics |
| Prometheus | 拉取 + 存储 + 规则计算 |
| PromQL | rate 配 Counter、by 聚合 |
| Alertmanager | 分组、抑制、路由通知 |
| Grafana | 大盘可视化(1860 直接抄) |
本文是「云原生」系列第 7 篇。