2. 资源配额模型基础:Kubernetes ResourceQuota 对象详解、作用域与核心字段
2.1 ResourceQuota 对象概述
ResourceQuota 是 Kubernetes 内置的准入控制机制,用于在多租户或团队共享集群中限制命名空间(Namespace)级别的资源消耗总量。它通过声明式策略定义“该命名空间最多能使用多少 CPU、内存、存储以及对象数量”,从而防止单个租户或应用过度占用集群资源,保障整体稳定性。
从架构视角看,ResourceQuota 属于 准入控制(Admission Control) 层的策略执行点。当用户通过 API Server 创建 Pod、Service、PVC 等资源时,ResourceQuota 准入控制器会拦截请求,校验当前命名空间已使用资源量加上新请求资源量是否超过配额上限。若超出,则直接拒绝请求并返回错误。
2.2 ResourceQuota 对象结构
一个标准的 ResourceQuota 对象包含以下核心字段:
| 字段路径 | 类型 | 说明 |
|---|---|---|
apiVersion |
string | 固定为 v1 |
kind |
string | 固定为 ResourceQuota |
metadata.name |
string | 配额对象名称,在命名空间内唯一 |
metadata.namespace |
string | 配额生效的目标命名空间 |
spec.hard |
map[string]Quantity | 硬限制:定义资源类型及其最大允许总量 |
spec.scopes |
[]ResourceQuotaScope | 作用域:限制配额仅对特定类别的资源生效 |
spec.scopeSelector |
ScopeSelector | 更精细的作用域选择器(支持表达式匹配) |
status.hard |
map[string]Quantity | 当前生效的硬限制(与 spec.hard 一致) |
status.used |
map[string]Quantity | 当前命名空间已使用的资源量 |
status.used 是动态更新的,由 kube-controller-manager 中的 ResourceQuota 控制器定期计算并上报。API Server 在准入阶段读取该值进行校验。
2.3 核心字段详解:spec.hard
spec.hard 是 ResourceQuota 的策略本体,以键值对形式定义资源类型与上限。根据资源类型,可分为三大类:
2.3.1 计算资源(Compute Resources)
requests.cpu:所有 Pod 的 CPU 请求总和上限(单位:核心数或 millicores)requests.memory:所有 Pod 的内存请求总和上限(单位:字节、Ki、Mi、Gi)limits.cpu:所有 Pod 的 CPU 限制总和上限limits.memory:所有 Pod 的内存限制总和上限
2.3.2 存储资源(Storage Resources)
requests.storage:所有 PVC 的存储请求总和上限persistentvolumeclaims:PVC 对象数量上限storageclass.storage.k8s.io/requests.storage:特定 StorageClass 的存储请求总和上限storageclass.storage.k8s.io/persistentvolumeclaims:特定 StorageClass 的 PVC 数量上限
2.3.3 对象数量(Object Count Quotas)
count/pods:Pod 对象数量上限count/services:Service 对象数量上限count/configmaps:ConfigMap 对象数量上限count/secrets:Secret 对象数量上限count/persistentvolumeclaims:PVC 对象数量上限count/deployments.apps:Deployment 对象数量上限count/statefulsets.apps:StatefulSet 对象数量上限- …(支持所有 Kubernetes 资源类型)
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
requests.storage: "100Gi"
persistentvolumeclaims: "10"
count/pods: "50"
count/services: "10"
count/configmaps: "20"
count/secrets: "20"
2.4 作用域(Scopes)与 ScopeSelector
作用域用于控制 ResourceQuota 仅对特定“类别”的 Pod 生效。默认情况下,配额对所有 Pod 生效;通过设置 spec.scopes 或 spec.scopeSelector,可以实现更精细的策略粒度。
2.4.1 预定义作用域
| 作用域名称 | 含义 | 典型场景 |
|---|---|---|
Terminating |
匹配 spec.activeDeadlineSeconds >= 0 的 Pod |
批处理作业、定时任务 |
NotTerminating |
匹配 spec.activeDeadlineSeconds 为 nil 的 Pod |
长期运行的服务 |
BestEffort |
匹配 QoS 等级为 BestEffort 的 Pod(无 requests/limits) | 低优先级、可被驱逐的作业 |
NotBestEffort |
匹配 QoS 等级为 Burstable 或 Guaranteed 的 Pod | 生产级服务 |
PriorityClass |
通过 scopeSelector 按 PriorityClass 名称匹配 |
按优先级隔离资源池 |
2.4.2 使用 ScopeSelector 实现优先级隔离
apiVersion: v1
kind: ResourceQuota
metadata:
name: high-priority-quota
namespace: production
spec:
hard:
requests.cpu: "20"
requests.memory: "40Gi"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high-priority
scopes 或 scopeSelector 时,配额只对匹配的 Pod 生效。未匹配的 Pod 不受该配额限制。这允许管理员为不同优先级的 Pod 设置独立的资源池。
2.5 ResourceQuota 生命周期与状态
ResourceQuota 的状态由控制器自动维护,管理员只需关注 spec 定义。以下流程图展示了配额校验的完整链路:
2.6 多配额对象叠加规则
一个命名空间可以创建多个 ResourceQuota 对象。当存在多个配额时,准入控制器会检查所有匹配的配额,只要任意一个配额超出,请求即被拒绝。这种设计允许管理员将配额按维度拆分管理:
- 全局配额: 定义命名空间整体资源上限
- 作用域配额: 按 QoS、优先级、是否可终止等维度细分
- 对象数量配额: 单独控制各类 API 对象数量
compute-quota(限制 CPU/Memory)和 object-quota(限制 Pod 数量),则创建 Pod 时必须同时满足两个配额。即使 CPU 未超限,若 Pod 数量已达上限,请求也会被拒绝。
2.7 常见陷阱与最佳实践
| 陷阱 | 说明 | 建议 |
|---|---|---|
| 未设置 requests/limits | Pod 未设置 requests 时,配额无法计算资源消耗,可能导致准入失败 | 配合 LimitRange 设置默认 requests/limits |
| 作用域不匹配 | 使用 scopes 后,未匹配的 Pod 不受限制,可能绕过配额 | 明确规划作用域策略,必要时创建多个配额覆盖所有场景 |
| 存储配额粒度不足 | 仅限制 requests.storage 无法控制特定 StorageClass 的用量 | 使用 storageclass.storage.k8s.io/requests.storage 精细化控制 |
| 忽略 status.used 延迟 | 配额控制器更新 status.used 存在秒级延迟,极端并发可能短暂超限 | 预留 10%-20% 缓冲余量,避免临界值 |
2.8 架构视角总结
ResourceQuota 是 Kubernetes 资源配额模型的策略定义层,它通过声明式 API 将资源限制策略转化为可被准入控制器执行的规则。从架构视角看,其核心价值在于:
- 策略与实现分离: 管理员只需定义
spec.hard,控制器负责计算与校验 - 作用域机制: 支持按 Pod 特性(QoS、优先级、生命周期)差异化配额
- 状态反馈闭环:
status.used提供实时资源消耗视图,支撑运维决策 - 多对象叠加: 允许将配额按维度拆分,提升策略的可维护性