PromQL 基础查询
High Contrast
Dark Mode
Light Mode
Sepia
Forest
1 min read294 words

PromQL 基础查询

核心问题:Prometheus 收集了大量指标,怎样写查询语句找到关心的数据?


指标类型

类型 说明 示例
Counter 只增不减的累计值(重启后重置为 0) 请求总数、错误总数
Gauge 可增可减的当前值 当前 CPU 使用率、Pod 数量
Histogram 采样观测值,分桶统计分布 请求耗时分布、响应体大小
Summary 类似 Histogram,但在客户端计算分位数 响应时间 P50/P95/P99

基础选择器语法

# 查询所有时间序列(metric name 选择器)
http_requests_total
# 精确标签匹配(=)
http_requests_total{job="api-server", namespace="production"}
# 不等于匹配(!=)
http_requests_total{status_code!="200"}
# 正则匹配(=~)
http_requests_total{status_code=~"5.."}   # 5xx 错误
# 正则排除(!~)
http_requests_total{status_code!~"2.."}   # 非 2xx
# 时间范围选择器(Range Vector)
http_requests_total[5m]   # 过去 5 分钟的所有采样点

聚合函数

# 求和(sum)
sum(http_requests_total)
# 按标签分组求和
sum by (status_code) (http_requests_total)
sum by (namespace, pod) (container_cpu_usage_seconds_total)
# 排除某标签后求和
sum without (pod, container) (container_cpu_usage_seconds_total)
# 最大/最小/平均
max(container_memory_working_set_bytes)
min by (node) (node_cpu_seconds_total)
avg by (namespace) (container_cpu_usage_seconds_total)
# 计数
count(kube_pod_info)    # 所有 Pod 数量
count by (namespace) (kube_pod_info)   # 按 Namespace 统计
# TopK / BottomK
topk(5, sum by (pod) (container_cpu_usage_seconds_total))  # CPU 用最多的 5 个 Pod

速率函数(Rate Functions)

Counter 类型的指标需要用 rate() / irate() 转换为每秒速率:

# rate():5 分钟内的平均速率(推荐,对抖动不敏感)
rate(http_requests_total[5m])
# irate():最后两个采样点的瞬时速率(响应快,适合仪表板)
irate(http_requests_total[1m])
# increase():时间范围内的增量(不除以时间)
increase(http_requests_total[1h])   # 过去 1 小时请求数增量

常用 Kubernetes 监控查询

集群资源使用

# 集群 CPU 使用率(总体)
1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m]))
# 按节点 CPU 使用率
100 - (avg by (node) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 集群内存使用率
1 - sum(node_memory_MemAvailable_bytes) / sum(node_memory_MemTotal_bytes)
# 节点磁盘使用率
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_free_bytes{mountpoint="/"})
/ node_filesystem_size_bytes{mountpoint="/"}

Pod/容器资源

# 容器 CPU 使用量(核数)
sum by (namespace, pod, container) (
rate(container_cpu_usage_seconds_total{container!=""}[5m])
)
# 容器内存使用量(MB)
sum by (namespace, pod) (container_memory_working_set_bytes{container!=""}) / 1024 / 1024
# CPU 使用率 vs Request(超额使用)
sum by (pod) (rate(container_cpu_usage_seconds_total[5m]))
/ sum by (pod) (kube_pod_container_resource_requests{resource="cpu"})
# 内存使用率 vs Limit
sum by (pod, namespace) (container_memory_working_set_bytes)
/ sum by (pod, namespace) (kube_pod_container_resource_limits{resource="memory"})

应用健康

# HTTP 错误率(5xx 比例)
sum(rate(http_requests_total{status_code=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
# 请求 P95 延迟(Histogram 类型)
histogram_quantile(0.95,
sum by (le, job) (
rate(http_request_duration_seconds_bucket[5m])
)
)
# 请求 P50/P95/P99 对比
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
histogram_quantile(0.50, rate(http_request_duration_seconds_bucket[5m]))
# 可用 Pod 比例
kube_deployment_status_replicas_available{namespace="production"}
/ kube_deployment_spec_replicas{namespace="production"}

K8s 对象状态

# 非 Running 状态的 Pod
count(kube_pod_status_phase{phase!="Running", phase!="Succeeded"}) by (namespace, phase)
# Pod 重启次数(过去 1 小时)
increase(kube_pod_container_status_restarts_total[1h]) > 0
# PVC 使用率
kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes
# Deployment 副本不满足期望
kube_deployment_status_replicas_available
!= kube_deployment_spec_replicas

函数速查

函数 用途 示例
rate(v[t]) Counter 5min 平均速率 rate(http_requests_total[5m])
irate(v[t]) Counter 瞬时速率 irate(errors_total[1m])
increase(v[t]) Counter 增量 increase(restarts_total[1h])
histogram_quantile(φ, v) 百分位数 histogram_quantile(0.95, ...)
absent(v) 指标不存在时返回 1 absent(up{job="api"})
changes(v[t]) 时间范围内值变化次数 changes(config_reloads_total[10m])
delta(v[t]) Gauge 时间范围内差值 delta(memory_bytes[30m])
predict_linear(v[t], s) 线性预测 s 秒后的值 predict_linear(disk_free[1h], 4*3600)
label_replace() 动态添加/修改标签 label_replace(v, "dst", "$1", "src", "(.*)")

实用查询模板

# SLO:过去 30 天错误率 < 0.1%
1 - (
sum_over_time(http_request_errors_total[30d]) /
sum_over_time(http_requests_total[30d])
)
# 内存即将不足(预测 4 小时后)
predict_linear(node_memory_MemFree_bytes[1h], 4 * 3600) < 0
# 磁盘即将满(预测 6 小时后)
predict_linear(
node_filesystem_free_bytes{mountpoint="/"}[6h],
6 * 3600
) / node_filesystem_size_bytes{mountpoint="/"} < 0.1

下一节Grafana 仪表板与 AlertManager 规则