AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

prometheus / promtool —— 监控数据查询和工具

一句话定义

prometheus 是 K8s 生态最主流的时序数据库 + 监控系统,组件本身在 K8s 里作为 Deployment 跑。它没有"日常 CLI"——所有查询走 PromQL 通过 HTTP API。但 prometheus 自带的 promtool 提供本地工具:验证配置、查询 API、测告警规则。

典型场景

  • 看哪些 target 没采集到:curl http://prom:9090/api/v1/targets
  • 验证 prometheus 配置语法:promtool check config prometheus.yml
  • 验证告警规则语法:promtool check rules rules.yml
  • 命令行查询 PromQL:promtool query instant http://prom:9090 'up'
  • 排查"指标没看到":sum + by + 命名 + scrape job 全链路

Prometheus 的核心概念(理解了这个再用 CLI)

target  ──scrape──►  prometheus  ──store──►  TSDB
   ▲                       │
   │                       └──query──►  PromQL / API
   │
service discovery
(K8s pod, kube-sd, file-sd, ...)

四个核心:

  1. Target —— 被采集的 endpoint(pod 上 :9100/metrics)
  2. Scrape —— 周期性(默认 15s)pull target,存数据
  3. Series —— 一条时序:metric_name{label1=v1,label2=v2} -> [(ts, value), ...]
  4. PromQL —— 查询语言

CLI 工作主要围绕:确认 target up、看 series、跑 PromQL。


promtool —— Prometheus 自带的工具

装 prometheus 时自带:

# 单独装
curl -L https://github.com/prometheus/prometheus/releases/download/v2.51.0/prometheus-2.51.0.linux-amd64.tar.gz | tar xz
mv prometheus-*/promtool /usr/local/bin/

promtool --version
# promtool, version 2.51.0 ...

promtool check config —— 验证配置语法

promtool check config /etc/prometheus/prometheus.yml
# Checking /etc/prometheus/prometheus.yml
#   SUCCESS: 0 rule files found

promtool check rules /etc/prometheus/rules/*.yml
# Checking /etc/prometheus/rules/recording.yml
#   SUCCESS: 12 rules found

CI 流水线里改 prometheus 配置之前必跑,避免改错让 prometheus 重启失败。

promtool query —— 命令行跑 PromQL

# 瞬时查询
promtool query instant http://prom:9090 'up'
# 返回 { up{instance="...",job="..."} => 1 ... }

# 范围查询
promtool query range http://prom:9090 'rate(http_requests_total[5m])' \
  --start='2026-05-27T00:00:00Z' \
  --end='2026-05-27T01:00:00Z' \
  --step=1m

# 看时序的所有 label
promtool query labels http://prom:9090 job

在没有 grafana / web UI 时调试 PromQL 用。

promtool tsdb —— 看 TSDB 状态(在 prometheus pod 里跑)

promtool tsdb analyze /prometheus/                # 看磁盘 / series 数 / chunk 等
promtool tsdb list /prometheus/                    # 列 block

排查"prometheus 磁盘暴涨" / "series 太多" 必备。


直接 curl Prometheus HTTP API

Prometheus 暴露 REST API(端口默认 9090)。CLI 友好的方式是 curl:

看 targets

curl -s http://prom:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, instance: .labels.instance, health}'
# {"job": "kubelet", "instance": "m1:10250", "health": "up"}
# {"job": "kubelet", "instance": "m4:10250", "health": "down"}    ← 这个失败了

排查"prometheus 看不到指标"第一步:看 target health。

跑 PromQL

# 瞬时
curl -s --data-urlencode 'query=up' http://prom:9090/api/v1/query | jq
# {"status":"success","data":{"resultType":"vector","result":[...]}}

# 范围
curl -s --data-urlencode 'query=rate(http_requests_total[5m])' \
     --data-urlencode 'start=2026-05-27T00:00:00Z' \
     --data-urlencode 'end=2026-05-27T01:00:00Z' \
     --data-urlencode 'step=1m' \
     http://prom:9090/api/v1/query_range | jq

看 series / labels / metadata

curl -s 'http://prom:9090/api/v1/label/__name__/values' | jq '.data | length'
# 5000 → 集群有 5000 个不同 metric

curl -s 'http://prom:9090/api/v1/labels' | jq '.data'
# 所有 label 名

curl -s 'http://prom:9090/api/v1/series?match[]=up' | jq
# 拥有 up 这个 metric 的所有 series

Reload / Quit

# 让 prometheus 重新读配置(要启动时加 --web.enable-lifecycle)
curl -X POST http://prom:9090/-/reload

# 查看 build info
curl -s http://prom:9090/api/v1/status/buildinfo | jq

PromQL 速查(实战必背)

基础

up                                            # 所有 target 健康(1=up, 0=down)
up == 0                                       # 只看挂的
up{job="kubelet"}                              # 过滤 job
node_cpu_seconds_total{mode="idle"}            # 多 label

rate / irate(速率)

rate(http_requests_total[5m])                  # 5 分钟均速(QPS)
irate(http_requests_total[1m])                  # 即时速率(最近 2 个采样点)

rate 给平均,irate 给瞬时。alerting 用 rate(稳)、dashboard 实时用 irate(敏感)。

sum / by / without(聚合)

sum(rate(http_requests_total[5m]))                                 # 所有 series 加起来
sum by (job) (rate(http_requests_total[5m]))                        # 按 job 聚合
sum without (instance) (rate(http_requests_total[5m]))              # 除了 instance 全保留

by 保留指定 label、without 删除指定 label。后者更稳——加新 label 不影响。

topk / bottomk

topk(5, rate(http_requests_total[5m]))                             # CPU top 5
topk(10, container_memory_working_set_bytes)                        # 内存 top 10

histogram_quantile(P95 / P99)

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))      # P95 延迟
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

PromQL 必备技能——SRE 面试常考。

常用查询模板

# 节点 CPU 利用率
(1 - rate(node_cpu_seconds_total{mode="idle"}[5m]))

# 节点内存利用率
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes

# 节点磁盘剩余
(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})

# K8s pod 重启次数(最近 1 小时)
increase(kube_pod_container_status_restarts_total[1h])

# pod CPU 使用率
sum by (pod) (rate(container_cpu_usage_seconds_total{container!=""}[5m]))

# pod 内存使用
sum by (pod) (container_memory_working_set_bytes{container!=""})

# 5xx 错误率
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))

排查"prometheus 看不到指标"

# 1. target 在不在
curl -s http://prom:9090/api/v1/targets | jq '.data.activeTargets[] | select(.labels.job=="my-job")'
# 如果空,scrape config 没匹配上

# 2. target 是不是 up
curl -s http://prom:9090/api/v1/targets | jq '.data.activeTargets[] | select(.labels.job=="my-job") | {health, lastError}'
# health: down / lastError: "connection refused" → 应用没在 /metrics 暴露

# 3. service / pod 是不是有正确 annotation(K8s sd)
kubectl get pod my-pod -o yaml | grep -A 5 annotations
# prometheus.io/scrape: "true"
# prometheus.io/port: "9090"

# 4. metric 名对不对(应用真的暴露了吗)
kubectl port-forward my-pod 9090:9090
curl http://localhost:9090/metrics | grep -i my_metric_name

# 5. PromQL 拼错?
promtool query instant http://prom:9090 'my_metric_name'

看告警规则评估

# 看所有规则
curl -s http://prom:9090/api/v1/rules | jq

# 看 firing 的告警
curl -s http://prom:9090/api/v1/alerts | jq '.data.alerts[] | {labels, state}'

或者 web UI /alerts 页面更直观。

规则评估测试

promtool test rules tests.yml

tests.yml 例子:

rule_files:
  - rules.yml
tests:
  - interval: 1m
    input_series:
      - series: up{job="test"}
        values: '1 1 0 0 0 0'
    alert_rule_test:
      - eval_time: 5m
        alertname: TargetDown
        exp_alerts:
          - exp_labels:
              severity: critical
              job: test

CI 跑这个能验证你的告警规则在特定输入下是否真的会触发。


TSDB 操作

看 prometheus 数据目录占用

# 在 prometheus pod 里
kubectl exec -it prometheus-prom-0 -n monitoring -- df -h /prometheus
kubectl exec -it prometheus-prom-0 -n monitoring -- du -sh /prometheus

或者用 promtool 分析:

kubectl exec -it prometheus-prom-0 -n monitoring -- promtool tsdb analyze /prometheus
# Block ID: 01HVKZ...
# Duration: 2h
# Series: 50000
# Label Pairs: ...
# Distinct Label Names: 200
# ...

看 high cardinality series

kubectl exec -it prometheus-prom-0 -n monitoring -- \
  promtool tsdb analyze /prometheus | head -50

"Highest cardinality metric names" / "Label pairs most involved in churning series" 是排查 cardinality 爆炸的金矿。


常见踩坑

坑 1:target health=down

curl http://prom:9090/api/v1/targets | jq '.data.activeTargets[] | select(.health=="down")'
# {lastError: "...connection refused"}

应用没在 /metrics 暴露 / 端口不对 / 网络挡。

# 节点上手动测
kubectl port-forward my-pod 9090:<port>
curl http://localhost:9090/metrics

坑 2:series 数爆炸

# 看 series 总数
curl -s 'http://prom:9090/api/v1/status/tsdb' | jq '.data.headStats'
# {numSeries: 5000000, ...}      ← 太多

通常是 label cardinality 爆炸——label value 是 user ID / request URL 等 unbounded 集合。

promtool tsdb analyze /prometheus | head
# Highest cardinality metric names

修法:

  • 改应用 / exporter,把高基数 label 拿掉
  • 加 metric_relabel_configs drop 掉
  • 否则 prometheus 内存爆 OOM

坑 3:PromQL rate 用错时间窗口

rate(http_requests_total[5m])

[5m] 至少要 4 倍 scrape 间隔(默认 scrape 15s → 至少 60s,安全 5m)。窗口太短,新 series 还没 2 个采样点,rate 返回 NaN。

坑 4:histogram_quantile 没加 by (le)

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

要 sum by (le, ...) 才能正确计算分位数。否则不同 series 的 bucket 拼一起得到错误结果。

histogram_quantile(0.95, sum by (le, route) (rate(http_request_duration_seconds_bucket[5m])))

坑 5:/-/reload 不工作

curl -X POST http://prom:9090/-/reload
# {"status":"error","errorType":"unavailable","error":"Lifecycle API is not enabled"}

启动时没加 --web.enable-lifecycle。要 reload 时 kill -HUP 也行:

kubectl exec -n monitoring prometheus-xxx -- kill -HUP 1

坑 6:误把 up == 0 配成告警 + 持续触发

alert: TargetDown
expr: up == 0
for: 5m

某 service 永远停服时,告警永远 firing。要么加 silence、要么加 unless on(job) ... 排除特定 job。

坑 7:promtool 检查通过但 prom 起不来

promtool check config prometheus.yml
# SUCCESS

# 但 prom 起来报错
kubectl logs prometheus-xxx
# Error opening query log file

promtool check 只验证 yaml 语法 + scrape config。不验证:

  • 数据目录权限
  • service discovery 连不到
  • 引用的文件存在

要看 prometheus pod 自身日志才能定位运行时问题。

坑 8:长期保留打爆磁盘

retention: 90d                                # 默认 15d

K8s 集群 5000 个 series × 15s × 90d = 几十 GB。规划好 PVC 大小、或者用 Thanos / VictoriaMetrics 做长期存储。


关联命令

  • curl —— 调 prom API
  • jq —— 处理 prom API JSON 输出
  • helm —— 装 prom 全家桶 (kube-prometheus-stack)
  • alertmanager —— prom 的告警下游
  • grafana —— prom 的可视化前端
  • amtool —— alertmanager CLI(详见 alertmanager.md)
  • thanos / victoriametrics-cli —— prom 长期存储
在 GitHub 上编辑此页