4. 命名空间资源限制:LimitRange 对象、默认请求/限制、最小/最大约束、跨命名空间策略

在多租户集群中,仅靠 ResourceQuota 限制总量是不够的——如果某个 Pod 没有设置资源请求(requests)和限制(limits),它可能“偷用”整个节点的资源,破坏租户间的公平性。LimitRange 对象正是为了解决这一问题而设计的:它在命名空间级别为 Pod 和容器设置默认的资源请求/限制,并强制最小/最大约束,确保每个工作负载都遵循合理的资源边界。

核心要点: LimitRange 是命名空间内的“资源契约”,它定义了单个容器或 Pod 的资源上下限,防止极端资源消耗行为,同时为未显式设置资源的 Pod 提供默认值。

4.1 LimitRange 对象概述

LimitRange 是一个 Kubernetes 原生资源,作用于特定命名空间。它通过一组规则(Limits)来约束该命名空间内 Pod 或容器的资源声明。主要能力包括:

  • 默认请求/限制(Default / DefaultRequest):为未设置资源声明的容器自动注入 CPU 和内存的 requests 与 limits。
  • 最小/最大约束(Min / Max):强制容器或 Pod 的资源声明必须在指定范围内,超出则拒绝创建。
  • 比例约束(MaxLimitRequestRatio):限制 limits 与 requests 的最大比值,防止过度超卖。
字段 类型 说明 示例值
default ResourceList 容器的默认 limits(当 Pod 未指定 limits 时使用) cpu: 500m, memory: 512Mi
defaultRequest ResourceList 容器的默认 requests(当 Pod 未指定 requests 时使用) cpu: 100m, memory: 256Mi
max ResourceList 容器资源声明(requests 或 limits)的最大值 cpu: 2, memory: 4Gi
min ResourceList 容器资源声明的最小值 cpu: 50m, memory: 64Mi
maxLimitRequestRatio ResourceList limits 与 requests 的最大比值(如 3 表示 limits ≤ 3 × requests) cpu: 3, memory: 2
最佳实践: 在创建命名空间时,应同时部署 ResourceQuota 和 LimitRange。ResourceQuota 控制总量,LimitRange 控制单个容器的行为,两者配合形成“总量 + 单量”的双重防线。
LimitRange 在命名空间中的位置与作用 LimitRange 在命名空间中的位置与作用 命名空间:team-alpha ResourceQuota 总量限制:CPU 10, Mem 20Gi LimitRange 单容器约束:Min / Max / Default Pod A requests: 100m / limits: 500m Pod B requests: 200m / limits: 1 Pod C(无声明) → 注入默认值 LimitRange 为每个容器设置资源边界,未声明资源的 Pod 自动获得默认值 超出 Min/Max 范围的 Pod 创建请求将被 API Server 拒绝

4.2 默认请求与限制:为无声明 Pod 注入资源值

在多租户环境中,开发者经常忘记为容器设置 resources 字段。如果没有默认值,这些 Pod 将使用节点的默认 QoS 类别(通常为 BestEffort),可能抢占其他租户的资源。LimitRange 的 default 和 defaultRequest 字段可以自动填充缺失值。

工作流程:

  1. 用户创建 Pod,容器未设置 resources.requests 和 resources.limits。
  2. API Server 检查命名空间内的 LimitRange 对象。
  3. 如果 LimitRange 定义了 default,则将其值设置为容器的 limits。
  4. 如果 LimitRange 定义了 defaultRequest,则将其值设置为容器的 requests。
  5. 如果只定义了 default 而未定义 defaultRequest,则 requests 默认等于 limits(Burstable QoS)。
注意: LimitRange 的默认值仅在 Pod 创建时生效。如果后续修改 LimitRange,已存在的 Pod 不会自动更新资源声明。需要重建 Pod 才能应用新的默认值。

4.3 最小与最大约束:强制资源边界

为了防止某个租户的单个容器占用过多资源,LimitRange 允许设置 min 和 max 约束。任何容器(或 Pod,取决于 scope)的资源声明必须满足:

  • min ≤ requests ≤ max
  • min ≤ limits ≤ max

如果容器声明超出范围,API Server 会返回验证错误,Pod 创建失败。这确保了命名空间内所有工作负载的资源声明都在可控区间内。

场景 LimitRange 配置 容器声明 结果
正常 min: cpu=100m, max: cpu=2 requests: 500m, limits: 1 ✅ 通过
低于最小值 min: cpu=100m, max: cpu=2 requests: 50m, limits: 200m ❌ 拒绝(requests 低于 min)
超过最大值 min: cpu=100m, max: cpu=2 requests: 1, limits: 4 ❌ 拒绝(limits 超过 max)
未声明(有默认值) default: cpu=500m, min: cpu=100m 未设置 ✅ 注入默认值 500m,满足 min

4.4 跨命名空间策略:全局与局部资源治理

LimitRange 是命名空间级别的资源,无法直接跨命名空间生效。但在多租户集群中,我们需要一种机制来确保所有命名空间都遵循统一的资源治理策略。常见的跨命名空间策略包括:

  • 模板化部署:通过 GitOps 或 Operator 在创建命名空间时自动注入预定义的 LimitRange 模板。
  • 准入控制 Webhook:使用 ValidatingAdmissionPolicy 或自定义 Webhook 强制每个命名空间必须包含 LimitRange,或统一校验资源声明。
  • 组织策略(OPA/Gatekeeper):使用 ConstraintTemplate 定义全局规则,例如“所有命名空间的 LimitRange 必须设置 min 和 max”。
跨命名空间资源策略架构 跨命名空间资源策略架构 全局策略层:OPA/Gatekeeper / ValidatingAdmissionPolicy 强制每个命名空间必须包含 LimitRange,且满足最小资源边界 命名空间:team-a LimitRange: min=100m, max=2 Pod: requests=200m, limits=1 命名空间:team-b LimitRange: min=200m, max=4 Pod: requests=500m, limits=2 命名空间:team-c LimitRange: min=50m, max=1 Pod: requests=100m, limits=500m 每个命名空间拥有独立的 LimitRange,但全局策略确保所有命名空间 都设置了合理的资源边界,防止“无限制”命名空间的出现 策略引擎(OPA/Gatekeeper)在 Admission 阶段拦截并验证

4.5 实战:LimitRange 配置示例

以下是一个完整的 LimitRange YAML 示例,展示了如何在一个命名空间中同时设置默认值、最小/最大约束和比例约束:

apiVersion: v1
kind: LimitRange
metadata:
  name: team-resource-policy
  namespace: team-alpha
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "100m"
      memory: "256Mi"
    max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
    maxLimitRequestRatio:
      cpu: "3"
      memory: "2"

配置解读:

  • 任何未设置资源的容器将获得 CPU requests=100m、limits=500m,内存 requests=256Mi、limits=512Mi。
  • 任何容器的 CPU 声明必须在 50m~2 之间,内存必须在 64Mi~4Gi 之间。
  • CPU 的 limits/requests 比值不得超过 3,内存比值不得超过 2。
验证命令: 使用 kubectl describe limitrange team-resource-policy -n team-alpha 查看生效的规则。创建测试 Pod 时,可以通过 kubectl get pod <pod-name> -o yaml 确认资源字段是否被正确注入。

4.6 避坑指南

常见问题 原因 解决方案
Pod 创建失败,提示“exceeded max” 容器资源声明超过 LimitRange 的 max 值 调整容器资源声明,或修改 LimitRange 的 max 值
Pod 创建失败,提示“below min” 容器资源声明低于 LimitRange 的 min 值 增加容器资源声明,或降低 min 值
Pod 运行但 QoS 为 BestEffort LimitRange 未设置 default 和 defaultRequest,且 Pod 未声明资源 在 LimitRange 中添加 default 和 defaultRequest 字段
修改 LimitRange 后 Pod 未生效 LimitRange 仅对新创建的 Pod 生效 重建已有 Pod 以应用新的资源约束
跨命名空间策略不一致 缺少全局策略引擎,各命名空间自行配置 部署 OPA/Gatekeeper 或 ValidatingAdmissionPolicy 统一治理

通过合理配置 LimitRange,多租户集群可以实现“细粒度资源治理”——每个租户的每个容器都有明确的资源边界,既防止了资源滥用,又保证了集群的整体稳定性。下一层级的资源隔离将结合 NetworkPolicy 和 Pod Security Standards 进一步强化租户间的安全边界。