4. 资源水位定义:CPU/内存/存储的请求与限制水位、水位阈值设定原则

资源水位是 VPA 驱动成本优化的核心标尺。定义不清的水位会导致两种极端:请求(Requests) 设置过高造成资源浪费,或 限制(Limits) 设置过低引发 OOMKill 与性能抖动。本章将系统定义 CPU、内存、存储三类资源的水位模型,并给出安全水位与弹性水位的设定原则。

4.1 资源水位基础模型

在 Kubernetes 中,每个容器可定义两类资源约束:

  • Requests(请求):调度时保证的最小资源量,也是集群资源计费的基准。
  • Limits(限制):运行时允许使用的资源上限,超过则触发节流(CPU)或驱逐(内存)。

VPA 的核心工作就是动态调整 Requests,而 Limits 通常由运维策略或 LimitRange 控制。存储水位则通过 PVC 的 Requests 字段定义,VPA 目前仅支持对存储的垂直扩缩(需启用 StorageVPA 特性门控)。

关键认知: VPA 不直接修改 Limits,而是通过 Recommender 给出推荐值,由 Updater 执行 Eviction 后,Admission Controller 在 Pod 重建时注入新的 Requests。因此,Limits 的水位策略需要独立定义。

4.2 CPU 水位定义

水位指标 定义公式 典型值(mCPU) 监控指标
请求水位(Request) P99(8h CPU Usage) × 安全系数 250m – 2000m container_cpu_usage_seconds_total
限制水位(Limit) Request × 弹性倍数 500m – 4000m container_cpu_cfs_throttled_seconds_total
节流水位(Throttle) CPU Throttle Rate > 5% 触发告警 container_cpu_cfs_periods_total

设定原则:

  • 安全水位(Requests):基于过去 7–14 天的 P95/P99 实际用量,叠加 10%–20% 的缓冲系数,确保调度稳定。
  • 弹性水位(Limits):设置为 Requests 的 1.5–2.0 倍,允许突发流量时使用额外 CPU 资源,但不超过节点剩余容量。
  • 节流监控:当 CPU Throttle 比例超过 5% 时,说明 Limits 设置过紧,需要上调弹性倍数。

4.3 内存水位定义

水位指标 定义公式 典型值(MiB) 监控指标
请求水位(Request) P99(7d RSS Usage) + 安全余量 128 – 4096 container_memory_working_set_bytes
限制水位(Limit) Request × 弹性倍数(通常 1.0–1.25) 256 – 5120 container_memory_rss
OOM 水位 Usage > Limit × 0.95 触发 OOMKill container_oom_events_total

设定原则:

  • 安全水位(Requests):内存不可压缩,必须基于 working_set_bytes 的 P99 值,并额外增加 15%–25% 的余量,防止 GC 抖动或缓存膨胀。
  • 弹性水位(Limits):内存弹性倍数建议 ≤ 1.25,因为过度承诺内存会导致节点 OOM 风险急剧上升。对于 Java/Go 等有堆内内存管理的应用,建议 Limits = Requests × 1.1。
  • OOM 预警:当内存使用率持续超过 Limits 的 90% 时,应触发告警并考虑提前扩容。

4.4 存储水位定义

水位指标 定义公式 典型值(GiB) 监控指标
请求水位(PVC Request) P99(7d Disk Usage) × 1.3 10 – 500 kubelet_volume_stats_used_bytes
扩容水位 Usage > PVC Request × 0.8 触发 VPA 扩容 kubelet_volume_stats_capacity_bytes
缩容水位 Usage < PVC Request × 0.3 持续 72h 触发 VPA 缩容 kubelet_volume_stats_available_bytes

设定原则:

  • 安全水位(PVC Request):基于历史峰值用量乘以 1.3 倍系数,预留足够的 inode 和元数据空间。
  • 弹性水位:存储的弹性体现在扩容速度(云盘通常支持在线扩容),因此扩容水位设为 80%,缩容水位设为 30% 并持续 72 小时,避免频繁缩容引发 I/O 抖动。
  • 注意:存储 VPA 目前仅支持 ExpandInUsePersistentVolumes 特性,缩容需要重建 PVC,建议仅对无状态或可迁移数据使用。

4.5 安全水位 vs 弹性水位:阈值设定原则

核心原则: 安全水位保稳定,弹性水位保成本。两者之间通过“水位间隙”实现资源复用与突发容忍的平衡。

下表对比两种水位的设计目标与设定方法:

维度 安全水位(Requests) 弹性水位(Limits)
目标 保证调度确定性,避免资源争抢 允许突发流量,提高资源复用率
数据来源 P95/P99 历史用量 + 安全系数 安全水位 × 弹性倍数
CPU 弹性倍数 — 1.5 – 2.0
内存弹性倍数 — 1.0 – 1.25
存储弹性倍数 — 1.3(扩容水位)
调整频率 VPA Recommender 每 1h 更新 运维策略固定,或通过 LimitRange 控制
风险 设置过高 → 资源浪费 设置过低 → 节流/OOM

阈值设定五步法:

  1. 采集基线:使用 Prometheus 采集 14 天的 CPU、内存、存储用量,排除部署/回滚等异常窗口。
  2. 计算 P99:对每个容器计算 P99 用量,作为安全水位的基准。
  3. 叠加系数:CPU 加 10%,内存加 20%,存储加 30%,得到初始 Requests。
  4. 设定弹性倍数:CPU 设为 1.5,内存设为 1.1,存储设为 1.3(扩容水位)。
  5. 观察与微调:运行 72 小时后,检查节流率、OOM 事件、磁盘使用率,反向调整系数。

4.6 资源水位关系图

下图展示了 CPU 与内存的安全水位、弹性水位、节流/OOM 水位之间的层级关系:

资源水位层级关系(CPU / 内存) 安全水位(Requests) 基于 P99 历史用量 + 安全系数(CPU 10% / 内存 20%) 弹性水位(Limits) 安全水位 × 弹性倍数(CPU 1.5–2.0 / 内存 1.0–1.25) 节流 / OOM 水位(Throttle / OOM) CPU Throttle > 5% 或 内存使用 > Limits × 0.95 水位间隙 = 弹性水位 − 安全水位 间隙越大,突发容忍度越高,但节点资源复用率越低; 间隙越小,资源利用率越高,但节流/OOM 风险越大。

4.7 证书轮换作业的特殊水位考量

证书轮换作业(如 cert-manager 的 cmctl renew 或自定义 CronJob)具有明显的 突发性 和 短生命周期 特征,水位设定需额外注意:

  • CPU 水位:轮换作业通常涉及证书签名与 API 调用,CPU 峰值可达常规 Pod 的 3–5 倍。建议安全水位按 P99 设定,弹性倍数提升至 3.0,避免签名超时。
  • 内存水位:证书轮换作业内存消耗相对稳定,但需注意大量证书并发轮换时的内存叠加。建议安全水位按 P99 + 30%,弹性倍数设为 1.5。
  • 存储水位:证书轮换作业通常不涉及持久化存储,但若使用 vault 或 PKI 后端,需确保临时卷的存储水位不低于 1GiB。
  • 时间窗口:证书轮换作业应在集群低负载时段执行,避免与业务高峰重叠,从而降低对弹性水位的依赖。
避坑提示: 证书轮换作业的 VPA 配置应使用 updateMode: "Off" 或 "Initial",避免 VPA 在作业执行期间频繁驱逐 Pod 导致轮换失败。推荐在作业启动前由 Operator 手动触发一次 VPA 推荐更新。

4.8 水位设定清单

资源类型 安全水位(Requests) 弹性水位(Limits) 告警阈值 VPA 模式
CPU(常规业务) P99(14d) × 1.1 Requests × 1.5 Throttle > 5% Auto
CPU(证书轮换) P99(14d) × 1.1 Requests × 3.0 Throttle > 10% Initial
内存(常规业务) P99(14d) × 1.2 Requests × 1.1 Usage > Limits × 0.9 Auto
内存(证书轮换) P99(14d) × 1.3 Requests × 1.5 Usage > Limits × 0.85 Initial
存储(PVC) P99(7d) × 1.3 — Usage > PVC × 0.8 Auto(需特性门控)

以上清单可直接作为团队内部的水位定义标准,结合 VPA Recommender 的推荐值进行周期性校准(建议每两周一次)。