4. 资源配额概念:Kubernetes ResourceQuota 对象、CPU/内存/存储配额、配额作用域与范围

在 Kubernetes 多租户或团队共享集群场景中,ResourceQuota 是防止资源争抢、保障服务质量的核心策略对象。它通过声明式配额约束,限制命名空间(Namespace)级别的资源使用总量,确保单个应用或团队不会耗尽集群资源。本章将深入剖析 ResourceQuota 的构成、配额类型、作用域及范围,为后续 Kustomize 缓存命中性能测试奠定资源约束基础。

4.1 ResourceQuota 对象结构

ResourceQuota 是一个 Kubernetes API 原生对象,定义在 v1 核心 API 组中。其核心字段位于 spec.hard,用于声明资源上限。以下是一个典型的 ResourceQuota YAML 示例:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    persistentvolumeclaims: "10"
    requests.storage: "100Gi"
    count/deployments.apps: "5"
    count/services: "10"

该对象定义了命名空间 team-a 的资源硬上限:CPU 请求总量不超过 4 核,内存请求不超过 8Gi,存储声明不超过 10 个 PVC,总存储量不超过 100Gi,同时限制了 Deployment 和 Service 的数量。

4.2 配额类型:CPU、内存、存储

ResourceQuota 支持三类核心资源配额,每类又细分为 requests(预留)和 limits(上限)两个维度:

资源类别 配额键(Key) 说明 典型单位
CPU requests.cpu 所有 Pod 的 CPU 请求总和上限 核(core),如 4、0.5
limits.cpu 所有 Pod 的 CPU 限制总和上限 核(core),如 8、2
内存 requests.memory 所有 Pod 的内存请求总和上限 字节(Gi、Mi),如 8Gi、512Mi
limits.memory 所有 Pod 的内存限制总和上限 字节(Gi、Mi),如 16Gi、1Gi
存储 requests.storage 所有 PVC 的存储容量请求总和上限 字节(Gi、Ti),如 100Gi
persistentvolumeclaims PVC 对象数量上限 整数,如 10
最佳实践: 在性能测试环境中,建议同时设置 requests 和 limits 配额,避免 Pod 因突发资源使用导致节点过载。对于 Kustomize 缓存测试,应重点关注 requests.memory 和 limits.memory,因为缓存命中率与可用内存配额直接相关。

4.3 配额作用域与范围

ResourceQuota 的作用域(Scope)决定了配额生效的 Pod 范围。通过 spec.scopes 字段,可以精细控制配额适用的 Pod 类别。Kubernetes 支持以下标准作用域:

  • Terminating:仅适用于 spec.activeDeadlineSeconds >= 0 的 Pod(通常为 Job 或批处理任务)。
  • NotTerminating:仅适用于 spec.activeDeadlineSeconds 为 nil 的 Pod(长期运行服务)。
  • BestEffort:仅适用于 QoS 类别为 BestEffort 的 Pod(未设置 requests 和 limits)。
  • NotBestEffort:仅适用于 QoS 类别为 Burstable 或 Guaranteed 的 Pod。
  • PriorityClass:通过 scopeSelector 匹配特定 PriorityClass 的 Pod。

作用域组合使用可实现更细粒度的配额隔离。例如,为批处理任务和长期服务分别设置不同的 CPU 配额:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: batch-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "2"
    requests.memory: "4Gi"
  scopes:
    - Terminating
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: service-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
  scopes:
    - NotTerminating

上述配置确保批处理任务最多使用 2 核 CPU,而长期服务最多使用 4 核 CPU,两者互不干扰。

4.4 配额范围:命名空间级别与集群级别

ResourceQuota 默认作用于单个命名空间,但 Kubernetes 也提供了 ClusterResourceQuota(由 OpenShift 扩展,社区版可通过 kubectl 配合 ResourceQuota 模拟)实现跨命名空间的配额聚合。以下对比两种范围:

范围类型 对象名称 作用范围 适用场景
命名空间级别 ResourceQuota 单个 Namespace 团队隔离、环境隔离(dev/staging/prod)
集群级别 ClusterResourceQuota(OpenShift) 多个 Namespace 聚合 租户级配额、跨项目资源池管理
注意: 标准 Kubernetes 社区版不内置 ClusterResourceQuota。如需跨命名空间配额,可通过 kubectl 配合 ResourceQuota 在每个命名空间独立配置,或使用第三方策略引擎(如 OPA/Gatekeeper)实现。在 Kustomize 测试中,我们默认使用命名空间级别的 ResourceQuota。

4.5 配额约束下的资源调度流程

以下 SVG 图展示了 ResourceQuota 在 Pod 创建时的校验与调度流程:

ResourceQuota 校验与调度流程 ResourceQuota 校验与调度流程 用户提交 Pod API Server 准入控制 ResourceQuota 校验 是否超限? 拒绝创建 允许创建 Scheduler 调度 说明: ResourceQuota 在准入控制阶段拦截 Pod 创建请求,实时计算命名空间内已使用资源总量。 若加上新 Pod 的请求后超过 hard 上限,则拒绝创建并返回错误信息。

4.6 配额约束对 Kustomize 缓存的影响

在资源配额约束下,Kustomize 缓存命中性能测试需要特别关注以下三个关键点:

  • 内存配额限制缓存容量:Kustomize 缓存通常存储在内存中(如 kustomize build 的中间产物)。若命名空间 limits.memory 过低,缓存可能被频繁驱逐,导致命中率下降。
  • CPU 配额影响构建并发:Kustomize 构建过程涉及 YAML 解析、资源合并等 CPU 密集型操作。CPU 配额不足会延长构建时间,间接影响缓存命中窗口。
  • 存储配额限制持久化缓存:若使用持久卷(PV)作为缓存后端,requests.storage 和 persistentvolumeclaims 配额将直接限制缓存数据量。
测试建议: 在后续性能测试中,我们将设置三组不同的 ResourceQuota 配置(低配额/中配额/无配额),对比 Kustomize 缓存命中率与构建延迟的变化。具体配额值将在第 5 章测试设计中给出。

4.7 配额监控与调试

运维人员可通过以下命令实时查看命名空间的资源使用情况:

# 查看命名空间 team-a 的 ResourceQuota 状态
kubectl get resourcequota compute-quota -n team-a -o yaml

# 查看命名空间资源使用量(配额视角)
kubectl describe resourcequota compute-quota -n team-a

# 查看命名空间所有资源使用汇总
kubectl get resourcequota -n team-a

kubectl describe 输出会显示 Used 和 Hard 字段,直观展示当前使用量与配额上限的对比。例如:

Name:            compute-quota
Namespace:       team-a
Resource         Used  Hard
--------         ----  ----
requests.cpu     2.5   4
requests.memory  5Gi   8Gi
limits.cpu       4     8
limits.memory    10Gi  16Gi
persistentvolumeclaims 3 10

当 Used 接近 Hard 时,新 Pod 创建将失败,错误信息类似:failed quota: compute-quota: must specify limits.cpu 或 exceeded quota: compute-quota: requested 2Gi memory, already used 7Gi, limited to 8Gi。

4.8 本章小结