2. Kubernetes 资源配额基础:ResourceQuota 对象定义、作用域、核心字段
ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的资源消耗总量。当 Operator 控制循环与资源配额冲突时,根本原因往往在于 Operator 创建的 Pod/Job 超出了配额限制,导致调度失败或驱逐。理解 ResourceQuota 的对象定义、作用域和核心字段,是定位此类瓶颈的前提。
2.1 ResourceQuota 对象定义
ResourceQuota 是一个 Kubernetes API 对象,通过 YAML 或 JSON 声明式配置。以下是一个典型的 ResourceQuota 定义示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
persistentvolumeclaims: "10"
pods: "50"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high-priority
该示例定义了一个名为 compute-quota 的 ResourceQuota,作用于 production 命名空间。它限制了 CPU 请求总量不超过 4 核、内存请求不超过 8Gi,同时限制了 Pod 数量不超过 50 个。通过 scopeSelector,该配额仅对 high-priority 优先级类的 Pod 生效。
2.2 作用域(Scope)与 scopeSelector
ResourceQuota 的作用域决定了配额约束的生效范围。Kubernetes 支持以下标准作用域:
| 作用域名称 | 描述 | 典型使用场景 |
|---|---|---|
BestEffort |
仅对 QoS 为 BestEffort 的 Pod 生效 | 限制低优先级、无资源限制的批处理任务 |
NotBestEffort |
对 QoS 非 BestEffort 的 Pod 生效 | 保障生产级服务的资源配额 |
Terminating |
对 activeDeadlineSeconds 已设置的 Pod 生效 |
限制有超时时间的 Job 或批处理任务 |
NotTerminating |
对 activeDeadlineSeconds 未设置的 Pod 生效 |
限制长期运行的服务 |
PriorityClass |
通过 scopeSelector 匹配指定优先级类 |
为不同优先级的工作负载分配独立配额 |
scopeSelector 字段提供了更精细的匹配能力,支持 In、NotIn、Exists、DoesNotExist 四种操作符。当 Operator 创建 Pod 时,如果 Pod 的标签或优先级类与 scopeSelector 不匹配,该 ResourceQuota 将不会对其生效。
priorityClassName 或 QoS 类,可能导致配额意外生效或失效,从而引发资源冲突。建议在 Operator 的 Pod 模板中显式声明优先级类。
2.3 核心字段:hard
hard 字段是 ResourceQuota 的核心,定义了命名空间内资源消耗的硬性上限。它支持两类资源:
- 计算资源:
requests.cpu、requests.memory、limits.cpu、limits.memory、requests.ephemeral-storage、limits.ephemeral-storage - 对象数量:
pods、services、persistentvolumeclaims、configmaps、secrets、replicationcontrollers、resourcequotas、services.nodeports、services.loadbalancers
当命名空间内资源使用量达到 hard 上限时,Kubernetes 准入控制器会拒绝后续的资源创建请求,并返回 403 Forbidden 错误。Operator 控制循环在创建 Pod 或 PVC 时,必须处理此类错误并实现重试或降级逻辑。
requests 和 limits,却忽略了 pods 和 persistentvolumeclaims 等对象数量配额。当 Operator 创建大量短生命周期 Pod 时,即使计算资源充足,也可能因 Pod 数量配额耗尽而失败。
2.4 ResourceQuota 与 Operator 控制循环的交互关系
下图展示了 ResourceQuota 在 Operator 控制循环中的位置及其对资源创建的影响:
2.5 多个 ResourceQuota 的叠加规则
一个命名空间可以定义多个 ResourceQuota 对象。当多个配额同时生效时,Kubernetes 遵循以下叠加规则:
- 取并集约束: 所有匹配的 ResourceQuota 的
hard字段共同构成约束集合。例如,Quota A 限制pods: 20,Quota B 限制pods: 30,则实际 Pod 上限为 20(取最小值)。 - 作用域隔离: 不同作用域的 ResourceQuota 互不干扰。例如,
BestEffort配额与NotBestEffort配额独立计算。 - 优先级类隔离: 通过
scopeSelector匹配不同优先级类的配额,可以实现多级资源池。
2.6 核心字段速查表
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
hard |
map[string]Quantity | 是 | 定义资源硬性上限,键为资源名称,值为 Kubernetes Quantity 格式 |
scopes |
[]ResourceQuotaScope | 否 | 指定配额作用域,如 BestEffort、NotTerminating 等 |
scopeSelector |
ScopeSelector | 否 | 通过表达式匹配作用域,支持 PriorityClass 等高级匹配 |