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 创建时的准入控制流程:

ResourceQuota 准入控制流程 用户提交 Pod API Server 准入控制器 检查 ResourceQuota 通过 资源充足,创建成功 失败 配额超限,拒绝创建 说明: ResourceQuota 在 Pod 创建时进行准入检查,统计命名空间内所有 Pod 的资源总和。 如果当前使用量 + 新 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)可以实现批处理作业与长期服务的资源隔离。
  • 定期审计配额使用率,及时调整配额值以适应业务增长。