2. Kubernetes 资源管理基础:Pod 与容器的资源请求(Requests)与限制(Limits)概念、QoS 类别
在 Kubernetes 集群中,资源管理是调度与运行时稳定的基石。每个 Pod 由一组容器组成,而每个容器都可以声明其所需的计算资源——CPU 和内存。这些声明通过 Requests(请求) 和 Limits(限制) 两个字段表达,并最终决定了 Pod 的 QoS(服务质量)类别。kubelet 正是依据这些信息与容器运行时(如 containerd、CRI-O)交互,完成容器的创建、资源分配与驱逐决策。
2.1 Requests 与 Limits 的定义与作用
| 字段 | 含义 | 调度依据 | 运行时行为 |
|---|---|---|---|
| Requests | 容器启动时保证获得的最小资源量 | kube-scheduler 根据节点剩余可分配资源进行调度 | cgroup 的 cpu.shares(CPU)和 memory.limit_in_bytes(内存软限制) |
| Limits | 容器运行时不能超过的资源上限 | 不参与调度决策 | cgroup 的 cpu.cfs_quota_us(CPU 硬限制)和 memory.limit_in_bytes(内存硬限制) |
关键区别: Requests 是“保证值”,Limits 是“天花板”。当节点资源紧张时,kubelet 会优先保证 Requests 的满足,而超出 Limits 的容器会被 OOM Kill 或 CPU 节流。
2.2 资源单位与配置示例
- CPU: 以
m(毫核)为单位,1 CPU = 1000m。例如500m表示 0.5 个 CPU 核心。 - 内存: 使用
Mi(Mebibytes)、Gi(Gibibytes)等二进制单位。例如256Mi表示 256 Mebibytes。
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
实践要点: 生产环境中建议始终设置 Requests 与 Limits。仅设置 Limits 而不设置 Requests 会导致调度器低估实际需求,可能引发节点过载。
2.3 QoS 类别:Guaranteed / Burstable / BestEffort
Kubernetes 根据 Pod 中所有容器的 Requests 与 Limits 设置情况,将 Pod 划分为三种 QoS 类别。kubelet 在节点资源压力下,按照 QoS 优先级进行驱逐:BestEffort > Burstable > Guaranteed。
2.4 三种 QoS 类别的详细对比
| QoS 类别 | 设置条件 | CPU 行为 | 内存行为 | 驱逐优先级 |
|---|---|---|---|---|
| Guaranteed | 所有容器 requests == limits(CPU 和内存均设置) | 使用 CFS 配额,不会节流到 requests 以下 | 内存上限严格等于 limits,OOM 优先级最低 | 最低(最安全) |
| Burstable | 至少一个容器 requests < limits,或仅设置 requests | 可突发使用空闲 CPU,但受 CFS 配额限制 | 内存可超用至 limits,超限时 OOM Kill | 中等 |
| BestEffort | 所有容器均未设置 requests 和 limits | 使用空闲 CPU,无保证,可能被节流 | 无内存限制,节点内存不足时最先被杀死 | 最高(最先被驱逐) |
重要提醒: 即使 Pod 的 QoS 类别为 Guaranteed,如果其内存使用超过 limits,仍然会被 OOM Killer 终止。Limits 是硬边界,不是建议值。
2.5 kubelet 与 CRI 的资源交互视角
当 kubelet 创建 Pod 时,它会将 Requests 和 Limits 转换为 CRI 的 LinuxContainerResources 结构体,并通过 RunPodSandbox 和 CreateContainer 接口传递给容器运行时。运行时再将其映射为 cgroup 参数:
// CRI 资源结构体示例(简化)
message LinuxContainerResources {
int64 cpu_shares = 1; // 对应 requests.cpu
int64 cpu_period = 2; // 默认 100000 us
int64 cpu_quota = 3; // 对应 limits.cpu
int64 memory_limit_in_bytes = 4; // 对应 limits.memory
int64 memory_swap_limit_in_bytes = 5; // 通常与 memory_limit 相同
}
容量调优关键: 理解 Requests/Limits 与 cgroup 的映射关系,是后续章节中分析 CPU 节流、内存 OOM、以及 kubelet 驱逐策略的基础。例如,
cpu_shares 控制 CPU 时间片的分配权重,而 cpu_quota 决定容器能否突发使用更多 CPU。
2.6 最佳实践建议
- 生产环境: 始终为所有容器设置 Requests 和 Limits,避免 BestEffort Pod 影响关键业务。
- 性能敏感型应用: 使用 Guaranteed QoS,确保 CPU 和内存的确定性。
- 弹性负载: 使用 Burstable QoS,允许容器在空闲时使用更多资源,但需监控内存超用风险。
- 监控指标: 关注
container_cpu_cfs_throttled_seconds_total和container_oom_events_total,判断资源限制是否合理。