2. Kubernetes Resource Quota 基础:ResourceQuota 对象定义、作用域、与 LimitRange 的区别
在云原生成本分摊模型中,Resource Quota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的资源消耗总量。它是实现多租户资源隔离、防止资源争抢、以及进行成本核算与分摊的基石。本章将深入解析 ResourceQuota 的对象定义、作用域,并对比其与 LimitRange 的核心差异。
2.1 ResourceQuota 对象定义
ResourceQuota 是一个 Kubernetes API 对象,通过 YAML 清单定义。它作用于一个特定的 Namespace,对该 Namespace 内所有 Pod 的聚合资源消耗设置硬性上限。
以下是一个典型的 ResourceQuota 定义示例,它限制了计算资源(CPU/内存)和存储资源(PVC 请求),以及核心对象数量(Pod、Service、ConfigMap 等):
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
persistentvolumeclaims: "10"
requests.storage: "50Gi"
pods: "20"
services: "10"
configmaps: "15"
secrets: "15"
- spec.hard:定义资源配额的上限值,是一个键值对映射。
- requests.cpu / requests.memory:所有 Pod 的
requests总和上限。 - limits.cpu / limits.memory:所有 Pod 的
limits总和上限。 - pods / services / configmaps:限制该 Namespace 内可创建的对象数量。
2.2 ResourceQuota 作用域(Scope)
ResourceQuota 支持通过 spec.scopeSelector 或 spec.scopes 字段,将配额限制应用于特定类别的 Pod。作用域允许管理员对资源消耗进行更精细的控制,例如区分“尽力而为”和“有 QoS 保障”的工作负载。
常见的作用域包括:
| 作用域名称 | 匹配条件 | 典型用途 |
|---|---|---|
| BestEffort | Pod 未设置 requests 和 limits | 限制低优先级、可被驱逐的批处理任务 |
| NotBestEffort | Pod 设置了 requests 或 limits | 保障生产级服务的资源上限 |
| Terminating | Pod 设置了 activeDeadlineSeconds |
限制有运行时间上限的 Job 或 CronJob |
| NotTerminating | Pod 未设置 activeDeadlineSeconds |
限制常驻服务(Deployment、StatefulSet) |
| PriorityClass | 通过 scopeSelector 匹配特定 PriorityClass |
按优先级等级分配资源池 |
以下示例展示了如何创建一个仅对 NotBestEffort Pod 生效的 ResourceQuota:
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-not-besteffort
namespace: team-alpha
spec:
hard:
requests.cpu: "6"
requests.memory: "12Gi"
scopes:
- NotBestEffort
scopes 字段时,ResourceQuota 仅统计匹配该作用域的 Pod 资源。如果 Namespace 内同时存在 BestEffort 和 NotBestEffort Pod,你需要创建两个独立的 ResourceQuota 对象来分别管理它们。
2.3 ResourceQuota 与 LimitRange 的区别
ResourceQuota 和 LimitRange 都是 Kubernetes 中用于资源治理的准入控制器,但它们的职责和粒度完全不同。理解两者的区别是构建成本分摊模型的前提。
以下 SVG 图直观展示了两者的核心差异:
下表从多个维度详细对比了 ResourceQuota 与 LimitRange:
| 对比维度 | ResourceQuota | LimitRange |
|---|---|---|
| 作用粒度 | Namespace 级别(聚合统计) | Pod / 容器级别(单个实例) |
| 核心功能 | 设置资源消耗的 硬上限 | 设置资源请求/限制的 最小/最大范围 及默认值 |
| 触发时机 | Pod 创建时检查 Namespace 总量是否超限 | Pod 创建时校验或注入单个容器的资源值 |
| 典型场景 | 多租户成本分摊、资源容量规划 | 防止单个 Pod 资源过大或过小、为 Legacy 应用注入默认值 |
| 是否影响已有 Pod | 否(仅限制新创建的对象) | 否(仅对新创建的 Pod 生效) |
| 与成本分摊的关系 | 直接提供 Namespace 资源消耗上限,用于计算最大可分摊成本 | 间接影响成本分摊的准确性(通过约束单个 Pod 的资源规格) |
2.4 实战中的协同使用建议
在云原生成本分摊模型中,ResourceQuota 和 LimitRange 通常配合使用,形成“双层资源治理”策略:
- 第一层:LimitRange —— 为每个 Namespace 设置默认的 requests 和 limits,确保所有 Pod 都有明确的资源声明,避免“空跑”Pod 导致成本黑洞。
- 第二层:ResourceQuota —— 设置 Namespace 的资源总量上限,防止某个团队或项目过度消耗集群资源,保障成本分摊的公平性。
limits.cpu 和 limits.memory 将无法生效,导致配额形同虚设。LimitRange 可以自动为未设置资源的 Pod 注入默认值,确保 ResourceQuota 的统计完整性。
以下 SVG 图展示了 ResourceQuota 与 LimitRange 在 Pod 创建流程中的协同工作顺序: