4.1 LimitRange 基础:作用、默认请求/限制、最小/最大约束

在 Kubernetes 多租户或团队共享集群的场景中,如果没有对 Namespace 内的 Pod 资源进行约束,个别“超规格”容器可能耗尽节点资源,导致其他正常 Pod 被驱逐或无法调度。LimitRange 正是 Namespace 级别的资源策略工具,它通过声明式配置,为 Namespace 内所有 Pod 或容器设定资源使用的“下限”与“上限”,并自动注入默认的 request 与 limit。

4.1.1 LimitRange 的核心作用

作用维度 说明 典型场景
默认值注入 当 Pod 未显式设置 resource request/limit 时,LimitRange 自动为其填充预设值 开发人员忘记写资源规格,避免 Pod 因无限制而抢占节点资源
最小约束 强制 Pod 的 request/limit 不能低于指定值,防止“微容器”过度挤占调度资源 禁止创建 CPU request < 0.1 核的 Pod,保证基础调度权重
最大约束 限制 Pod 的 request/limit 不能超过指定值,防止单个 Pod 垄断节点 限制单容器内存 limit ≤ 8Gi,避免内存泄漏影响集群稳定性
比例约束 强制 limit / request 的比值范围(如 maxLimitRequestRatio) 限制 CPU 的 limit/request ≤ 3,防止过度超卖导致 CPU 竞争
成本调优视角: LimitRange 是 Namespace 资源预算的“第一道防线”。通过设置合理的默认值与上限,可以避免因 Pod 规格差异过大导致的资源碎片,从而提升节点装箱率,降低单位 Pod 的云资源成本。

4.1.2 默认请求/限制的注入机制

当 Pod 中某个容器未指定 resources.requests 或 resources.limits 时,LimitRange 会根据 default 和 defaultRequest 字段自动补全。注入规则如下:

  • default:容器的 limits 默认值(若容器未定义 limits)。
  • defaultRequest:容器的 requests 默认值(若容器未定义 requests)。
  • 如果只设置了 default 而未设置 defaultRequest,则 requests 会继承 default 的值(即 request = limit)。
  • 如果只设置了 defaultRequest 而未设置 default,则 limits 不会被自动注入,但 Pod 仍需通过准入检查。
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-mem-defaults
  namespace: team-budget
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    min:
      cpu: "100m"
      memory: "128Mi"
    max:
      cpu: "2"
      memory: "4Gi"
    maxLimitRequestRatio:
      cpu: "3"
验证命令: 创建上述 LimitRange 后,在 team-budget Namespace 中创建一个未指定资源的 Pod,使用 kubectl describe pod <pod-name> 查看自动注入的 request 和 limit。

4.1.3 最小/最大约束的准入控制

LimitRange 的 min 和 max 字段在 Pod 创建或更新时由 LimitRanger 准入控制器 强制执行。如果 Pod 中任意容器的资源声明违反约束,API Server 会直接拒绝请求,并返回明确的错误信息。

约束类型 检查对象 违反示例 错误提示(部分)
min 容器的 requests 和 limits 均不能低于 min 值 memory request = 64Mi < min 128Mi minimum memory usage per Container is 128Mi
max 容器的 requests 和 limits 均不能高于 max 值 cpu limit = 4 > max 2 maximum cpu usage per Container is 2
maxLimitRequestRatio 容器的 limit / request 比值不能超过该值 cpu limit=3, request=0.5, 比值=6 > 3 ratio cpu limit/request is 6, max allowed ratio is 3
注意: LimitRange 的约束是 Namespace 级别 的,且只对创建或更新操作生效,不会影响已存在的 Pod。如果需要全局约束,应结合 ResourceQuota 使用。

4.1.4 LimitRange 资源约束流程

下图展示了 LimitRange 在 Pod 创建时的完整处理流程,包括默认值注入与约束校验:

LimitRange 准入控制流程 用户提交 Pod YAML API Server 接收请求 LimitRanger 准入控制器 读取 Namespace 关联的 LimitRange 对象 步骤1:默认值注入 补全未设置的 request/limit 步骤2:约束校验 检查 min/max/ratio ✅ 通过 → Pod 创建成功 ❌ 拒绝 → 返回错误信息 说明:默认值注入在约束校验之前执行,因此注入后的值也必须满足 min/max 约束 若注入后的值超出 max 或低于 min,Pod 仍会被拒绝

4.1.5 多类型 LimitRange 与作用域

LimitRange 支持按 type 区分作用域,常见类型包括:

类型 作用对象 典型配置项
Container Pod 中的每个容器 cpu, memory 的 default / defaultRequest / min / max
Pod Pod 级别(所有容器资源总和) Pod 总 CPU/内存的 min / max
PersistentVolumeClaim PVC 的存储请求 storage 的 min / max
最佳实践: 在成本敏感的生产环境中,建议为每个 Namespace 同时配置 Container 和 Pod 类型的 LimitRange。前者控制单容器规格,后者控制 Pod 整体资源上限,防止 Sidecar 容器过多导致资源膨胀。

4.1.6 常见问题与避坑

  • LimitRange 不限制 InitContainer: InitContainer 的资源声明不受 LimitRange 约束,需单独通过 ResourceQuota 或 Pod 安全策略管理。
  • 默认值覆盖顺序: 如果 Pod 中部分容器指定了 request 但未指定 limit,LimitRange 只注入 limit 默认值,不会覆盖已显式设置的 request。
  • 更新已有 LimitRange: 修改 LimitRange 后,仅对新创建的 Pod 生效,已运行的 Pod 不受影响。如需强制更新,需重建 Pod。
  • 与 ResourceQuota 的协作: LimitRange 控制“单个 Pod 的规格”,ResourceQuota 控制“Namespace 的总量”。两者配合使用可实现精细化的资源预算管理。
成本优化提示: 通过设置合理的 maxLimitRequestRatio(如 CPU ≤ 3、内存 ≤ 2),可以避免 Pod 的 limit 远大于 request 导致的资源超卖风险,从而提升集群的调度稳定性与资源利用率。