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