3. SLI指标设计原则:如何选择有效的SLI指标
在Kubernetes环境下,SLO的可靠性运营始于正确的SLI选择。SLI(Service Level Indicator)是衡量服务行为的具体量化指标,其选择质量直接决定SLO的可用性与可操作性。本节将围绕Google SRE经典四大黄金信号——延迟、流量、错误、饱和度,阐述其在K8s场景下的映射原则与选型方法。
3.1 黄金信号概述与K8s映射矩阵
四大黄金信号覆盖了用户可感知的服务质量与系统内部健康度。下表展示了每个信号在Kubernetes环境中的典型映射对象与采集来源:
| 黄金信号 | 核心关注点 | K8s映射对象 | 典型采集来源 |
|---|---|---|---|
| 延迟 (Latency) | 请求处理耗时,区分成功与失败 | Pod/Service响应时间、Ingress/API Server延迟 | Prometheus Histogram、Istio/Envoy指标 |
| 流量 (Traffic) | 系统负载需求,QPS/RPS/连接数 | Pod/Service请求速率、Node网络吞吐 | kube-state-metrics、cAdvisor、ServiceMonitor |
| 错误 (Errors) | 显式/隐式失败率,HTTP 5xx/4xx/超时 | Pod/Service错误率、OOMKilled、CrashLoopBackOff | Prometheus Counter、Event API、kubectl get events |
| 饱和度 (Saturation) | 资源耗尽程度,CPU/Mem/磁盘/网络 | Node/Pod资源使用率、HPA扩缩容状态、OOM事件 | Metrics Server、Node Exporter、Kubernetes ResourceQuota |
选型原则:优先选择用户可感知的指标作为SLI。例如,对于Web服务,延迟和错误率是直接反映用户体验的黄金信号;对于批处理任务,饱和度(资源争抢)和错误(任务失败率)更为关键。
3.2 延迟指标设计原则
延迟指标应区分成功请求与失败请求的延迟分布。在K8s中,建议使用分位数(p50/p90/p99)而非平均值,以避免长尾效应掩盖真实性能。
- 原则1:延迟SLI必须基于服务端感知的请求处理时间,排除客户端网络抖动。
- 原则2:在Istio/Envoy网格中,使用
istio_request_duration_millisecondsHistogram指标,按destination_service和response_code分组。 - 原则3:对于API Server延迟,监控
apiserver_request_duration_seconds,重点关注写操作(CREATE/PUT/DELETE)的p99。
# PromQL示例:计算服务A的p99延迟(毫秒)
histogram_quantile(0.99,
sum(rate(istio_request_duration_milliseconds_bucket{
destination_service="service-a.ns.svc.cluster.local",
response_code=~"2[0-9]{2}|3[0-9]{2}"
}[5m])) by (le)
)
3.3 流量指标设计原则
流量反映系统当前承载的请求量级,是判断负载变化趋势和容量规划的基础。在K8s中,流量SLI应关注请求速率与并发连接数。
- 原则1:使用
rate()函数计算每秒请求数(RPS),避免使用原始Counter值。 - 原则2:区分南北向流量(Ingress/Service)与东西向流量(Pod间通信),分别设定SLI阈值。
- 原则3:结合HPA(Horizontal Pod Autoscaler)的
kube_horizontalpodautoscaler_status_current_replicas,判断流量是否触发自动扩缩容。
避坑提示:不要将Node级别的网络吞吐直接作为服务流量SLI,因为Node可能运行多个Pod,吞吐量无法精确反映单个服务的负载。应优先使用Service级别的指标。
3.4 错误指标设计原则
错误SLI应覆盖显式错误(HTTP 5xx、4xx)和隐式错误(响应超时、业务逻辑异常)。在K8s中,还需关注Pod生命周期错误。
- 原则1:错误率计算分母应为总请求数,而非仅成功请求数。
- 原则2:在K8s中,将
kube_pod_status_phase{phase="Failed"}和kube_pod_container_status_restarts_total纳入错误SLI,反映基础设施层面的故障。 - 原则3:对于gRPC服务,监控
grpc_server_handled_total并按grpc_code分组,将Unavailable/Internal/DeadlineExceeded视为错误。
# PromQL示例:计算服务B的错误率(HTTP 5xx + 请求超时)
sum(rate(http_requests_total{
service="service-b",
status=~"5[0-9]{2}|timeout"
}[5m]))
/
sum(rate(http_requests_total{
service="service-b"
}[5m]))
3.5 饱和度指标设计原则
饱和度是预测系统瓶颈的前瞻性指标。在K8s中,饱和度SLI应覆盖计算资源、内存资源、存储资源和网络资源。
- 原则1:使用资源利用率百分比而非值,便于跨环境对比。
- 原则2:关注资源预留与资源限制的差值,判断是否存在资源碎片。
- 原则3:对于有状态服务(如数据库),监控磁盘IOPS和网络带宽饱和度,而非仅CPU/Mem。
| 资源类型 | K8s指标 | 饱和度阈值建议 |
|---|---|---|
| CPU | node_cpu_seconds_total / container_cpu_usage_seconds_total |
长期 > 80% 触发预警 |
| 内存 | node_memory_MemAvailable_bytes / container_memory_working_set_bytes |
剩余 < 20% 触发预警 |
| 磁盘 | node_filesystem_avail_bytes / container_fs_usage_bytes |
剩余 < 15% 触发预警 |
| 网络 | node_network_receive_bytes_total / container_network_receive_bytes_total |
带宽利用率 > 70% 触发预警 |
3.6 黄金信号在K8s中的映射架构
下图展示了四大黄金信号在Kubernetes集群中的采集、聚合与SLO计算的整体映射关系:
3.7 SLI选择避坑清单
在实际运营中,以下常见错误会削弱SLI的有效性:
- ❌ 使用平均值掩盖长尾:延迟SLI必须使用分位数(p99/p90),平均值会掩盖5%的慢请求。
- ❌ 忽略隐式错误:仅监控HTTP 5xx,遗漏了业务逻辑错误(如返回200但数据为空)或Pod重启导致的请求中断。
- ❌ 饱和度指标滞后:仅监控CPU利用率,忽略了内存OOM或磁盘IO瓶颈,导致故障发生后才告警。
- ❌ 指标粒度过粗:使用Node级别指标代替Pod/Service级别指标,无法精确定位故障服务。
- ❌ 未区分成功/失败延迟:将失败请求的延迟混入成功请求的延迟统计中,导致SLO失真。
关键提醒:SLI指标选择应遵循“少而精”原则。每个服务建议选择2~3个核心黄金信号作为SLI,避免指标爆炸导致SLO管理复杂化。优先选择与用户体验直接相关的延迟和错误指标,再辅以饱和度和流量指标用于容量规划。