4. 资源配额概念:Kubernetes ResourceQuota 对象详解、作用域、与 LimitRange 的区别、在 CAPI 集群中的生效范围
在多租户 CAPI 集群中,资源配额是防止“噪声邻居”和保障租户 SLA 的第一道防线。Kubernetes 原生提供的 ResourceQuota 对象能够对命名空间级别的聚合资源消耗进行硬性限制,而 LimitRange 则负责约束单个 Pod/容器的资源边界。两者协同工作,构成 CAPI 多租户资源调优的基石。
核心要点: ResourceQuota 是“总量闸门”,LimitRange 是“单实例护栏”。在 CAPI 管理的集群中,ResourceQuota 的生效范围严格限定在每个租户命名空间内,且由 ClusterClass 或 ClusterResourceSet 自动下发。
4.1 ResourceQuota 对象详解
ResourceQuota 是一个命名空间级别的 API 对象,用于定义该命名空间内所有 Pod、Service、PVC 等资源对象的聚合使用上限。一旦命名空间内的资源总量超过配额,Kubernetes API Server 将拒绝后续的创建请求。
4.1.1 资源类型与配额维度
| 资源类别 | 可配额度字段 | 说明 |
|---|---|---|
| 计算资源 | requests.cpu |
所有 Pod 的 CPU 请求总和上限(单位:核心数) |
requests.memory |
所有 Pod 的内存请求总和上限(单位:字节) | |
limits.cpu / limits.memory |
所有 Pod 的 CPU/内存限制总和上限 | |
| 存储资源 | requests.storage |
所有 PVC 的存储请求总和上限 |
persistentvolumeclaims |
命名空间中允许的 PVC 最大数量 | |
| 对象数量 | pods |
命名空间中允许的 Pod 最大数量 |
services |
命名空间中允许的 Service 最大数量 | |
configmaps / secrets |
命名空间中允许的 ConfigMap/Secret 最大数量 |
4.1.2 典型 ResourceQuota 配置示例
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
persistentvolumeclaims: "10"
requests.storage: "100Gi"
services: "10"
configmaps: "30"
secrets: "30"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high-priority
最佳实践: 在 CAPI 多租户场景中,建议为每个租户命名空间同时配置
requests 和 limits 配额。仅限制 limits 而不限制 requests 可能导致调度器过度承诺,引发节点资源争抢。
4.2 ResourceQuota 作用域
作用域(Scope)允许管理员对配额进行更精细的控制,使配额规则仅适用于特定类别的 Pod。Kubernetes 支持以下四种作用域:
- Terminating:适用于设置了
activeDeadlineSeconds的 Pod(通常是 Job 或批处理任务)。 - NotTerminating:适用于未设置
activeDeadlineSeconds的 Pod(长期运行的服务)。 - BestEffort:适用于 QoS 等级为 BestEffort 的 Pod(未设置任何 requests/limits)。
- NotBestEffort:适用于 QoS 等级为 Burstable 或 Guaranteed 的 Pod。
通过 scopeSelector 或 scopes 字段,可以为不同优先级的负载分配独立的配额池。例如,将批处理任务与在线服务隔离:
apiVersion: v1
kind: ResourceQuota
metadata:
name: batch-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "2"
requests.memory: "4Gi"
pods: "10"
scopes:
- Terminating
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: service-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
pods: "20"
scopes:
- NotTerminating
注意: 作用域是互斥的。一个 Pod 只能匹配一个作用域下的配额。如果命名空间中同时存在多个作用域不同的 ResourceQuota,Pod 必须满足所有匹配的配额约束才能被创建。
4.3 ResourceQuota 与 LimitRange 的区别
两者虽然都用于资源管控,但职责和生效粒度完全不同。下表从多个维度进行对比:
| 对比维度 | ResourceQuota | LimitRange |
|---|---|---|
| 管控粒度 | 命名空间级别(聚合总量) | Pod / 容器级别(单个实例) |
| 核心功能 | 限制资源使用上限,防止超卖 | 设置默认值、最小/最大值约束 |
| 是否强制 | 硬性拒绝(超过即报错) | 硬性拒绝(超出范围报错) |
| 默认值能力 | 无 | 可为未设置 requests/limits 的 Pod 注入默认值 |
| 典型场景 | 租户资源总量隔离 | 防止单个容器过度占用,统一资源规格 |
| 冲突处理 | 与 LimitRange 配合:LimitRange 设默认值,ResourceQuota 检查总量 | 与 ResourceQuota 配合:先注入默认值,再校验配额 |
协同工作流: 当 Pod 创建时,Kubernetes 准入控制器首先应用 LimitRange 的默认值(如果 Pod 未显式设置 requests/limits),然后检查 ResourceQuota 的聚合总量是否超标。两者缺一不可。
4.4 在 CAPI 集群中的生效范围
在 CAPI 架构中,ResourceQuota 的生效范围遵循“管理集群下发,工作集群执行”的原则。具体生效路径如下:
- 管理集群:通过 ClusterClass 的
patches或 ClusterResourceSet 定义 ResourceQuota 模板。 - 下发机制:CAPI 控制器将 ResourceQuota 对象应用到工作集群的指定命名空间(通常与租户一一对应)。
- 生效范围:ResourceQuota 仅在其所在的工作集群命名空间内生效,不影响管理集群或其他工作集群。
- 多集群隔离:每个工作集群拥有独立的 etcd 和 API Server,因此跨集群的 ResourceQuota 互不感知。
4.5 CAPI 环境下的配额调优策略
基于上述生效范围,在 CAPI 多租户环境中实施 ResourceQuota 调优时,应遵循以下策略:
- 模板化下发:在 ClusterClass 中定义 ResourceQuota 模板,通过
patches或variables为不同租户注入差异化配额值。 - 分层配额:为每个租户命名空间设置基础配额(如 CPU 4 核、内存 8Gi),再通过作用域为高优先级负载预留额外资源。
- 监控与告警:使用
kubectl describe quota或 Prometheus 监控配额使用率,当使用率超过 80% 时触发告警。 - 动态调整:结合 CAPI 的 ClusterResourceSet 实现配额的热更新,无需重建工作集群。
实战建议: 在 CAPI 管理集群中,建议使用
ClusterResourceSet 而非手动创建 ResourceQuota。这样当工作集群重建或扩缩容时,配额配置会自动同步,避免配置漂移。