3、资源配额(ResourceQuota)基础:Kubernetes ResourceQuota 对象定义、作用域、常用字段
在多租户或团队共享集群的场景中,资源配额(ResourceQuota)是防止“资源挤兑”的第一道防线。它通过限制命名空间(Namespace)级别的聚合资源用量,确保单个团队不会耗尽集群的全部 CPU 或内存,从而保障其他工作负载的稳定性。本章将深入解析 ResourceQuota 的对象定义、作用域机制以及核心字段。
3.1 ResourceQuota 对象定义与核心概念
ResourceQuota 是一个 Kubernetes 原生 API 对象,作用于特定的命名空间。它定义了一组硬性限制(Hard Limits),用于约束该命名空间内所有 Pod 和容器的资源请求(Requests)与限制(Limits)的总和。
以下是一个标准的 ResourceQuota YAML 定义示例:
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"
requests.nvidia.com/gpu: "1"
persistentvolumeclaims: "10"
pods: "20"
configmaps: "10"
services: "5"
3.2 资源配额作用域(Scope)
ResourceQuota 支持通过 scopes 字段对资源进行更精细的划分。作用域决定了配额是应用于所有 Pod,还是仅应用于特定 QoS 类别的 Pod。这是实现资源分层和优先级保障的关键机制。
| 作用域(Scope) | 匹配条件 | 典型用途 |
|---|---|---|
BestEffort |
Pod 未设置任何 requests 或 limits | 限制低优先级、可被驱逐的“尽力而为”型任务 |
NotBestEffort |
Pod 设置了至少一个 requests 或 limits | 保障有资源声明的 Pod 的配额 |
Terminating |
Pod 设置了 activeDeadlineSeconds |
限制批处理或定时任务的总资源 |
NotTerminating |
Pod 未设置 activeDeadlineSeconds |
限制长期运行的服务(Deployment/StatefulSet) |
PriorityClass |
Pod 关联了指定的 PriorityClass 名称 | 按优先级等级分配不同的资源池 |
NotTerminating(长期服务),另一个用于 Terminating(批处理任务),以实现资源池的物理隔离。
3.3 常用字段详解
ResourceQuota 的 spec.hard 字段支持三类资源:计算资源、存储资源和对象计数资源。以下是 GitOps 交付中最常用的字段清单:
3.3.1 计算资源(Compute Resources)
- requests.cpu:所有非 BestEffort Pod 的 CPU 请求总和上限(单位:核心数或 millicores)。
- requests.memory:所有非 BestEffort Pod 的内存请求总和上限(单位:字节、Ki、Mi、Gi)。
- limits.cpu:所有非 BestEffort Pod 的 CPU 限制总和上限。
- limits.memory:所有非 BestEffort Pod 的内存限制总和上限。
- requests.nvidia.com/gpu:GPU 资源请求总和上限(适用于 AI/ML 工作负载)。
3.3.2 存储资源(Storage Resources)
- requests.storage:所有 PVC 的存储容量请求总和上限。
- persistentvolumeclaims:命名空间内允许的 PVC 总数上限。
- storage-class-name.storageclass.storage.k8s.io/requests.storage:针对特定 StorageClass 的存储容量上限。
3.3.3 对象计数资源(Object Count Quotas)
- pods:命名空间内允许的 Pod 总数上限。
- services:Service 对象总数上限。
- configmaps:ConfigMap 对象总数上限。
- secrets:Secret 对象总数上限。
- replicationcontrollers:ReplicationController 对象总数上限。
3.4 ResourceQuota 作用域与资源分层 SVG 图
下图展示了不同作用域如何将命名空间内的 Pod 划分为独立的资源池,每个池子受不同的 ResourceQuota 约束:
3.5 配额冲突与准入控制
当 ResourceQuota 被创建后,Kubernetes 的准入控制器(ResourceQuota Admission Controller)会在 Pod 创建或更新时进行校验。如果命名空间内的资源总和已超过配额上限,新的 Pod 创建请求将被拒绝,并返回 403 Forbidden 错误。
requests.cpu 或 limits.memory,这些 Pod 将无法创建。因为 ResourceQuota 要求所有非 BestEffort Pod 必须显式声明资源。解决方案是配合 LimitRange 为未设置资源的 Pod 注入默认值。
3.6 资源配额与 LimitRange 的协同关系
ResourceQuota 和 LimitRange 是 Kubernetes 资源管理的“双保险”。下表对比了二者的核心差异:
| 特性 | ResourceQuota | LimitRange |
|---|---|---|
| 作用范围 | 命名空间级别(聚合约束) | Pod/容器级别(单个约束) |
| 主要功能 | 限制资源总量上限 | 设置单个 Pod 的资源最小/最大值及默认值 |
| 触发时机 | Pod 创建时校验总量 | Pod 创建时注入默认值或校验范围 |
| 典型场景 | 防止团队资源滥用 | 确保每个 Pod 有合理的资源声明 |
| 依赖关系 | 建议与 LimitRange 配合使用 | 可为 ResourceQuota 提供默认值支撑 |
3.7 在 GitOps 中声明 ResourceQuota
在 GitOps 工作流中,ResourceQuota 应作为应用交付的一部分,与 Namespace 和 LimitRange 一同存储在 Git 仓库中。推荐使用 Kustomize 的 resources 字段或 Helm 的模板机制进行声明式管理。
以下是一个 Kustomize 示例,展示如何将 ResourceQuota 集成到应用基线中:
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: team-alpha
resources:
- namespace.yaml
- resourcequota.yaml
- limitrange.yaml
- deployment.yaml
- service.yaml
base/ 目录下,作为“命名空间基线”的一部分。不同环境(dev/staging/prod)可以通过 overlay 调整配额数值,而无需修改底层资源定义。