4. 资源配额(ResourceQuota)基础
ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的资源消耗总量。它防止单个团队或项目过度占用集群资源,是集群管理员实现多租户资源隔离的核心工具。在 Kyverno 策略与集群升级场景中,ResourceQuota 的准确配置直接决定了升级过程中 Pod 能否正常调度、资源是否被预留。
4.1 ResourceQuota 核心概念
ResourceQuota 以命名空间为作用域,通过声明式 YAML 定义该命名空间内所有 Pod 可使用的资源上限。当用户尝试创建或更新 Pod 时,Kubernetes 准入控制器会检查当前命名空间的已使用资源加上新 Pod 的请求资源是否超过配额上限,若超过则拒绝操作。
4.2 作用域(Scope)
ResourceQuota 支持按作用域(Scope)细分配额限制,使管理员能针对不同状态的 Pod 设置差异化配额。下表列出 Kubernetes 内置的 ResourceQuota 作用域:
| 作用域名称 | 匹配条件 | 典型用途 |
|---|---|---|
BestEffort |
Pod 未设置任何资源请求(requests)和限制(limits) | 限制“尽力而为”类 Pod 的总数或 CPU/内存总量 |
NotBestEffort |
Pod 设置了至少一个资源请求或限制 | 对正常业务 Pod 进行资源总量控制 |
Terminating |
Pod 设置了 activeDeadlineSeconds |
限制批处理或定时任务类 Pod 的资源占用 |
NotTerminating |
Pod 未设置 activeDeadlineSeconds |
限制常驻服务类 Pod 的资源占用 |
PriorityClass |
Pod 关联了指定的 PriorityClass 名称 | 按优先级等级隔离资源配额(需指定 scopeSelector) |
NotBestEffort 和 NotTerminating 作用域组合来限制常规工作负载,避免因升级过程中临时创建的 BestEffort Pod 挤占关键业务资源。
4.3 配额类型
ResourceQuota 支持三类资源配额:计算资源、存储资源 和 对象数量。每类配额在 YAML 中通过 spec.hard 字段下的不同键名来定义。
4.3.1 计算资源配额
计算资源配额控制命名空间内所有 Pod 的 CPU 和内存总量。支持以下键名:
requests.cpu— 所有 Pod 的 CPU 请求总和上限(单位:核心数或 millicores)requests.memory— 所有 Pod 的内存请求总和上限(单位:字节、Ki、Mi、Gi)limits.cpu— 所有 Pod 的 CPU 限制总和上限limits.memory— 所有 Pod 的内存限制总和上限
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-alpha
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
4.3.2 存储资源配额
存储资源配额控制命名空间内所有 PersistentVolumeClaim(PVC)的存储总量。支持以下键名:
requests.storage— 所有 PVC 的存储请求总和上限persistentvolumeclaims— PVC 对象数量上限<storage-class-name>.storageclass.storage.k8s.io/requests.storage— 按 StorageClass 细分的存储请求上限<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims— 按 StorageClass 细分的 PVC 数量上限
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
namespace: team-alpha
spec:
hard:
requests.storage: "500Gi"
persistentvolumeclaims: "10"
ssd.storageclass.storage.k8s.io/requests.storage: "200Gi"
ssd.storageclass.storage.k8s.io/persistentvolumeclaims: "5"
4.3.3 对象数量配额
对象数量配额控制命名空间内 Kubernetes 核心对象的数量上限。常见对象类型包括:
| 配额键名 | 控制对象 | 典型上限 |
|---|---|---|
pods |
Pod 总数(含所有状态) | 100 |
services |
Service 总数 | 50 |
configmaps |
ConfigMap 总数 | 100 |
secrets |
Secret 总数 | 100 |
replicationcontrollers |
ReplicationController 总数 | 20 |
resourcequotas |
ResourceQuota 对象总数 | 1(通常每个命名空间只定义一个) |
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
namespace: team-alpha
spec:
hard:
pods: "50"
services: "10"
configmaps: "20"
secrets: "20"
4.4 ResourceQuota 与 Pod 资源请求的关系
当命名空间设置了 ResourceQuota 后,Kubernetes 要求该命名空间内的每个 Pod 必须显式设置资源请求(requests)。如果 Pod 未设置 requests,则创建请求会被拒绝。这一行为确保了配额计算的可预测性。
4.5 ResourceQuota 架构关系图
下图展示了 ResourceQuota 在 Kubernetes 控制平面中的位置及其与 API Server、准入控制器、命名空间和 Pod 的关系:
4.6 多配额类型组合示例
实际生产环境中,通常将计算、存储和对象配额合并到一个 ResourceQuota 对象中,以便统一管理。以下是一个综合示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
# 计算资源
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "16"
limits.memory: "32Gi"
# 存储资源
requests.storage: "200Gi"
persistentvolumeclaims: "20"
# 对象数量
pods: "40"
services: "10"
configmaps: "30"
secrets: "30"
replicationcontrollers: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high-priority
4.7 配额使用情况查看
管理员可以通过 kubectl describe resourcequota 命令查看当前命名空间的配额使用情况,输出会显示已使用量和上限:
kubectl describe resourcequota team-alpha-quota -n team-alpha
Name: team-alpha-quota
Namespace: team-alpha
Resource Used Hard
-------- --- ---
requests.cpu 3.5 8
requests.memory 7Gi 16Gi
limits.cpu 6.2 16
limits.memory 14Gi 32Gi
pods 18 40
services 5 10
configmaps 12 30
secrets 8 30
该输出是集群升级前资源校准的重要依据。如果 Used 接近 Hard,则升级过程中新 Pod 可能无法调度,需要提前调整配额或清理资源。
4.8 配额校准与升级准备
在集群升级场景中,ResourceQuota 校准应遵循以下步骤:
- 收集现状:使用
kubectl get resourcequota --all-namespaces列出所有命名空间的配额配置。 - 分析使用率:对每个命名空间,计算
Used / Hard比率,标记使用率超过 80% 的配额项。 - 评估升级影响:升级过程中,Deployment 滚动更新会创建临时 Pod,导致资源使用量短暂上升。确保配额有 20% 以上的余量。
- 调整配额:对余量不足的命名空间,临时提高配额上限,或要求业务方清理闲置资源。
- 验证:使用 Kyverno 策略模拟升级场景,验证配额调整后的 Pod 创建是否正常。
kubectl top pod 检查实际资源使用量,确保配额设置合理。