4. SLO 定义与设计:服务等级目标(SLO)的制定原则、延迟与吞吐量指标、可用性SLO的数学表达
在 Kubernetes 容器运行时环境中,HPA 的扩缩容决策最终需要服务于业务层面的服务质量承诺。SLO(Service Level Objective)是连接基础设施容量与用户体验的桥梁。本节将系统阐述 SLO 的制定原则、核心指标选择以及可用性 SLO 的数学建模方法。
4.1 SLO 制定三原则
有效的 SLO 必须同时满足以下三个原则,缺一不可:
| 原则 | 核心要求 | 反例(不可用) |
|---|---|---|
| 可测量性 | 指标必须能从 Prometheus、Datadog 等监控系统直接采集,且采样粒度 ≤ 10s | "系统响应要快"(无量化单位) |
| 可达成性 | 目标值应基于历史 P99 数据设定,预留 20% 缓冲空间 | "全年 100% 可用"(不现实) |
| 可问责性 | SLO 必须对应明确的错误预算消耗规则,触发告警后能定位到具体 Pod 或容器 | "整体体验良好"(无法归因) |
实践建议: 在定义 SLO 前,先确认你的监控系统能按
container、pod、namespace 三个维度聚合指标。如果只能看到集群级平均值,则无法制定有效的容器级 SLO。
4.2 延迟与吞吐量指标
在容器运行时治理中,延迟和吞吐量是 HPA 扩缩容策略最直接的输入信号。以下是两类指标的定义与采集方式:
4.2.1 延迟指标(Latency)
- P50 / P95 / P99 延迟: 分别代表 50%、95%、99% 请求的响应时间上限。P99 是 SLO 最常用的分位点。
- 平均延迟(AVG): 容易受极端值影响,不推荐单独用于 SLO,但可用于趋势观察。
- 采集方式: 通过 Istio/Envoy 的
istio_request_duration_milliseconds_bucket或应用侧 Micrometer 直方图。
4.2.2 吞吐量指标(Throughput)
- RPS(Requests Per Second): 每秒请求数,直接反映业务负载压力。
- 并发连接数: 对于 WebSocket 或长连接服务,比 RPS 更能反映资源占用。
- 采集方式: 使用
rate(http_requests_total[1m])或 K8s 内置的container_network_receive_bytes_total。
关键对比: 延迟指标用于判断"用户体验是否达标",吞吐量指标用于判断"系统是否过载"。HPA 通常以吞吐量作为扩缩容主指标,以延迟作为辅助验证指标。
4.3 可用性 SLO 的数学表达
可用性 SLO 是所有 SLO 中最基础也最容易被误解的一类。其核心数学表达基于"成功请求占总请求的比例":
可用性 SLO = (成功请求数 / 总请求数) × 100%
其中:
- 成功请求数 = 状态码为 2xx 或 3xx 的请求(可根据业务自定义)
- 总请求数 = 所有进入容器的请求(含健康检查、重试等)
示例:30 天内总请求数 10,000,000,成功请求数 9,990,000
可用性 = (9,990,000 / 10,000,000) × 100% = 99.9%
在 Kubernetes 环境中,可用性 SLO 通常以"滑动窗口"形式计算,避免因单次故障导致整个窗口失效:
- 固定窗口(不推荐): 按月/季度统计,一次故障可能导致整个窗口不达标。
- 滑动窗口(推荐): 以 28 天或 30 天为窗口长度,每小时/每天滚动计算,更符合 SRE 实践。
4.4 错误预算(Error Budget)的计算
错误预算 = 1 - SLO。例如 99.9% 可用性对应 0.1% 的错误预算。在 30 天窗口内,允许的失败请求数为:
允许失败数 = 总请求数 × (1 - SLO)
= 10,000,000 × (1 - 0.999)
= 10,000 次失败请求
当消耗的错误预算超过 50% 时,应触发告警并考虑扩容或限流;当消耗超过 100% 时,SLO 已违反,需立即介入。
常见误区: 不要将"可用性 SLO"等同于"Pod 存活率"。Pod 重启但请求仍被正确处理时,可用性 SLO 可能未受影响;反之,Pod 存活但返回 500 错误,则直接消耗错误预算。
4.5 SLO 与 HPA 的联动关系
下图展示了 SLO 定义如何驱动 HPA 扩缩容策略的闭环:
4.6 典型 SLO 定义示例(容器运行时场景)
以下是一个面向容器化微服务的 SLO 定义模板,可直接用于 HPA 策略配置:
| SLO 名称 | 指标来源 | 目标值 | 窗口 | 错误预算 |
|---|---|---|---|---|
| API 响应延迟 | Istio: P99 延迟 | ≤ 200ms | 28 天滑动 | 0.1% 请求超时 |
| 订单服务可用性 | HTTP 状态码 2xx/3xx | ≥ 99.95% | 30 天滑动 | 0.05% 失败请求 |
| 消息队列吞吐量 | Kafka 消费延迟 | ≤ 500ms | 1 小时固定 | N/A(非请求类) |
容器级 SLO 注意事项: 在定义容器运行时 SLO 时,务必区分"容器本身"与"容器内进程"的可用性。例如,容器运行中但进程 OOM,应视为可用性 SLO 违反;容器重启但进程快速恢复,则可能不违反 SLO(取决于重启耗时是否超过延迟阈值)。
4.7 从 SLO 到 HPA 配置的映射
定义好 SLO 后,需要将其转化为 HPA 可理解的指标阈值。以下是一个映射示例:
# SLO 定义
SLO: P99 延迟 ≤ 200ms,错误预算 0.1%
# 映射为 HPA 指标(使用 Prometheus Adapter)
metrics:
- type: Pods
pods:
metric:
name: p99_latency_ms
target:
type: AverageValue
averageValue: 180 # 预留 10% 缓冲,避免频繁触发
# 同时监控错误预算消耗
- type: Object
object:
metric:
name: error_budget_consumption_ratio
target:
type: Value
value: 0.5 # 消耗超过 50% 时触发告警
通过这种映射,HPA 不仅能根据负载扩缩容,还能在 SLO 接近违反边界时主动调整副本数,实现"容量调优"与"SLO 保障"的闭环。