4. 容器资源限制基础:requests 与 limits 的定义、CPU 与内存单位、QoS 类别

在 Kubernetes 集群中,容器资源限制是保障集群稳定性与公平调度的基石。没有资源约束的 Pod 可能耗尽节点资源,导致其他 Pod 被驱逐甚至节点宕机。本章深入解析 requests 与 limits 的定义、CPU/内存单位换算以及由此产生的三种 QoS(服务质量)类别,为后续的容量规划与 OPA 策略编写奠定基础。

4.1 requests 与 limits 的定义

Kubernetes 通过两个关键字段控制容器的资源使用:

  • requests:容器启动时向节点请求的“最小保证资源”。调度器依据 requests 值选择满足条件的节点;如果节点资源不足,Pod 将处于 Pending 状态。
  • limits:容器运行时允许使用的“资源上限”。当容器试图使用超过 limits 的资源时,CPU 会被节流(throttle),内存不足时容器会被 OOM Kill。
关键原则:limits 必须大于或等于 requests。如果只设置 limits 而未设置 requests,Kubernetes 会自动将 requests 设置为与 limits 相同的值。

以下是一个典型的资源声明示例:

apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: app
    image: nginx:1.25
    resources:
      requests:
        cpu: "500m"
        memory: "256Mi"
      limits:
        cpu: "1"
        memory: "512Mi"

4.2 CPU 与内存单位详解

Kubernetes 使用标准化单位表示 CPU 和内存,理解这些单位对精确配置至关重要。

资源类型 单位 说明 示例
CPU 整数核 1 个 vCPU / 超线程核心 cpu: "2" 表示 2 个完整核心
毫核(m) 1 核 = 1000m,最小粒度 1m cpu: "500m" 表示 0.5 个核心
小数 与毫核等价,但推荐使用 m 单位 cpu: "0.5" 等价于 500m
内存 字节(B) 基础单位,通常不使用裸数字 memory: "536870912"(不推荐)
Ki / Mi / Gi 二进制单位(2^10 进制) memory: "256Mi" = 256 × 1024² 字节
K / M / G 十进制单位(10^3 进制) memory: "256M" = 256 × 1000² 字节
注意事项 Kubernetes 内部以字节计算,但推荐使用二进制单位(Mi/Gi)避免精度误差
常见陷阱:CPU 的 "m" 单位是毫核,不是毫秒。设置 cpu: "1000m" 与 cpu: "1" 完全等价。内存的 "M" 与 "Mi" 相差约 4.86%,在大型内存配置中可能造成意外 OOM。

4.3 QoS 类别:Guaranteed / Burstable / BestEffort

Kubernetes 根据 Pod 中所有容器的 requests 与 limits 配置,自动将 Pod 归入三种 QoS(服务质量)类别之一。该类别决定了节点资源紧张时 Pod 被驱逐的优先级。

Kubernetes QoS 类别判定流程 Pod 资源声明 所有容器均设置 requests == limits? (CPU 和内存均需满足) 是 Guaranteed 最高优先级,最后被驱逐 否 至少一个容器 设置了 requests? 是 Burstable 中等优先级,可突发使用 否 BestEffort 最低优先级,最先被驱逐 驱逐优先级(节点资源不足时): BestEffort → Burstable(按 OOM 分数排序)→ Guaranteed(仅当节点发生系统 OOM 时) 注:Guaranteed Pod 的 OOM 分数最低,系统会优先杀死其他 Pod 来释放内存。

4.4 三种 QoS 类别的详细对比

QoS 类别 触发条件 CPU 行为 内存行为 驱逐优先级 典型场景
Guaranteed 所有容器 requests == limits(CPU 和内存均需满足) 保证 requests 值,可突发至 limits 保证 requests 值,超过 limits 触发 OOM 最低(最后被驱逐) 数据库、关键中间件、有状态服务
Burstable 至少一个容器设置了 requests,且不满足 Guaranteed 条件 保证 requests 值,可突发至 limits 保证 requests 值,超过 limits 触发 OOM 中等(按 OOM 分数排序) Web 服务、API 网关、批处理任务
BestEffort 没有任何容器设置 requests 和 limits 无保证,节点空闲时可使用任意 CPU 无保证,节点空闲时可使用任意内存 最高(最先被驱逐) 开发测试、非关键日志收集、临时任务
安全基线建议:生产环境应避免使用 BestEffort 类别。对于关键业务 Pod,推荐使用 Guaranteed 类别以确保资源稳定性;对于可弹性伸缩的微服务,Burstable 类别配合合理的 requests/limits 比例(如 1:2)是性价比最高的选择。

4.5 OOM 分数与驱逐机制

当节点内存不足时,kubelet 会启动驱逐流程。每个 Pod 的 OOM 分数由 QoS 类别和实际内存使用量共同决定:

  • BestEffort Pod:OOM 分数最高(通常为 1000),优先被杀死。
  • Burstable Pod:OOM 分数 = 1000 - (实际内存使用量 / 节点内存总量) × 1000。使用内存越多的 Pod 分数越高,越容易被杀死。
  • Guaranteed Pod:OOM 分数最低(通常为 0-10),仅在节点发生系统级 OOM 且无其他 Pod 可杀时才会被终止。
OOM 分数与驱逐优先级关系 低 高 OOM 分数 QoS 类别 Guaranteed 0-10 Burstable 0-1000 BestEffort 1000 驱逐优先级递增

4.6 安全基线配置示例

以下是一个符合生产安全基线的 Deployment 资源声明,结合了 QoS 类别选择与资源限制:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: secure-app
  template:
    metadata:
      labels:
        app: secure-app
    spec:
      containers:
      - name: app
        image: myapp:1.0.0
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1"
            memory: "1Gi"
        securityContext:
          runAsNonRoot: true
          runAsUser: 1001
          capabilities:
            drop: ["ALL"]
      - name: sidecar
        image: envoy:1.28
        resources:
          requests:
            cpu: "200m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "256Mi"
        securityContext:
          runAsNonRoot: true
          runAsUser: 1002
配置要点:
  • 主容器与 sidecar 均设置了 requests 和 limits,且两者不相等 → 整体 Pod 属于 Burstable 类别。
  • CPU 的 requests/limits 比例为 1:2,内存比例为 1:2,允许突发但有限制。
  • 结合 securityContext 实现最小权限原则,符合安全基线要求。

4.7 常见配置错误与避坑指南

错误模式 后果 正确做法
只设置 limits 不设置 requests requests 自动等于 limits,可能过度预留资源 显式设置 requests 为实际基线值
CPU requests 设置过高 节点资源碎片化,Pod 调度失败 基于历史监控数据设置合理的 requests
内存 limits 设置过低 容器频繁 OOM Kill,影响服务可用性 设置 limits 为 requests 的 1.5~2 倍,并配置 livenessProbe
所有 Pod 使用 BestEffort 节点资源紧张时大量 Pod 被驱逐 至少设置 requests,生产环境避免 BestEffort
使用十进制内存单位(M/G) 与二进制单位(Mi/Gi)存在约 5% 差异 统一使用二进制单位(Mi/Gi)
容量规划警示:requests 的总和决定了集群的“资源承诺”,而 limits 的总和决定了“资源上限”。在规划节点容量时,应确保节点可分配资源 ≥ 所有 Pod 的 requests 总和,同时预留 10%~20% 的系统开销(kubelet、操作系统、DaemonSet 等)。