3. SLI指标采集:使用Prometheus采集Pod CPU、内存、请求延迟等核心指标
SLI(Service Level Indicator)是SLO体系的量化基石。在Kubernetes集群中,SLI指标采集的准确性直接决定了SLO计算的可信度。本章聚焦于使用Prometheus生态,系统化采集Pod级别的CPU、内存、请求延迟三大核心指标,并建立标准化的指标采集模板。
3.1 核心SLI指标分类与采集策略
根据Google SRE经典方法论,SLI指标通常分为三类:吞吐量、延迟、错误率。在Kubernetes场景下,我们还需要关注资源饱和度指标(CPU/内存使用率),因为它们直接影响Pod的稳定性和SLO达成。
| SLI类别 | 核心指标 | Prometheus指标名 | 采集来源 | 典型阈值参考 |
|---|---|---|---|---|
| 资源使用 | CPU使用率 | rate(container_cpu_usage_seconds_total[1m]) |
cAdvisor / kubelet | < 80% 为健康 |
| 资源使用 | 内存使用率 | container_memory_working_set_bytes |
cAdvisor / kubelet | < 85% 为健康 |
| 请求延迟 | P99 / P95 延迟 | histogram_quantile(0.99, ...) |
应用暴露 / Istio | < 500ms (P99) |
| 请求延迟 | 平均延迟 | rate(http_request_duration_seconds_sum[1m]) / rate(http_request_duration_seconds_count[1m]) |
应用暴露 / Istio | < 200ms (avg) |
| 错误率 | HTTP 5xx 比例 | sum(rate(http_requests_total{status=~"5.."}[1m])) / sum(rate(http_requests_total[1m])) |
应用暴露 / Ingress | < 0.1% |
container_memory_working_set_bytes 而非 container_memory_usage_bytes,因为 working_set 更准确地反映了容器实际占用的不可回收内存,与 OOM 行为直接相关。
3.2 Prometheus指标采集架构
在Kubernetes集群中,Prometheus通过服务发现机制自动发现目标Pod。采集架构分为三个层次:节点层(kubelet/cAdvisor)、服务网格层(Istio/Linkerd)、应用层(业务指标暴露)。
3.3 Pod CPU指标采集详解
CPU指标采集依赖kubelet内置的cAdvisor组件。核心指标为 container_cpu_usage_seconds_total,这是一个累积计数器,需要配合 rate() 函数计算每秒使用率。
3.3.1 核心PromQL查询
# 计算Pod CPU使用率(相对于request)
sum(
rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[1m])
) by (pod, namespace)
/
sum(
kube_pod_container_resource_requests{resource="cpu"}
) by (pod, namespace)
* 100
# 计算Pod CPU使用率(相对于limit)
sum(
rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[1m])
) by (pod, namespace)
/
sum(
kube_pod_container_resource_limits{resource="cpu"}
) by (pod, namespace)
* 100
container!="POD" 用于排除Pause容器(Sandbox容器),container!="" 用于排除未指定容器名称的指标行。这两个过滤条件在SLI计算中必须使用,否则会导致CPU使用率被低估。
3.4 Pod内存指标采集详解
内存指标同样来自cAdvisor,但需要区分工作集内存和RSS内存。对于SLO计算,推荐使用 container_memory_working_set_bytes,因为它更接近OOM判定的实际依据。
3.4.1 核心PromQL查询
# 计算Pod内存使用率(相对于request)
sum(
container_memory_working_set_bytes{container!="POD",container!=""}
) by (pod, namespace)
/
sum(
kube_pod_container_resource_requests{resource="memory"}
) by (pod, namespace)
* 100
# 计算Pod内存使用率(相对于limit)
sum(
container_memory_working_set_bytes{container!="POD",container!=""}
) by (pod, namespace)
/
sum(
kube_pod_container_resource_limits{resource="memory"}
) by (pod, namespace)
* 100
| 内存指标 | 含义 | 适用场景 | 注意事项 |
|---|---|---|---|
container_memory_working_set_bytes |
工作集内存(活跃内存) | SLO资源饱和度计算 | 最接近OOM行为,推荐使用 |
container_memory_rss |
常驻内存(RSS) | 应用内存泄漏排查 | 不包含缓存,可能低估实际使用 |
container_memory_cache |
Page Cache | 缓存效率分析 | 可被回收,不影响OOM |
container_memory_usage_bytes |
总使用内存(含缓存) | 容量规划 | 包含可回收缓存,可能高估 |
3.5 请求延迟指标采集详解
请求延迟是SLO中最关键的SLI之一。在Kubernetes环境中,延迟指标通常来自服务网格(如Istio)或应用自身暴露的Histogram指标。
3.5.1 Istio指标采集
Istio Sidecar(Envoy)会自动暴露请求延迟指标,格式为 istio_request_duration_milliseconds_bucket。这是典型的Histogram类型指标,用于计算百分位延迟。
# 计算P99延迟(毫秒)
histogram_quantile(
0.99,
sum(
rate(istio_request_duration_milliseconds_bucket{reporter="destination"}[1m])
) by (le, destination_service, destination_workload)
)
# 计算P95延迟(毫秒)
histogram_quantile(
0.95,
sum(
rate(istio_request_duration_milliseconds_bucket{reporter="destination"}[1m])
) by (le, destination_service, destination_workload)
)
3.5.2 应用自定义指标采集
对于非服务网格场景,应用需要自行暴露Histogram指标。推荐使用Prometheus客户端库的标准命名规范:
# 应用暴露的Histogram指标示例(Go语言)
http_request_duration_seconds_bucket{le="0.005", method="GET", path="/api/v1/users"} 10
http_request_duration_seconds_bucket{le="0.01", method="GET", path="/api/v1/users"} 25
http_request_duration_seconds_bucket{le="0.025", method="GET", path="/api/v1/users"} 50
http_request_duration_seconds_bucket{le="0.05", method="GET", path="/api/v1/users"} 80
http_request_duration_seconds_bucket{le="0.1", method="GET", path="/api/v1/users"} 95
http_request_duration_seconds_bucket{le="0.25", method="GET", path="/api/v1/users"} 99
http_request_duration_seconds_bucket{le="0.5", method="GET", path="/api/v1/users"} 100
http_request_duration_seconds_bucket{le="1", method="GET", path="/api/v1/users"} 100
http_request_duration_seconds_bucket{le="+Inf", method="GET", path="/api/v1/users"} 100
http_request_duration_seconds_count{method="GET", path="/api/v1/users"} 100
http_request_duration_seconds_sum{method="GET", path="/api/v1/users"} 3.45
3.6 标准化指标采集模板
为了在集群中统一SLI采集,建议使用Prometheus ServiceMonitor或PodMonitor资源定义采集规则。以下是一个标准化的PodMonitor模板:
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: sli-pod-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app.kubernetes.io/sli-enabled: "true"
podMetricsEndpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
relabelings:
- sourceLabels: [__meta_kubernetes_pod_node_name]
targetLabel: node
- sourceLabels: [__meta_kubernetes_namespace]
targetLabel: namespace
- sourceLabels: [__meta_kubernetes_pod_name]
targetLabel: pod
- sourceLabels: [__meta_kubernetes_pod_container_name]
targetLabel: container
metricRelabelings:
- sourceLabels: [__name__]
regex: 'container_(cpu|memory)_.*|istio_request_duration_milliseconds_.*|http_request_duration_seconds_.*'
action: keep
3.7 指标采集质量检查清单
部署采集配置后,建议按以下清单验证采集质量:
- 指标完整性:确认所有目标Pod的CPU、内存、延迟指标均已出现在Prometheus target列表中
- 数据连续性:检查指标是否存在断点(gap),使用
up{job="sli-pod-monitor"}确认采集状态 - 标签一致性:验证
pod、namespace、container标签是否正确传递 - 延迟桶分布:检查Histogram的
_bucket指标是否覆盖了目标SLO范围 - 资源开销:确认Prometheus采集对目标Pod的CPU/内存开销在可接受范围内(通常 < 1% CPU)
3.8 采集模板与SLO作业模板的集成
标准化采集模板是SLO作业模板的前置依赖。在后续章节中,我们将基于本节采集的SLI指标,构建SLO计算规则和错误预算监控。建议在集群中建立以下命名规范:
- PodMonitor名称:
sli-{service-name}-monitor - PrometheusRule名称:
slo-{service-name}-rules - Grafana Dashboard标签:
sli: enabled和slo: {service-name}