2. Kubernetes 资源模型基础:Pod 资源请求与限制、QoS 类别、资源单位
在 Operator 的容量调优中,理解 Kubernetes 资源模型是第一步。Pod 是调度的最小单元,其资源声明方式直接决定了调度决策、节点压力以及 Operator 在故障场景下的行为。本节将系统梳理 CPU、内存、临时存储的资源单位,以及请求(Requests)与限制(Limits)的语义差异,并深入 QoS 类别的判定逻辑。
2.1 资源单位与语义
Kubernetes 使用三种主要资源类型:CPU、内存和临时存储(Ephemeral Storage)。每种资源都有明确的单位体系和分配语义。
| 资源类型 | 单位 | 常见表示 | 说明 |
|---|---|---|---|
| CPU | 核心(Core) | 0.5、1、2、100m | 1 核心 = 1000m(millicores)。0.5 表示 500m CPU 时间片。 |
| 内存 | 字节(Byte) | 128Mi、1Gi、512M | Mi = 2^20 字节,M = 10^6 字节。推荐使用 Mi/Gi 避免精度问题。 |
| 临时存储 | 字节(Byte) | 1Gi、10Gi | 挂载在 /var/lib/kubelet 的本地存储,用于 emptyDir、日志、容器可写层。 |
关键区分:CPU 是可压缩资源(可以限流),内存和临时存储是不可压缩资源(不足时直接 OOM Kill 或 Evict)。Operator 的稳定性调优应优先保障不可压缩资源的合理预留。
2.2 Requests 与 Limits 的语义差异
每个容器可以在 spec.containers[].resources 下声明 requests 和 limits。两者的调度与执行语义完全不同:
- Requests:调度时保证。kube-scheduler 以 requests 值为依据计算节点剩余容量,确保 Pod 至少能获得该数量的资源。
- Limits:运行时上限。kubelet 强制容器不能超过该值。CPU 超限会被限流(throttle),内存超限会触发 OOM Kill。
Operator 容量规划要点:Operator 的 controller Pod 通常应设置 requests = limits(Guaranteed QoS),避免因突发流量导致节点过载或自身被驱逐。对于 sidecar 或监控组件,可适当放宽 limits 但保持 requests 稳定。
# 典型 Operator Pod 资源声明示例
apiVersion: v1
kind: Pod
metadata:
name: example-operator-pod
spec:
containers:
- name: controller
image: my-operator:latest
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "512Mi"
- name: sidecar
image: metrics-exporter:latest
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
2.3 QoS 类别:Guaranteed、Burstable、BestEffort
Kubernetes 根据 Pod 内所有容器的 requests 和 limits 设置情况,将 Pod 划分为三个 QoS 类别。该类别决定了节点资源压力下的驱逐优先级。
| QoS 类别 | 判定条件 | 驱逐优先级 | 适用场景 |
|---|---|---|---|
| Guaranteed | 所有容器 requests == limits(CPU 和内存均需设置) | 最低(最后被驱逐) | Operator 核心控制器、数据库、关键中间件 |
| Burstable | 至少一个容器设置了 requests,且至少一个容器 requests < limits 或未设置 limits | 中等 | 批处理任务、监控代理、日志采集器 |
| BestEffort | 所有容器均未设置 requests 和 limits | 最高(最先被驱逐) | 开发测试、临时调试 Pod、低优先级作业 |
Operator 稳定性风险:如果 Operator 的 controller Pod 被标记为 BestEffort 或 Burstable,在节点内存压力升高时,kubelet 会优先驱逐这些 Pod,导致 Operator 控制循环中断、CR 状态更新延迟甚至级联故障。生产环境必须将 Operator 核心组件设置为 Guaranteed QoS。
2.4 QoS 判定流程与驱逐顺序
下图展示了 kubelet 在节点资源压力下如何根据 QoS 类别决定驱逐顺序:
2.5 临时存储的特殊性
临时存储(ephemeral-storage)在 Kubernetes 1.19+ 中成为正式资源维度。它与内存类似,属于不可压缩资源,但驱逐机制略有不同:
- 本地临时存储:包括 emptyDir 卷、容器日志、容器可写层、镜像层。
- 节点压力驱逐:当节点磁盘使用率超过阈值(默认 85%),kubelet 开始驱逐 Pod,驱逐顺序同样遵循 QoS 优先级。
- Operator 影响:Operator 如果频繁写入日志或使用 emptyDir 缓存,应设置 ephemeral-storage 的 requests 和 limits,避免因磁盘压力被驱逐。
# 包含临时存储声明的完整资源示例
resources:
requests:
cpu: "500m"
memory: "512Mi"
ephemeral-storage: "1Gi"
limits:
cpu: "500m"
memory: "512Mi"
ephemeral-storage: "2Gi"
容量调优建议:Operator 的 controller Pod 应始终设置 ephemeral-storage 的 requests,且建议 requests 与 limits 一致(Guaranteed QoS)。对于日志量大的 Operator,可考虑将日志挂载到独立持久卷,避免占用节点临时存储。
2.6 资源模型对 Operator 稳定性的影响总结
下表汇总了不同资源声明策略对 Operator 稳定性的影响:
| 配置策略 | QoS 类别 | 调度确定性 | 驱逐风险 | Operator 稳定性 |
|---|---|---|---|---|
| requests=limits(全部资源) | Guaranteed | 高 | 低 | 高(推荐) |
| requests<limits(部分资源) | Burstable | 中 | 中 | 中(可接受,需监控) |
| 仅设置 requests | Burstable | 中 | 中 | 中 |
| 未设置任何资源 | BestEffort | 低 | 高 | 低(生产环境禁止) |