Prometheus —— 拉模型指标采集、时序存储与告警评估的开源标准
Prometheus —— 拉模型指标采集、时序存储与告警评估的开源标准
分类:01 指标采集与时序存储 适用:Linux / 容器 / Kubernetes;单机到数千节点、百万级序列 一句话:pull 采集指标、本地 TSDB 存储、PromQL 查询并评估告警,云原生监控事实标准。 官方:https://prometheus.io/ 授权:Apache License 2.0(开源,无商业阉割)
1. 它解决什么问题
| 痛点 | 做法 |
|---|---|
| agent 协议各异、指标格式不统一 | 统一 /metrics 纯文本 + 多维标签,Exporter 生态覆盖主流组件 |
| 扩缩容节点发现困难 | 拉模型 + 服务发现(static/file/consul/kubernetes_sd)自动感知上下线 |
| 只有当前值,无法做趋势与预测 | 内置 TSDB 保留历史样本,PromQL 支持速率/分位数/线性预测 |
| 告警阈值散落脚本、改一次发版 | rule_files 声明式规则 + promtool 校验 + 热加载 |
| 容器 Pod 频繁重建、维度多 | kubernetes_sd_configs + relabel_configs 动态打标 |
| 各团队大盘口径不一致 | recording rule 固化公共口径,Grafana 统一数据源 |
| 不适合:不存日志原文(用 Loki/ELK)、不做链路追踪(用 Tempo/Jaeger)、非强一致计费/审计(拉模型可漏采、本地存储非分布式)、超高基数标签、纯 Windows 主机(用 windows_exporter)。长期归档与跨集群查询需 remote_write 到 Thanos/Mimir/VictoriaMetrics(以各项目官方文档为准)。 |
2. 核心概念与架构
| 术语 | 含义 |
|---|---|
| Target / Job | 一个 /metrics 端点 / 一组同类抓取配置(job 标签来源) |
| Series / Sample | 指标名+标签集 唯一确定序列;样本 = (timestamp, float64) |
| Metric type | Counter / Gauge / Histogram / Summary(详见 5.3) |
| Exporter / TSDB | 第三方指标转 /metrics 的旁路进程 / head+WAL→每 2h 落 block 并 compaction |
| Relabel | 抓前改标签(relabel_configs)/ 抓后丢样本(metric_relabel_configs) |
| Rule / PromQL | recording 预计算、alerting 告警条件 / 查询表达式语言 |
| Remote write | 把本地样本转发到长期存储 |
exporter / 业务 /metrics ──pull(15s)──► ┌─ scrape manager(服务发现+relabel)
Pushgateway(短任务,push) ────────────► │ │
│ ▼
│ TSDB: head→WAL→block :9090
│ ├─► PromQL / HTTP API ──► Grafana 大盘
│ └─► rule_manager ──► Alertmanager :9093 ──► 通知
└──────────────► remote_write(可选) ──► 长期存储
要点:Prometheus 只评估告警、不发送通知(交给 Alertmanager),不渲染大盘(交给 Grafana)。
3. 安装与部署
3.1 环境准备
| 项 | 要求 |
|---|---|
| 依赖/端口 | 单二进制无外部依赖;仅需 9090/tcp;配套 9100 exporter、9093 AM、9091 Pushgateway 需区分 |
| 时钟 | ⚠️ 全链路 NTP/chrony,偏差会导致样本被判未来时间而丢弃 |
| 磁盘 | SSD;--storage.tsdb.path 分区预留 = 容量估算 ×2(compaction 需临时空间) |
| 内核/资源 | nofile ≥ 65535;内存与活跃序列线性相关(第 9 章),起步 4 GiB / 十万级序列 |
| 版本 | 当前大版本 3.x(含 LTS),精确版本号以官方最新稳定版为准:https://prometheus.io/download/ |
3.2 多种安装方式
<VERSION> 为占位符,下载前到官方下载页确认,本文不绑定固定 tag。
# A. 发行版包(版本滞后,仅实验用);RHEL 系用 EPEL,包名以仓库为准
sudo apt install -y prometheus promtool
# B. 官方二进制 + systemd(生产推荐)
VER=<VERSION>; cd /tmp
curl -LO "https://github.com/prometheus/prometheus/releases/download/v${VER}/prometheus-${VER}.linux-amd64.tar.gz"
tar xzf "prometheus-${VER}.linux-amd64.tar.gz" && cd "prometheus-${VER}.linux-amd64"
sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus
sudo install -m 0755 prometheus promtool /usr/local/bin/
sudo mkdir -p /etc/prometheus/rules /var/lib/prometheus
sudo cp -r consoles console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
# /etc/systemd/system/prometheus.service
[Unit]
After=network-online.target
[Service]
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus --storage.tsdb.retention.time=15d --web.listen-address=127.0.0.1:9090 --web.enable-lifecycle
Restart=always
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/prometheus
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now prometheus
# C. Docker(官方镜像 prom/prometheus 或 quay.io/prometheus/prometheus;tag 以官方最新稳定版为准)
docker volume create prometheus-data
docker run -d --name prometheus -p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml:ro \
-v prometheus-data:/prometheus \
prom/prometheus:<VERSION> --config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus --web.enable-lifecycle
# docker compose 等价:image + volumes 挂配置与 prometheus-data 卷 + command 传同上 flag
⚠️ 容器内数据默认在 /prometheus,不挂卷重启即丢;自定义 command 会覆盖镜像默认参数,所需 flag 必须写全。
# D. K8s:prometheus-community/kube-prometheus-stack(含 Operator/Grafana/AM)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install <release> prometheus-community/kube-prometheus-stack -n <namespace> --create-namespace -f values.yaml
kubectl -n <namespace> get pods -l app.kubernetes.io/name=prometheus
# Operator 模式用 Prometheus / ServiceMonitor / PodMonitor / PrometheusRule CRD 自动生成抓取与规则
3.3 首次启动与验证
promtool check config /etc/prometheus/prometheus.yml # SUCCESS
curl -s http://localhost:9090/-/healthy ; curl -s http://localhost:9090/-/ready # Healthy. / Ready.
curl -sG http://localhost:9090/api/v1/query --data-urlencode 'query=up' | jq '.data.result' # value=["1"]
curl -s http://localhost:9090/api/v1/targets?state=active | jq -r '.data.activeTargets[].health' # up
4. 配置文件详解
主配置 /etc/prometheus/prometheus.yml(容器同路径,--config.file 可覆盖),规则单独放 rule_files(示例见第 6 章)。
| 键 | 作用 / 默认 |
|---|---|
global.scrape_interval / scrape_timeout / evaluation_interval |
抓取 1m / 超时 10s / 评估 1m;timeout 必须 ≤ interval |
global.external_labels |
发往 AM、remote_write 附加标签;HA 用 replica 区分实例 |
rule_files / alerting.alertmanagers |
规则文件 glob / AM 地址 |
job_name / scrape_interval / metrics_path / scheme / params |
必填唯一的 job 标签 / 覆盖周期 / /metrics / http / 抓取参数 |
static_configs / file_sd_configs / kubernetes_sd_configs |
静态 / 文件自动发现 / K8s 发现 |
relabel_configs / metric_relabel_configs |
抓前改标签 / 抓后丢高基数样本 |
sample_limit / label_limit / honor_labels |
样本、标签上限 / 信任 target 自带标签(默认 false 防伪造) |
basic_auth / authorization / tls_config / remote_write |
抓取认证与 TLS(凭据用 *_file)/ 长期存储转发 |
| 完整可运行最小配置(含文件发现、告警对接): |
global:
scrape_interval: 15s
scrape_timeout: 10s
evaluation_interval: 15s
external_labels: { cluster: "<cluster_name>", replica: "<replica_a>" }
rule_files: ["rules/*.yml"]
alerting:
alertmanagers:
- static_configs:
- targets: ["<alertmanager_host>:9093"]
scrape_configs:
- job_name: "prometheus"
static_configs: [{ targets: ["localhost:9090"] }]
- job_name: "node"
relabel_configs:
- { source_labels: [__address__], regex: "(.*):9100", target_label: instance, replacement: "$1" }
- job_name: "blackbox-http"
metrics_path: /probe
params: { module: [http_2xx] }
static_configs: [{ targets: ["https://<example_host>/health"] }]
relabel_configs:
- { source_labels: [__address__], target_label: __param_target }
- { source_labels: [__param_target], target_label: instance }
- { target_label: __address__, replacement: "<blackbox_host>:9115" }
promtool check config /etc/prometheus/prometheus.yml && promtool check rules /etc/prometheus/rules/*.yml
curl -X POST http://localhost:9090/-/reload # 需 --web.enable-lifecycle
5. 核心使用方法
5.1 CLI(promtool 与启动参数)
promtool check config /etc/prometheus/prometheus.yml # 1 校验配置
promtool check rules /etc/prometheus/rules/*.yml # 2 校验规则
promtool test rules /etc/prometheus/tests/*.yml # 3 规则单元测试
curl -s http://<host>:9100/metrics | promtool check metrics # 4 校验 exporter 格式
promtool query instant http://localhost:9090 'up{job="node"}' # 5 即时查询
promtool query range --start "$(date -d '-1h' +%s)" --end "$(date +%s)" --step 60 http://localhost:9090 'rate(node_cpu_seconds_total{mode="idle"}[5m])' # 6 范围查询
promtool tsdb analyze /var/lib/prometheus # 7 分析 block
promtool tsdb list /var/lib/prometheus # 8 列出 block
prometheus --version ; prometheus --help # 9 版本 / 10 全参数
# 常用启动参数(完整列表见 --help):--config.file --storage.tsdb.path --storage.tsdb.retention.time=15d
⚠️ --web.enable-admin-api 开放删序列/快照、--web.enable-lifecycle 开放 /-/reload 与 /-/quit,勿对公网暴露。
5.2 HTTP API
P=http://localhost:9090
curl -sG "$P/api/v1/query" --data-urlencode 'query=up' | jq '.data.result' # 1 即时查询
curl -sG "$P/api/v1/query_range" --data-urlencode 'query=rate(http_requests_total[5m])' --data-urlencode "start=$(date -d '-1h' +%s)" --data-urlencode "end=$(date +%s)" --data-urlencode 'step=60' # 2 范围查询
curl -s -X POST "$P/api/v1/query" --data-urlencode 'query=sum by (job) (rate(http_requests_total[5m]))' # 3 POST 长表达式
curl -s "$P/api/v1/targets?state=active" | jq '.data.activeTargets | length' # 4 活跃目标
curl -s "$P/api/v1/rules?type=alert" | jq -r '.data.groups[].rules[] | "\(.name)\t\(.health)"' # 5 规则状态
curl -s "$P/api/v1/alerts" | jq -r '.data.alerts[] | "\(.labels.alertname)\t\(.state)"' # 6 活跃告警
curl -s "$P/api/v1/status/config" | jq -r '.data.yaml' | head -20 # 7 已加载配置
curl -sG "$P/api/v1/series" --data-urlencode 'match[]=up' | jq '.data | length' # 9 序列
curl -s -X POST "$P/api/v1/admin/tsdb/snapshot" | jq '.data.name' # 10 快照(需 admin API)
curl -s "$P/-/healthy" ; curl -s "$P/-/ready" ; curl -X POST "$P/-/reload" ; curl -X POST "$P/-/quit" # 11 健康/重载/退出
query/query_range 支持 GET+POST(POST 用 application/x-www-form-urlencoded);targets/rules/alerts/status/config/labels/series 为 GET;admin/tsdb/snapshot 为 POST/PUT 且必须 --web.enable-admin-api。
5.3 PromQL 系统讲解
| 类型 | 语义 | 典型指标 | 正确用法 |
|---|---|---|---|
| Counter | 只增累计,重启归零 | node_cpu_seconds_total |
必须 rate()/increase(),勿画原值 |
| Gauge | 可增可减瞬时值 | node_memory_MemAvailable_bytes、up |
直接用、delta()、avg_over_time() |
| Histogram | 分桶 _bucket{le}/_sum/_count |
http_request_duration_seconds_bucket |
histogram_quantile(),可跨维度聚合 |
| Summary | 客户端预算分位数 {quantile} |
go_gc_duration_seconds |
直接读 quantile,不可跨实例聚合 |
选择器(= 精确、!= 取反、=~ 正则全匹配、!~ 正则取反)、区间向量、offset: |
http_requests_total{job="api",method="GET"} # = 精确
http_requests_total{status!="200"} # != 取反
http_requests_total{status=~"5.."} # =~ 正则
http_requests_total{path!~"/health|/metrics"} # !~ 正则取反
{__name__=~"node_.*_bytes"} # 按指标名过滤
http_requests_total[5m] # 区间向量(仅供 rate 等函数)
http_requests_total[5m] offset 1d # 时间偏移:昨天同窗口
| 函数 | 计算 | 适用 |
|---|---|---|
rate(v[range]) |
区间平均每秒增长率,自动补偿 counter 重置 | 告警、趋势(首选) |
irate(v[range]) |
最后两个样本瞬时速率 | 看突刺,抖动大 |
increase(v[range]) |
区间总增量 ≈ rate × range 秒 | "过去 1h 请求数" |
delta(v[range]) |
Gauge 首尾差 | 队列长度、温度变化 |
聚合(sum/min/max/avg/count/stddev/count_values/topk/bottomk/quantile;and/or/unless;on()/ignoring()/group_left): |
rate(node_cpu_seconds_total{mode="idle"}[5m]) # 正确:先 rate
sum by (instance) (rate(http_requests_total[5m])) # 正确:再聚合
sum(rate(http_requests_total[5m])) # 全集群 QPS
sum by (job) (rate(http_requests_total[5m])) # 保留 job
topk(5, sum by (instance) (rate(node_network_receive_bytes_total[5m])))
sum by (instance) (rate(app_errors_total[5m])) / on(instance) group_left(role) node_role_info # 多对一匹配
⚠️ [range] 必须 ≥ 2×scrape_interval,否则窗口内不足 2 样本返回空;15s 采集时 [10s] 无数据、[5m] 是安全下限。
常用函数:histogram_quantile、absent/absent_over_time、predict_linear、avg_over_time/max_over_time/quantile_over_time、clamp_max/clamp_min、label_replace/label_join、resets/changes/deriv、time()/vector()/scalar()。
生产表达式模板:
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) # CPU 使用率%
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 # 内存使用率%
100 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",mountpoint="/"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay",mountpoint="/"} * 100) # 根分区使用率%
predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*3600) < 0 # 4h 内磁盘将满
rate(node_disk_io_time_seconds_total[5m]) # 磁盘 IO 饱和度
sum by (instance) (rate(node_network_receive_errs_total[5m])) # 网卡收包错误率
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 # 5xx 占比%
histogram_quantile(0.99, sum by (le,job) (rate(http_request_duration_seconds_bucket[5m]))) # P99 延迟
5.4 Web UI
| 路径 | 用途 |
|---|---|
/graph |
Table/Graph 执行 PromQL |
/alerts / /rules |
告警与规则状态、health |
/targets |
UP/DOWN、抓取耗时、样本数 |
/service-discovery |
SD 原始标签 vs relabel 后差异(排查 target 丢失) |
/status |
运行时配置、启动参数、TSDB 状态 |
6. 告警与通知
Prometheus 侧只定义规则并推送告警;通知渠道、分组、抑制、静默、路由树全部在 Alertmanager(见同目录 alertmanager.md)。
# /etc/prometheus/rules/host.yml —— 阈值规则
groups:
- name: host.rules
rules:
- alert: HighCpuUsage
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels: { severity: warning, team: infra }
- alert: DiskWillFill
expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4*3600) < 0
for: 10m
labels: { severity: critical }
annotations: { summary: "{{ $labels.instance }} 根分区预计 4h 内写满" }
| 渠道 | Alertmanager 侧承载方式 |
|---|---|
| 邮件 | email_configs + global.smtp_smarthost |
| 企业微信 | 原生 wechat_configs(corp_id/api_secret/agent_id) |
| 钉钉 / Slack / Webhook | 钉钉用 webhook_configs 指机器人;Slack 用 slack_configs;通用 webhook_configs: [{ url: <url> }] HTTP POST JSON |
# 以下为 Alertmanager 侧片段,完整示例见 alertmanager.md 第 6 章(路由树/分组/抑制/静默)
route: # 路由树根节点 + 分组
receiver: default
group_by: [alertname, cluster]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- { matchers: ['severity="critical"'], receiver: wecom }
receivers:
- name: default
email_configs: [{ to: "<oncall@company>" }]
- name: wecom
wechat_configs: [{ corp_id: "<corp>", api_secret: "<secret>", agent_id: "<id>", to_user: "@all" }]
inhibit_rules: # 抑制:整机宕机时压制其上的子告警
- { source_matchers: ['alertname="InstanceDown"'], target_matchers: ['severity="warning"'], equal: [instance] }
# 静默:amtool silence add / Web UI 临时操作;time_intervals 可配静默时段
完整链路:exporter → Prometheus 抓取 → TSDB → evaluation_interval 评估 alerting rule → for 满足变 firing → POST :9093/api/v2/alerts → AM 分组/抑制/静默 → receiver 发通知;Grafana 用 Prometheus 数据源画大盘。
curl -s http://localhost:9090/api/v1/alertmanagers | jq '.data'
curl -s http://localhost:9090/api/v1/alerts | jq -r '.data.alerts[] | "\(.labels.alertname)\t\(.state)"'
7. 实战场景
7.1 批量接入 50 台主机(文件服务发现)
目标:新增主机不改主配置、不重启。步骤:部署 node_exporter → 写 target 文件 → SD 自动发现 → 验证。
sudo mkdir -p /etc/prometheus/targets/node
sudo tee /etc/prometheus/targets/node/web.yml >/dev/null <<'YAML'
- labels: { region: "<region>", role: "web" }
targets: ["<web01>:9100", "<web02>:9100"]
YAML
curl -sG http://localhost:9090/api/v1/query --data-urlencode 'query=count(up{job="node"})' | jq '.data.result'
验证:/service-discovery 出现新 target、/targets 为 UP,序列数增加。回滚:删除该 .yml,refresh_interval 后自动移除。
7.2 上线"磁盘将满"告警并热加载
目标:根分区预计 4h 写满时提前告警。
sudo tee /etc/prometheus/rules/disk.yml >/dev/null <<'YAML'
groups:
- name: disk.rules
rules:
- alert: DiskWillFillIn4h
expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",mountpoint="/"}[6h], 4*3600) < 0
for: 10m
labels: { severity: critical }
annotations: { summary: "{{ $labels.instance }} 根分区预计 4h 内写满" }
YAML
promtool check rules /etc/prometheus/rules/disk.yml && curl -X POST http://localhost:9090/-/reload
curl -s http://localhost:9090/api/v1/rules?type=alert | jq -r '.data.groups[].rules[].name'
验证:/rules 出现规则且 health=ok,AM 收到路由。回滚:rm /etc/prometheus/rules/disk.yml && curl -X POST http://localhost:9090/-/reload。
7.3 TSDB 快照备份与恢复
目标:升级/迁移前一致性备份,可原地恢复(前提 --web.enable-admin-api)。
SNAP=$(curl -s -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot | jq -r '.data.name')
sudo cp -a "/var/lib/prometheus/snapshots/$SNAP" /backup/prometheus-snap-<date>/
sudo systemctl stop prometheus
sudo mv /var/lib/prometheus /var/lib/prometheus.bak && sudo mkdir -p /var/lib/prometheus
sudo cp -a "/backup/prometheus-snap-<date>/$SNAP/." /var/lib/prometheus/
sudo chown -R prometheus:prometheus /var/lib/prometheus && sudo systemctl start prometheus
curl -s http://localhost:9090/-/ready
验证:可查到历史时间点数据,promtool tsdb analyze /var/lib/prometheus 无报错。回滚:停服 → 删新目录 → mv /var/lib/prometheus.bak /var/lib/prometheus → 启动。⚠️ 清空数据目录属高危,先确认备份完整。
8. 日常运维与故障排查
sudo systemctl status prometheus --no-pager ; sudo systemctl restart prometheus
sudo journalctl -u prometheus -f --no-pager # systemd 日志走 journald;容器用 docker logs prometheus
sudo journalctl -u prometheus --since "1 hour ago" | grep -iE 'error|warn'
curl -s http://localhost:9090/-/healthy ; curl -s http://localhost:9090/-/ready
curl -s http://localhost:9090/api/v1/targets?state=active | jq '.data.activeTargets[] | select(.health!="up")'
| 现象 | 原因 | 处置 |
|---|---|---|
Target DOWN / context deadline exceeded |
超时小于 exporter 耗时或网络不通 | curl -v http://<t>:9100/metrics 测耗时;调 scrape_timeout(≤ interval) |
rate() 返回空 |
窗口内样本不足 2 个(刚接入) | 等两个周期;保证 [range] ≥ 2×scrape_interval |
| reload 不生效 | 漏 --web.enable-lifecycle 或 YAML 错 |
promtool check config 后 POST /-/reload |
| 大盘"无数据" / 样本被丢弃 | 采集端与服务端时钟不同步 | 部署 chrony/NTP;⚠️ 禁止生产 date -s 硬跳 |
| 内存涨到 OOM | 高基数标签或 target 暴增 | metric_relabel_configs drop、加 sample_limit、看 prometheus_tsdb_head_series |
| 查询超时 / 页面卡死 | 大范围 query_range 无聚合、并发高 |
加 by()、缩小范围、调 --query.max-concurrency、落 recording rule |
| 磁盘写满 | retention 未限制或 compaction 空间不足 | 设 --storage.tsdb.retention.size;清理前先快照 |
| 告警一直 pending | for 未到 / 规则评估失败 / 数据断续 |
/api/v1/rules 看 health 与 lastEvaluation |
9. 性能、容量与高可用
磁盘(GB) ≈ 活跃序列数 × 每样本约 1.7B × (保留秒数 / 采集间隔秒) × 1.1 / 1024³
内存(GB) ≈ 活跃序列数 × 3~8KB(head chunk + 索引) / 1024³ + WAL/查询临时开销
示例:50 万序列、15s、15d ≈ 500000×1.7×(1296000/15)×1.1/1024³ ≈ 75 GiB(按 2× 预留)
入库速率 ≈ 活跃序列数 / scrape_interval;用 count({__name__=~".+"}) 估序列数
| 调优参数 | 建议 |
|---|---|
--storage.tsdb.retention.time / retention.size |
15d |
--storage.tsdb.wal-compression |
大实例开启,省磁盘换少量 CPU |
--query.max-concurrency / --query.timeout |
防大查询拖垮实例 |
sample_limit / label_limit / metric_relabel_configs: drop |
降基数最有效手段 |
recording rule / evaluation_interval 对齐 scrape_interval |
大盘与告警共用预计算 |
| HA / 扩展方案 | 做法 | 适用 |
|---|---|---|
| 双实例 HA | 相同配置抓同一批 target,external_labels.replica 区分;Grafana 去重、AM 集群去重告警 |
最常用 |
| 联邦 federation | 上层用 /federate?match[]= 抓下层已聚合序列 |
多机房全局视图 |
| 功能分片 | 按 job/业务拆多个实例(infra/app/k8s) | 超大规模、故障隔离 |
| remote_write | 本地短期 + 转发 Thanos/Mimir/VictoriaMetrics,Grafana 查远端 | 长期归档、跨集群(以各项目官方文档为准) |
up{job="prometheus"} == 0 # 自身挂(另一实例探活更可靠)
prometheus_tsdb_head_series # 活跃序列,突增即基数问题
rate(prometheus_tsdb_head_samples_appended_total[5m]) # 入库速率
scrape_duration_seconds / process_resident_memory_bytes # 抓取变慢 / 内存趋势
10. 安全加固、备份与升级
basic_auth_users: { <username>: <bcrypt_hash> }
tls_server_config: { cert_file: /etc/prometheus/tls/server.crt, key_file: /etc/prometheus/tls/server.key }
# 带认证的抓取配置(凭据勿写主配置,/api/v1/status/config 会泄露明文)
scrape_configs:
- job_name: secure-target
scheme: https
basic_auth: { username: <username>, password_file: /etc/prometheus/secrets/password }
tls_config: { ca_file: /etc/prometheus/tls/ca.crt }
static_configs: [{ targets: ["<host>:9100"] }]
sudo ufw allow from <grafana_cidr> to any port 9090 proto tcp && sudo ufw deny 9090/tcp
SNAP=$(curl -s -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot | jq -r '.data.name')
sudo tar czf /backup/prometheus-<date>.tar.gz -C /var/lib/prometheus/snapshots "$SNAP" # 在线快照
sudo tar czf /backup/prometheus-conf-<date>.tar.gz /etc/prometheus/ # 配置备份
sudo systemctl stop prometheus && sudo tar czf /backup/prometheus-cold-<date>.tar.gz -C /var/lib/prometheus . && sudo systemctl start prometheus # 冷备
最小权限:专用 prometheus 系统用户 + nologin;unit 加 NoNewPrivileges/ProtectSystem=strict/ReadWritePaths;凭据 chmod 0600;只监听回环由反代对外。⚠️ 勿以 root 运行、勿公网开放 9090 / /-/quit / admin API。
升级顺序:① prometheus --version 记录 → ② 备份数据与 /etc/prometheus/ → ③ 预发 promtool check config + 核心 PromQL 回归 → ④ cp /usr/local/bin/prometheus /usr/local/bin/prometheus.old → ⑤ 停服、替换二进制、启动、/-/ready + /targets 验证 → ⑥ 观察 24h → ⑦ 回滚:停服换回 prometheus.old;若新版已压实 block 致旧版不兼容,用冷备整体恢复(7.3)。跨大版本先读官方 Release notes 的 breaking changes。
11. 常见坑
- Counter 直接画原值:曲线只增、重启断崖 → 一律先
rate()/increase()。 [range]< 2×采集间隔:15s 下rate(x[10s])永远为空 → 用[5m]起步。rate(sum(...))写反:丢失 counter 重置语义 → 永远先 rate 后 sum。- 标签塞 user_id/trace_id/完整 URL:序列数指数膨胀 OOM →
metric_relabel_configsdrop,明细走日志。 - 容器不挂卷:重启历史全丢 → 生产必须
-v <volume>:/prometheus。 scrape_timeout > scrape_interval:抓取重叠、时间戳错乱 → 保证 timeout ≤ interval。- 时钟不同步:样本被判未来时间丢弃 → 全链路 chrony;⚠️ 禁止生产
date -s。 - reload 没生效:漏
--web.enable-lifecycle或 YAML 有错 → 先promtool check config。 up == 0检不到目标被删除:关键 job 补absent(up{job="..."});HA 两实例external_labels需不同replica。- Histogram 对各实例 quantile 求平均:先
sum by (le)再histogram_quantile;⚠️ admin API 勿暴露公网。
12. 速查表
| 类别 | 项 | 值 / 命令 |
|---|---|---|
| 端口 | Web/API | 9090 |
| 配置 | 主配置 / 规则 | /etc/prometheus/prometheus.yml / rules/*.yml |
| 数据 | TSDB 目录 | --storage.tsdb.path=/var/lib/prometheus(容器 /prometheus) |
| 校验 | 配置 / 规则 | promtool check config <f> / promtool check rules <f> |
| 重载 | 热加载 | curl -X POST http://localhost:9090/-/reload |
| 健康 | 存活 / 就绪 | /-/healthy、/-/ready |
| 参数 | 时间/容量保留 | --storage.tsdb.retention.time=15d / retention.size=200GB |
| 参数 | 管理 API / 生命周期 | --web.enable-admin-api / --web.enable-lifecycle |
| 参数 | TLS/认证 | --web.config.file=<file> |
| API | 即时 / 范围查询 | GET|POST /api/v1/query / /api/v1/query_range |
| API | 目标 / 规则 / 告警 | GET /api/v1/targets / /api/v1/rules / /api/v1/alerts |
| API | 配置 / 告警接收端 | GET /api/v1/status/config / /api/v1/alertmanagers |
| API | TSDB 快照 | POST /api/v1/admin/tsdb/snapshot |
| PromQL | 速率 | rate(counter[5m]) / irate / increase |
| PromQL | 聚合 / 偏移 | sum by (job)(...) / <expr> offset 1d |
| PromQL | 分位数 / 无数据 | histogram_quantile(0.99, sum by (le)(rate(x_bucket[5m]))) / absent(up{job="<j>"}) |
| 指标 | 目标存活 / 抓取耗时 | up / scrape_duration_seconds |
| 指标 | 序列数 / 入库速率 | prometheus_tsdb_head_series / rate(prometheus_tsdb_head_samples_appended_total[5m]) |
13. 选型建议与同类对比
| 维度 | Prometheus | Zabbix | Graphite+Carbon | InfluxDB | VictoriaMetrics |
|---|---|---|---|---|---|
| 数据模型 | 指标名+多维标签 | 主机/Item | 点分路径无标签 | measurement+tag | 兼容 Prometheus 标签 |
| 采集 | 拉+服务发现 | 推(agent/trapper) | 推 | 推(Telegraf) | 拉,兼容 scrape |
| 查询 | PromQL(聚合/预测强) | 前端点选 | Render API | Flux/InfluxQL | MetricsQL(PromQL 超集) |
| K8s 亲和 | 极高(Operator) | 中 | 低 | 中 | 高 |
| 最适 | 云原生、微服务、动态扩缩容 | 传统 IDC/SNMP | 老一代栈 | IoT/高频写 | 超大规模、长期留存 |
| 选它:容器/K8s;多维指标 + PromQL 速率/分位数/预测;告警评估与通知解耦;要成熟 Exporter 生态与 Grafana 无缝;接受"本地短期 + 远端长期"分层。 | |||||
| 别选:以 SNMP/网络设备为主且已重度用 Zabbix;需 100% 不丢样本的计费/审计;要开箱即用分布式集群且不愿引入 Thanos/Mimir/VM;主需求是日志或链路追踪。 |
14. 参考链接
- 官网 / 下载:https://prometheus.io/ | https://prometheus.io/download/
- 概览 / 入门:https://prometheus.io/docs/introduction/overview/ | https://prometheus.io/docs/prometheus/latest/getting_started/
- 安装 / 配置:https://prometheus.io/docs/prometheus/latest/installation/ | https://prometheus.io/docs/prometheus/latest/configuration/configuration/
- 查询 API / AM 配置:https://prometheus.io/docs/prometheus/latest/querying/api/ | https://prometheus.io/docs/alerting/latest/configuration/
- 源码 / 官方镜像:https://github.com/prometheus/prometheus | https://hub.docker.com/r/prom/prometheus/ | https://quay.io/repository/prometheus/prometheus
- Exporter 清单 / 命名规范:https://prometheus.io/docs/instrumenting/exporters/ | https://prometheus.io/docs/practices/naming/
<VERSION>/<xxx>为占位符;当前大版本 3.x(含 LTS),精确版本号、下载文件名与镜像 tag 以官方最新稳定版为准。