3. 命名空间资源配额:ResourceQuota 对象
在多租户或微服务架构中,单个命名空间内的资源消耗失控是常见的故障来源。Kubernetes 通过 ResourceQuota 对象为每个命名空间设置资源上限,防止“吵闹的邻居”问题,确保集群资源的公平分配与稳定性。
核心原则:ResourceQuota 是作用于命名空间级别的准入控制机制。一旦在命名空间中创建了 ResourceQuota,该命名空间内所有 Pod 和对象的资源请求(requests)与限制(limits)总和不得超过配额值。
3.1 ResourceQuota 对象结构
一个标准的 ResourceQuota 清单文件包含 apiVersion、kind、metadata 和 spec.hard 字段。spec.hard 中定义各类资源的硬性上限。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "6"
limits.memory: "12Gi"
requests.nvidia.com/gpu: "1"
提示:如果命名空间中已存在运行中的 Pod,创建 ResourceQuota 时需确保当前资源使用量不超过配额值,否则创建会失败。
3.2 CPU 与内存配额
CPU 和内存是计算资源的核心。ResourceQuota 支持分别对 requests(调度保证)和 limits(硬性上限)进行限制。
| 资源名称 | 含义 | 单位示例 |
|---|---|---|
requests.cpu |
所有 Pod 的 CPU 请求总和上限 | 4(核)、100m(毫核) |
requests.memory |
所有 Pod 的内存请求总和上限 | 8Gi、512Mi |
limits.cpu |
所有 Pod 的 CPU 限制总和上限 | 6(核) |
limits.memory |
所有 Pod 的内存限制总和上限 | 12Gi |
注意:如果只设置
limits.cpu 而未设置 requests.cpu,Kubernetes 会默认将 requests 值设为与 limits 相同。建议同时设置两者,避免资源浪费。
3.3 存储配额
存储配额用于控制持久卷声明(PVC)的总存储容量和数量,防止某个命名空间耗尽集群存储资源。
spec:
hard:
requests.storage: "500Gi" # 所有 PVC 存储请求总和上限
persistentvolumeclaims: "10" # PVC 对象数量上限
ssd.storageclass.storage.k8s.io/requests.storage: "200Gi" # 特定 StorageClass 的存储上限
| 资源名称 | 作用范围 | 说明 |
|---|---|---|
requests.storage |
所有 StorageClass | PVC 请求的总存储容量上限 |
persistentvolumeclaims |
所有 PVC | PVC 对象数量上限 |
<storage-class>.storageclass.storage.k8s.io/requests.storage |
特定 StorageClass | 按存储类细分的容量上限 |
<storage-class>.storageclass.storage.k8s.io/persistentvolumeclaims |
特定 StorageClass | 按存储类细分的 PVC 数量上限 |
3.4 对象数量配额
除了计算和存储资源,ResourceQuota 还可以限制命名空间内 Kubernetes 对象的数量,防止 API Server 因对象过多而性能下降。
spec:
hard:
pods: "50" # Pod 数量上限
services: "10" # Service 数量上限
configmaps: "20" # ConfigMap 数量上限
secrets: "20" # Secret 数量上限
replicationcontrollers: "10"
deployments.apps: "10"
statefulsets.apps: "5"
jobs.batch: "10"
cronjobs.batch: "5"
最佳实践:对象数量配额应结合命名空间的实际用途设定。例如,开发环境可适当放宽 Pod 数量,但严格限制 Service 和 Ingress 数量以控制网络复杂度。
3.5 配额作用域(Scopes)
ResourceQuota 支持通过 spec.scopes 字段将配额限定到特定类型的资源,实现更精细的控制。
| 作用域名称 | 匹配对象 | 典型用途 |
|---|---|---|
Terminating |
spec.activeDeadlineSeconds >= 0 的 Pod |
限制批处理作业的总资源 |
NotTerminating |
spec.activeDeadlineSeconds 为 nil 的 Pod |
限制长期运行服务 |
BestEffort |
QoS 等级为 BestEffort 的 Pod | 限制无资源保证的 Pod |
NotBestEffort |
QoS 等级非 BestEffort 的 Pod | 限制有资源保证的 Pod |
PriorityClass |
指定 PriorityClass 的 Pod | 按优先级隔离资源 |
apiVersion: v1
kind: ResourceQuota
metadata:
name: batch-quota
namespace: team-alpha
spec:
hard:
pods: "20"
requests.cpu: "2"
requests.memory: "4Gi"
scopes:
- Terminating
作用域组合:可以同时指定多个作用域(如
NotTerminating + NotBestEffort),配额仅对同时满足所有作用域条件的 Pod 生效。
3.6 配额生效流程与冲突处理
下图展示了 ResourceQuota 在 Pod 创建时的准入控制流程:
3.7 多配额对象共存与优先级
一个命名空间可以创建多个 ResourceQuota 对象。当多个配额同时存在时,Kubernetes 会计算所有配额的交集,取最严格的限制生效。
# 配额 A:限制总 CPU 为 4 核
# 配额 B:限制 Terminating 作用域的 CPU 为 2 核
# 最终效果:普通 Pod 最多 4 核,批处理 Pod 最多 2 核
冲突场景:如果两个 ResourceQuota 对同一资源设置了不同上限,Kubernetes 会同时检查两个配额。只要任一配额超限,创建请求就会被拒绝。务必避免配额之间的逻辑矛盾。
3.8 查看与监控配额使用量
使用 kubectl describe quota 命令可以查看当前命名空间的配额使用情况:
kubectl describe quota compute-quota -n team-alpha
Name: compute-quota
Namespace: team-alpha
Resource Used Hard
-------- ---- ----
limits.cpu 3 6
limits.memory 6Gi 12Gi
requests.cpu 2 4
requests.memory 4Gi 8Gi
pods 12 50
监控建议:将配额使用率接入 Prometheus 监控,设置告警阈值(如使用量达到配额的 80%),提前规划扩容或清理资源。
3.9 实战:为开发团队配置完整配额
以下是一个面向开发团队的 ResourceQuota 配置示例,涵盖计算、存储、对象数量和优先级作用域:
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-team-quota
namespace: dev-team
spec:
hard:
# 计算资源
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "12"
limits.memory: "24Gi"
# 存储资源
requests.storage: "200Gi"
persistentvolumeclaims: "20"
# 对象数量
pods: "100"
services: "15"
configmaps: "30"
secrets: "30"
deployments.apps: "20"
statefulsets.apps: "10"
jobs.batch: "20"
# 扩展资源
requests.nvidia.com/gpu: "2"
scopes:
- NotTerminating
- NotBestEffort
关键要点:
- ResourceQuota 是命名空间资源治理的第一道防线,必须与 LimitRange 配合使用(LimitRange 设置单个 Pod 的默认请求/限制)。
- 生产环境建议为每个命名空间至少配置一个 ResourceQuota,防止资源泄露。
- 使用作用域(Scopes)可以实现批处理作业与长期服务的资源隔离。
- 定期审计配额使用率,及时调整配额值以适应业务增长。