3. 资源配额(ResourceQuota)原理
ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的资源消耗总量。它通过声明式策略防止单个团队或应用“抢占”集群资源,是实现多租户隔离、成本分摊和性能保障的基础设施。
3.1 ResourceQuota 对象定义
一个标准的 ResourceQuota 对象包含 spec.hard 字段,用于定义资源上限。以下是一个典型配置:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
persistentvolumeclaims: "5"
pods: "20"
services: "10"
configmaps: "10"
关键字段说明:
spec.hard:硬性上限,超出后 API Server 会拒绝创建新资源。spec.scopes:可选,限定配额生效的作用域(如仅对 Terminating 或 NotTerminating 的 Pod 生效)。
3.2 作用域(Scopes)
作用域允许将配额细粒度地应用到特定类型的 Pod 或资源上,避免“一刀切”。常见作用域包括:
| 作用域 | 含义 | 典型场景 |
|---|---|---|
Terminating |
匹配设置了 activeDeadlineSeconds 的 Pod |
批处理任务、CI/CD Job |
NotTerminating |
匹配未设置 activeDeadlineSeconds 的 Pod |
长期运行的服务(Deployment、StatefulSet) |
BestEffort |
匹配 QoS 为 BestEffort 的 Pod(未设置 requests/limits) | 低优先级、可被驱逐的测试负载 |
NotBestEffort |
匹配 QoS 非 BestEffort 的 Pod | 生产级、有资源保障的服务 |
CrossNamespacePodAffinity |
匹配使用了跨命名空间 Pod 亲和性的 Pod | 多团队协同部署场景 |
最佳实践: 建议为每个命名空间创建至少两个 ResourceQuota 对象——一个用于
NotTerminating(生产服务),一个用于 Terminating(批处理任务),从而隔离不同工作负载的资源池。
3.3 配额类型
ResourceQuota 支持三类配额:计算资源、存储资源 和 对象数量。理解这三类的差异是成本分摊和性能调优的基础。
3.3.1 计算资源配额
控制 CPU 和内存的 requests 与 limits。这是影响 Pod 调度和运行时性能最直接的配额。
| 资源名称 | 单位 | 说明 |
|---|---|---|
requests.cpu |
核(m 或整数) | 调度时保证的最小 CPU 资源 |
requests.memory |
字节(Mi、Gi) | 调度时保证的最小内存资源 |
limits.cpu |
核(m 或整数) | Pod 可使用的 CPU 上限(CFS 配额) |
limits.memory |
字节(Mi、Gi) | Pod 可使用的内存上限(OOM 阈值) |
性能陷阱: 如果
limits.memory 设置过高而 requests.memory 设置过低,可能导致节点内存超卖严重,触发 OOM Killer 频繁驱逐 Pod。建议生产环境保持 requests.memory 与 limits.memory 比例不超过 1:2。
3.3.2 存储资源配额
控制持久化存储的声明总量和单个声明的大小上限。
| 资源名称 | 说明 |
|---|---|
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 数量上限 |
3.3.3 对象数量配额
控制 Kubernetes 核心对象(如 Pod、Service、ConfigMap 等)的数量上限。这直接影响 API Server 的负载和 etcd 的存储压力。
| 资源名称 | 典型上限建议 | 性能影响 |
|---|---|---|
pods |
100-500(视集群规模) | 影响调度器、kubelet 心跳、CNI 插件 |
services |
50-200 | 影响 kube-proxy iptables/IPVS 规则数量 |
configmaps |
100-500 | 影响 API Server 缓存和 etcd 存储 |
secrets |
100-500 | 影响 API Server 缓存和 etcd 存储 |
persistentvolumeclaims |
50-200 | 影响 PV/PVC 控制器和存储后端 |
3.4 配额生效与冲突处理
当多个 ResourceQuota 对象作用于同一个命名空间时,Kubernetes 会取所有配额中对应资源类型的 最大值 作为实际生效上限。例如:
- Quota A 设置
pods: 10 - Quota B 设置
pods: 20 - 实际生效:
pods: 20
成本分摊建议: 使用
kubectl describe quota -n <namespace> 查看当前配额使用率。结合 Prometheus 的 kube_resourcequota 指标,可以构建实时成本看板,按命名空间或团队维度展示资源消耗与配额占比。
3.5 配额与性能调优的关联
ResourceQuota 不仅是成本控制工具,更是性能调优的“安全阀”:
| 性能维度 | 配额设置建议 | 调优效果 |
|---|---|---|
| 调度延迟 | 限制 pods 数量上限 |
避免调度队列过长,降低调度器压力 |
| API Server 响应 | 限制 configmaps、secrets 数量 |
减少 etcd 对象数量,降低 watch 开销 |
| 节点稳定性 | 限制 limits.cpu 与 limits.memory 比例 |
防止内存超卖导致节点 OOM |
| 网络性能 | 限制 services 和 endpoints 数量 |
减少 kube-proxy 规则数量,提升转发效率 |
注意: ResourceQuota 是 准入控制 机制,仅在资源创建/更新时生效。它无法限制已运行的 Pod 的资源使用行为。对于运行时资源限制,需要结合 LimitRange 和 cgroup 配置。