2、资源配额(ResourceQuota)基础:概念、作用域与资源类型
ResourceQuota 是 Kubernetes 集群管理员用来限制命名空间(Namespace)级别资源消耗的核心策略对象。它通过声明式配置,为每个命名空间设定资源上限,防止单个租户或应用团队过度占用集群资源,保障多租户环境下的资源公平性与集群稳定性。
2.1 ResourceQuota 核心概念
ResourceQuota 本质上是一个准入控制机制。当用户尝试在命名空间中创建或更新 Pod、Service、PersistentVolumeClaim 等对象时,Kubernetes API Server 会调用配额插件,检查当前命名空间已消耗的资源量加上新请求的资源量是否超过配额上限。如果超出,请求将被拒绝并返回错误信息。
- 命名空间级作用域:每个 ResourceQuota 对象绑定到一个特定的命名空间,无法跨命名空间生效。
- 累加式计数:配额跟踪的是命名空间内所有对象的资源请求(requests)和限制(limits)的累加值,而非瞬时使用量。
- 硬性限制:默认情况下,ResourceQuota 是硬配额(Hard),超出即拒绝。支持通过
spec.scopeSelector实现软配额(BestEffort 或 NotBestEffort)。 - 动态更新:配额可以在运行时修改,修改后立即生效,但不会影响已存在的对象。
2.2 作用域(Scope)
ResourceQuota 支持通过作用域(Scope)对配额的应用范围进行精细化控制。作用域决定了配额规则适用于哪些类型的 Pod 或对象。Kubernetes 定义了以下标准作用域:
| 作用域名称 | 描述 | 适用场景 |
|---|---|---|
BestEffort |
仅匹配 QoS 类别为 BestEffort 的 Pod(未设置 requests 和 limits) | 限制低优先级、突发性任务的资源占用 |
NotBestEffort |
匹配 QoS 类别为 Burstable 或 Guaranteed 的 Pod | 保障有资源预留的生产级工作负载 |
Terminating |
匹配设置了 activeDeadlineSeconds 的 Pod |
限制批处理任务、CI/CD 作业 |
NotTerminating |
匹配未设置 activeDeadlineSeconds 的 Pod |
限制长期运行的服务 |
PriorityClass |
通过 scopeSelector 匹配指定 PriorityClass 的 Pod |
按优先级层级分配资源配额 |
CrossNamespacePodAffinity |
匹配使用了跨命名空间 Pod 亲和性的 Pod | 控制跨命名空间调度的影响范围 |
NotBestEffort 作用域限制生产级 Pod 的资源,另一个使用 BestEffort 作用域限制临时任务的资源。这样可以避免 BestEffort Pod 抢占 NotBestEffort Pod 的配额。
2.3 资源类型详解
ResourceQuota 支持对四类资源进行配额限制:计算资源(CPU/内存)、存储资源、对象数量以及扩展资源。每种资源类型都有对应的配额键(Key)和计数方式。
2.3.1 计算资源(CPU / 内存)
计算资源配额通过 requests 和 limits 两个维度进行控制。Kubernetes 会分别累加命名空间内所有 Pod 容器的 requests 和 limits 值。
| 配额键 | 描述 | 单位 | 示例值 |
|---|---|---|---|
requests.cpu |
所有 Pod 的 CPU 请求总和上限 | 核心数(m 或整数) | 10、5000m |
requests.memory |
所有 Pod 的内存请求总和上限 | 字节(Ei/Pi/Ti/Gi/Mi/Ki) | 20Gi、512Mi |
limits.cpu |
所有 Pod 的 CPU 限制总和上限 | 核心数(m 或整数) | 20、10000m |
limits.memory |
所有 Pod 的内存限制总和上限 | 字节(Ei/Pi/Ti/Gi/Mi/Ki) | 40Gi、1Ti |
2.3.2 存储资源
存储资源配额包括持久卷声明(PVC)的存储请求总量以及特定存储类的存储上限。
| 配额键 | 描述 | 单位 | 示例值 |
|---|---|---|---|
requests.storage |
所有 PVC 的存储请求总和上限 | 字节 | 100Gi |
persistentvolumeclaims |
PVC 对象数量上限 | 整数 | 50 |
requests.storage/<storage-class-name> |
指定 StorageClass 的 PVC 存储请求总和上限 | 字节 | 50Gi |
persistentvolumeclaims/<storage-class-name> |
指定 StorageClass 的 PVC 对象数量上限 | 整数 | 20 |
2.3.3 对象数量
对象数量配额限制命名空间内可创建的 Kubernetes 资源对象个数。这有助于防止资源对象泛滥导致 etcd 压力过大或控制器性能下降。
| 配额键 | 描述 | 示例值 |
|---|---|---|
pods |
Pod 对象数量上限 | 100 |
services |
Service 对象数量上限 | 50 |
services.loadbalancers |
LoadBalancer 类型 Service 数量上限 | 10 |
services.nodeports |
NodePort 类型 Service 数量上限 | 20 |
configmaps |
ConfigMap 对象数量上限 | 200 |
secrets |
Secret 对象数量上限 | 200 |
replicationcontrollers |
ReplicationController 对象数量上限 | 50 |
resourcequotas |
ResourceQuota 对象数量上限 | 10 |
2.3.4 扩展资源
扩展资源(Extended Resources)是用户自定义的非 Kubernetes 原生资源,例如 GPU、FPGA、NVMe 磁盘等。ResourceQuota 同样支持对扩展资源进行配额限制。
apiVersion: v1
kind: ResourceQuota
metadata:
name: gpu-quota
namespace: ai-team
spec:
hard:
requests.nvidia.com/gpu: 8
limits.nvidia.com/gpu: 16
pods: 50
requests.memory: 100Gi
limits.memory: 200Gi
nvidia.com/gpu,则配额键必须写 requests.nvidia.com/gpu,不能简写为 gpu。
2.4 完整 ResourceQuota 示例
以下是一个生产环境推荐的 ResourceQuota 配置,同时覆盖计算资源、存储资源和对象数量:
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
# 计算资源
requests.cpu: 20
requests.memory: 80Gi
limits.cpu: 40
limits.memory: 160Gi
# 存储资源
requests.storage: 500Gi
persistentvolumeclaims: 30
requests.storage/fast-ssd: 200Gi
persistentvolumeclaims/fast-ssd: 10
# 对象数量
pods: 100
services: 20
configmaps: 100
secrets: 100
# 扩展资源
requests.nvidia.com/gpu: 4
2.5 配额与 LimitRange 的协同关系
ResourceQuota 和 LimitRange 是 Kubernetes 资源治理的两大支柱,但职责不同:
| 特性 | ResourceQuota | LimitRange |
|---|---|---|
| 作用范围 | 命名空间级别(所有 Pod 累加) | 单个 Pod / 容器级别 |
| 主要功能 | 限制资源总量上限 | 设置单个容器的资源默认值、最小/最大值 |
| 检查时机 | 创建/更新对象时(准入控制) | 创建/更新 Pod 时(准入控制) |
| 典型场景 | 多租户资源隔离、成本控制 | 防止单个容器资源过大或过小 |
| 是否必须配合 | 建议与 LimitRange 一起使用 | 建议与 ResourceQuota 一起使用 |
2.6 配额监控与调试
管理员可以通过以下命令查看命名空间的当前配额使用情况:
# 查看命名空间的配额定义
kubectl get resourcequota -n production
# 查看配额使用详情(Used 列显示当前消耗)
kubectl describe resourcequota production-quota -n production
# 输出示例:
# Name: production-quota
# Namespace: production
# Resource Used Hard
# -------- --- ---
# requests.cpu 12 20
# requests.memory 48Gi 80Gi
# limits.cpu 24 40
# limits.memory 96Gi 160Gi
# pods 45 100
# persistentvolumeclaims 12 30
- 当 Pod 创建失败并返回
403 Forbidden时,使用kubectl describe quota检查是否达到配额上限。 - 使用
kubectl get events -n <namespace>查看被配额拒绝的详细事件。 - 对于存储配额,注意 PVC 的
requests.storage是累加所有 PVC 的spec.resources.requests.storage值,而非实际使用量。 - 如果配额更新后 Pod 仍然创建失败,检查是否同时存在多个 ResourceQuota 对象,它们的限制会取并集(最严格的限制生效)。