4、资源配额模型概述:Namespace ResourceQuota、LimitRange、以及自定义配额策略

在 Kubernetes 多租户或团队共享集群的场景中,资源配额模型是保障集群稳定性与公平性的第一道防线。本章将系统梳理三种核心配额控制机制:Namespace ResourceQuota(命名空间级总量控制)、LimitRange(Pod/容器级默认值与边界约束),以及自定义配额策略(基于准入控制器实现的灵活扩展)。理解这三者的分层关系与协作方式,是设计生产级资源配额架构的基础。

核心认知:ResourceQuota 解决“总量不能超”,LimitRange 解决“单个体不能越界”,自定义策略解决“业务规则不能漏”。三者叠加形成从集群到工作负载的完整配额防护网。

4.1 资源配额模型的分层架构

资源配额模型在 Kubernetes 中并非单一组件,而是由多个准入控制插件与 API 对象共同构成的层次化体系。下图展示了从集群管理员到最终用户工作负载之间的配额控制链路:

资源配额模型分层架构图 资源配额模型分层架构 集群层:全局默认配额 / 集群资源池 ClusterResourceQuota(OpenShift) / 集群管理员手动分配 命名空间层:ResourceQuota 对象 CPU / 内存 / 存储 / 对象数量(Pod、Service、PVC 等) 工作负载边界层:LimitRange 对象 默认 request/limit / 最小/最大约束 / 比例约束 自定义策略层:准入控制器 + OPA/Gatekeeper / Kyverno 标签约束、成本分摊、环境隔离、临时存储限制等
架构要点:每一层解决不同粒度的配额问题。集群层关注总容量,命名空间层关注租户预算,工作负载边界层关注容器规格合规,自定义策略层关注业务语义。四层缺一不可,且必须按顺序依次生效。

4.2 Namespace ResourceQuota:命名空间级总量控制

ResourceQuota 是 Kubernetes 原生 API 对象,作用于特定 Namespace,用于限制该命名空间内所有 Pod 和资源的累计使用量。它是最直接、最常用的配额手段。

4.2.1 核心字段与作用范围

资源类型 字段示例 说明
计算资源 requests.cpu、requests.memory、limits.cpu、limits.memory 所有 Pod 的 request/limit 总和上限
存储资源 requests.storage、persistentvolumeclaims PVC 请求的总存储容量与数量
对象数量 pods、services、configmaps、secrets、replicationcontrollers 命名空间内各类 Kubernetes 对象的最大数量
扩展资源 requests.nvidia.com/gpu 自定义扩展资源(如 GPU、FPGA)的总量限制

4.2.2 典型 ResourceQuota 配置示例

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"
    services: "10"
    persistentvolumeclaims: "5"
    requests.storage: "100Gi"
    configmaps: "20"
    secrets: "20"
重要行为:ResourceQuota 一旦创建,命名空间内所有新创建或更新的 Pod 必须设置 requests 和 limits(除非 LimitRange 提供了默认值)。否则准入控制器将拒绝创建。这是初学者最容易忽略的“先有鸡还是先有蛋”问题。

4.3 LimitRange:Pod/容器级边界约束

LimitRange 与 ResourceQuota 互补:ResourceQuota 管总量,LimitRange 管个体。LimitRange 在命名空间级别为每个容器或 Pod 设置默认值、最小值、最大值以及比例约束(如 limit/request 比例)。

4.3.1 LimitRange 的四种约束类型

  • 默认值(default):当容器未指定 resources.limits 时,自动注入默认 limit。
  • 默认请求值(defaultRequest):当容器未指定 resources.requests 时,自动注入默认 request。
  • 最大值(max):容器指定的 limit 不能超过此值。
  • 最小值(min):容器指定的 request 不能低于此值。
  • 比例约束(maxLimitRequestRatio):强制 limit / request 的比值不超过指定数值。

4.3.2 典型 LimitRange 配置示例

apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: team-a
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    max:
      cpu: "4"
      memory: "8Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
    maxLimitRequestRatio:
      cpu: "4"
最佳实践:始终为每个命名空间同时配置 ResourceQuota 和 LimitRange。ResourceQuota 防止租户超支,LimitRange 防止单个容器规格异常(如误设 64Gi 内存)。两者配合可覆盖 90% 的配额管理场景。

4.4 自定义配额策略:超越原生能力的扩展

原生 ResourceQuota 和 LimitRange 无法覆盖所有业务场景,例如:

  • 基于标签(label)的差异化配额(如环境标签 env=prod 与 env=dev 不同配额)。
  • 临时存储(ephemeral storage)的细粒度控制。
  • 跨命名空间的全局配额聚合。
  • 基于成本或团队预算的配额策略。

自定义配额策略通过准入控制器(Admission Controller)实现,最流行的方案包括:

方案 策略语言 典型场景
OPA / Gatekeeper Rego 标签约束、环境隔离、资源比例校验
Kyverno YAML 规则 默认值注入、突变、资源校验
自定义 Webhook 任意语言 与外部计费/预算系统集成

下图展示了自定义配额策略如何与原生配额机制协同工作:

自定义配额策略与原生配额协同流程图 自定义配额策略与原生配额协同流程 API Server 请求 原生 ResourceQuota + LimitRange 检查 自定义策略(OPA / Kyverno / Webhook) 允许 / 拒绝
关键设计原则:自定义策略不应替代原生配额,而应作为原生配额的补充。原生配额负责基础资源总量控制,自定义策略负责业务语义校验。例如:原生 ResourceQuota 限制命名空间总 CPU 为 10 核,自定义策略进一步要求生产环境 Pod 必须设置 requests.cpu >= 500m。

4.5 三种配额机制的对比与选型

维度 ResourceQuota LimitRange 自定义策略
作用粒度 命名空间级总量 Pod/容器级边界 任意粒度(标签、注解、外部数据)
原生支持 是 是 需额外部署(OPA/Kyverno/Webhook)
动态调整 手动更新 YAML 手动更新 YAML 支持热加载策略
适用场景 租户预算、资源公平分配 容器规格合规、默认值注入 复杂业务规则、跨集群策略、审计
学习成本 低 低 中高(Rego / Webhook 开发)
常见误区:不要试图用 ResourceQuota 做容器级约束,也不要用 LimitRange 做总量控制。两者职责分离,组合使用才能构建健壮的配额体系。自定义策略应作为“最后一道防线”,而非首选方案。

4.6 小结:构建分层配额模型的关键步骤

  1. 定义集群资源池:明确集群总容量与预留资源。
  2. 为每个租户/团队创建命名空间:并配置 ResourceQuota 限制总量。
  3. 配置 LimitRange:为每个命名空间设置容器规格默认值与边界。
  4. 识别业务特殊规则:如环境隔离、标签约束、成本分摊等。
  5. 选择自定义策略引擎:部署 OPA/Gatekeeper 或 Kyverno,编写策略规则。
  6. 测试与监控:使用 kubectl describe quota 和 kubectl describe limitrange 验证生效情况。