Prometheus —— 拉模型指标采集、时序存储与告警评估的开源标准

运维监控软件手册 01-指标采集与时序存储 23.9 KB 原文

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 15d30d 本地短期,size 设磁盘 70%80% 防写满
--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. 常见坑

  1. Counter 直接画原值:曲线只增、重启断崖 → 一律先 rate()/increase()。
  2. [range] < 2×采集间隔:15s 下 rate(x[10s]) 永远为空 → 用 [5m] 起步。
  3. rate(sum(...)) 写反:丢失 counter 重置语义 → 永远先 rate 后 sum。
  4. 标签塞 user_id/trace_id/完整 URL:序列数指数膨胀 OOM → metric_relabel_configs drop,明细走日志。
  5. 容器不挂卷:重启历史全丢 → 生产必须 -v <volume>:/prometheus。
  6. scrape_timeout > scrape_interval:抓取重叠、时间戳错乱 → 保证 timeout ≤ interval。
  7. 时钟不同步:样本被判未来时间丢弃 → 全链路 chrony;⚠️ 禁止生产 date -s。
  8. reload 没生效:漏 --web.enable-lifecycle 或 YAML 有错 → 先 promtool check config。
  9. up == 0 检不到目标被删除:关键 job 补 absent(up{job="..."});HA 两实例 external_labels 需不同 replica。
  10. 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. 参考链接

<VERSION> / <xxx> 为占位符;当前大版本 3.x(含 LTS),精确版本号、下载文件名与镜像 tag 以官方最新稳定版为准。

Prometheus —— 拉模型指标采集、时序存储与告警评估的开源标准 - 知识库 - 起航社区