3. Kubernetes 资源配额(ResourceQuota)详解:定义、作用域、常用字段

ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的聚合资源消耗。它通过一组硬性限制(Hard Limits)来约束命名空间内所有 Pod、PVC 等对象的总资源使用量,防止单个团队或应用“抢占”集群的全部资源,是实现多租户资源隔离与成本控制的核心工具。

3.1 核心定义与工作原理

ResourceQuota 本质上是一个 API 对象(v1/ResourceQuota),由 kube-apiserver 的准入控制器 ResourceQuota 在对象创建/更新时强制执行。其工作流程如下:

  1. 定义配额:管理员在命名空间内创建 ResourceQuota 对象,声明 CPU、内存、存储、对象数量等上限。
  2. 请求校验:当用户在该命名空间创建 Pod、PVC、Service 等资源时,准入控制器计算当前命名空间已使用量 + 新请求量。
  3. 准入/拒绝:若总和超过配额上限,请求被拒绝并返回错误信息;否则允许创建,并更新配额状态。
  4. 状态监控:ResourceQuota 的 status 字段实时反映当前使用量,可通过 kubectl describe quota 查看。
关键原则:ResourceQuota 是“尽力而为”的硬限制,不预留资源。它只阻止超配创建,不驱逐已运行的 Pod。若配额被调低,已存在的超配 Pod 不会被终止,但新 Pod 无法创建。
ResourceQuota 准入控制流程 用户创建 Pod ResourceQuota 准入 计算当前使用量 超限? 拒绝请求 允许创建并更新状态 说明:准入控制器在对象创建/更新时拦截,不驱逐已运行 Pod;调低配额不影响已有资源。

3.2 作用域(Scope)与匹配规则

ResourceQuota 支持通过 scopes 字段限定配额生效的范围,实现更精细的资源控制。作用域决定了哪些对象会被配额统计。

作用域名称 匹配对象 典型场景
BestEffort QoS 等级为 BestEffort 的 Pod(未设置 requests/limits) 限制“尽力而为”类 Pod 的总数或 CPU 使用
NotBestEffort QoS 等级非 BestEffort 的 Pod(设置了 requests 或 limits) 保障有 QoS 保证的 Pod 的资源配额
Terminating 设置了 activeDeadlineSeconds 的 Pod 限制批处理作业(Job)的聚合资源
NotTerminating 未设置 activeDeadlineSeconds 的 Pod 限制长期运行服务(Deployment)的资源
PriorityClass 指定了特定 PriorityClass 的 Pod 按优先级隔离资源,高优任务独占配额
CrossNamespacePodAffinity 使用了跨命名空间 Pod 亲和性的 Pod 控制跨命名空间调度的影响范围
实践建议:在集群升级场景中,建议为 NotTerminating 和 BestEffort 分别设置配额,避免升级过程中临时 Pod 挤占关键服务资源。

3.3 常用字段与配置示例

ResourceQuota 的 spec.hard 字段支持三类资源维度:计算资源、存储资源和对象数量。以下是一个完整的生产级配置示例:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: team-alpha
spec:
  hard:
    # 计算资源(单位:m 表示毫核,Mi 表示兆字节)
    requests.cpu: "10"          # 所有 Pod 的 CPU 请求总和不超过 10 核
    requests.memory: "20Gi"     # 所有 Pod 的内存请求总和不超过 20 GiB
    limits.cpu: "20"            # 所有 Pod 的 CPU 限制总和不超过 20 核
    limits.memory: "40Gi"       # 所有 Pod 的内存限制总和不超过 40 GiB

    # 存储资源
    requests.storage: "500Gi"   # 所有 PVC 的存储请求总和不超过 500 GiB
    persistentvolumeclaims: "10" # PVC 对象总数不超过 10 个

    # 对象数量
    pods: "50"                  # 活跃 Pod 总数不超过 50 个
    services: "10"              # Service 对象总数不超过 10 个
    configmaps: "20"            # ConfigMap 对象总数不超过 20 个
    secrets: "20"               # Secret 对象总数不超过 20 个
    replicationcontrollers: "10" # RC 对象总数不超过 10 个
    services.nodeports: "5"     # NodePort 类型 Service 不超过 5 个
    services.loadbalancers: "2" # LoadBalancer 类型 Service 不超过 2 个

3.4 字段分类详解

常用字段按资源类型分为三大类,每类字段的命名规则和单位如下:

类别 字段前缀/名称 单位 说明
计算资源 requests.cpu 核(整数或小数,如 0.5) 所有 Pod 的 CPU 请求总和上限
requests.memory 字节(Ki/Mi/Gi) 所有 Pod 的内存请求总和上限
limits.cpu 核 所有 Pod 的 CPU 限制总和上限
limits.memory 字节 所有 Pod 的内存限制总和上限
存储资源 requests.storage 字节 所有 PVC 的存储请求总和上限
persistentvolumeclaims 整数 PVC 对象数量上限
<storage-class>.storageclass.storage.k8s.io/requests.storage 字节 按 StorageClass 细分的存储配额
对象数量 pods 整数 活跃 Pod 数量上限(含 Running、Pending 等)
services 整数 Service 对象数量上限
configmaps 整数 ConfigMap 对象数量上限
secrets 整数 Secret 对象数量上限
services.nodeports 整数 NodePort 类型 Service 数量上限
services.loadbalancers 整数 LoadBalancer 类型 Service 数量上限

3.5 多配额对象与作用域组合

一个命名空间可以创建多个 ResourceQuota 对象,每个对象可以指定不同的作用域。Kubernetes 会累加所有匹配的配额限制,取最严格的约束生效。

多 ResourceQuota 对象组合示例 命名空间:team-alpha quota-main 作用域:NotTerminating pods: 40 requests.cpu: 8 requests.memory: 16Gi quota-batch 作用域:Terminating pods: 20 requests.cpu: 4 requests.memory: 8Gi quota-storage 作用域:全部 requests.storage: 300Gi pvc: 10 说明:长期服务 Pod 受 quota-main 限制,批处理 Job 受 quota-batch 限制,存储配额由 quota-storage 统一管理。

3.6 常见陷阱与避坑指南

  • 未设置 requests/limits 导致配额失效:若 Pod 未设置 requests 字段,则 requests.cpu 和 requests.memory 配额不会统计该 Pod。建议配合 LimitRange 设置默认值。
  • 配额与 LimitRange 冲突:LimitRange 设置单个 Pod 的默认 requests/limits,ResourceQuota 设置总和上限。两者需协同规划,避免 LimitRange 默认值过大导致配额迅速耗尽。
  • 存储配额不限制临时存储:requests.storage 仅统计 PVC,不统计 emptyDir 或 hostPath 等临时存储。若需限制临时存储,需使用 ephemeral-storage 字段。
  • 对象配额不包含已删除对象:ResourceQuota 仅统计当前活跃对象。已删除的 Pod 或 PVC 不会占用配额,但处于 Terminating 状态的 Pod 仍会计数。
  • 跨命名空间配额无法直接实现:ResourceQuota 是命名空间级别的,无法跨命名空间聚合。若需全局配额,需借助 Kyverno 等策略引擎或外部调度器。
升级场景特别提醒:在集群升级过程中,若同时运行旧版本和新版本 Pod(例如通过滚动更新),ResourceQuota 的 pods 配额可能成为瓶颈。建议在升级前临时调高 pods 配额,或使用 Kyverno 策略自动检测并调整。