2. K8s资源配额基础:ResourceQuota对象详解、LimitRange对象详解、命名空间级别的资源管控机制

在Kubernetes集群中,资源配额(Resource Quota)与限制范围(Limit Range)是命名空间级别资源管控的两大核心原语。它们共同构成了多租户环境下资源公平分配与稳定性保障的基础。本章将深入剖析这两个对象的定义、字段语义、工作原理及典型配置,为后续策略即代码模型在集群升级中的测试验证奠定坚实的知识基础。

2.1 ResourceQuota对象详解

ResourceQuota(资源配额)是一个命名空间级别的API对象,用于限制该命名空间内所有Pod、Service、PersistentVolumeClaim等对象可使用的计算资源(CPU、内存)与对象数量的上限。其核心作用是防止单个命名空间(或租户)过度消耗集群资源,确保资源分配的公平性与可预测性。

2.1.1 核心字段与语义

字段路径 类型 描述 示例值
spec.hard map[string]Quantity 定义命名空间内所有Pod可使用的资源上限(硬限制) requests.cpu: "4"
spec.scopes []ResourceQuotaScope 限定配额生效的范围(如仅对BestEffort或Terminating状态的Pod生效) NotTerminating
status.hard map[string]Quantity 当前生效的硬限制(与spec.hard一致,但可能被准入控制器修改) —
status.used map[string]Quantity 当前命名空间内已使用的资源量 requests.cpu: "2.5"

2.1.2 支持的资源类型

ResourceQuota可管控的资源分为三类:计算资源、存储资源和对象数量。以下为常用资源类型清单:

  • 计算资源:
    • requests.cpu / limits.cpu
    • requests.memory / limits.memory
    • requests.ephemeral-storage / limits.ephemeral-storage
  • 存储资源:
    • requests.storage(所有PVC的总存储请求)
    • persistentvolumeclaims(PVC数量上限)
    • storageclass.storage.k8s.io/requests.storage(按StorageClass细分的存储配额)
  • 对象数量:
    • pods、services、configmaps、secrets、replicationcontrollers、resourcequotas等

2.1.3 典型配置示例

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: team-alpha
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "3"
    requests.storage: "50Gi"
关键行为:当命名空间内已使用的资源达到spec.hard中定义的上限时,Kubernetes API Server会拒绝后续创建Pod或PVC的请求,并返回403 Forbidden错误。配额检查发生在准入控制阶段(Admission Control),因此不会出现资源超卖。

2.2 LimitRange对象详解

LimitRange(限制范围)是另一个命名空间级别的资源管控对象,其作用与ResourceQuota互补。ResourceQuota限制的是总量,而LimitRange限制的是单个Pod或容器的资源上下界,并可为未显式设置资源请求/限制的Pod提供默认值。

2.2.1 核心字段与语义

字段路径 类型 描述 示例值
spec.limits[*].type LimitType 限制类型:Pod、Container、PersistentVolumeClaim Container
spec.limits[*].min map[string]Quantity 容器/ Pod 资源请求的最小值 cpu: "100m"
spec.limits[*].max map[string]Quantity 容器/ Pod 资源限制的最大值 memory: "1Gi"
spec.limits[*].default map[string]Quantity 当容器未设置limits时,自动注入的默认限制值 cpu: "500m"
spec.limits[*].defaultRequest map[string]Quantity 当容器未设置requests时,自动注入的默认请求值 memory: "256Mi"
spec.limits[*].maxLimitRequestRatio map[string]Quantity 限制与请求的最大比值(如limits.cpu / requests.cpu ≤ 2) cpu: "2"

2.2.2 典型配置示例

apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: team-alpha
spec:
  limits:
  - type: Container
    min:
      cpu: "50m"
      memory: "64Mi"
    max:
      cpu: "2"
      memory: "2Gi"
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    maxLimitRequestRatio:
      cpu: "4"
  - type: PersistentVolumeClaim
    min:
      storage: "1Gi"
    max:
      storage: "100Gi"
注意:LimitRange的默认值注入发生在Pod创建时的准入控制阶段。如果Pod中某个容器未设置requests或limits,LimitRange会自动填充defaultRequest和default。但若Pod的显式设置违反了min或max约束,Pod创建将被拒绝。

2.3 命名空间级别的资源管控机制

ResourceQuota与LimitRange协同工作,形成命名空间级别的资源管控体系。其整体工作流程如下图所示:

命名空间资源管控机制流程图 命名空间资源管控机制流程图 用户提交Pod YAML LimitRange 准入检查 通过? 拒绝创建 ResourceQuota 总量检查 通过? 拒绝创建 Pod 创建成功 说明 1. LimitRange 先检查单容器约束 2. ResourceQuota 再检查总量约束 3. 两者都通过,Pod 才被允许创建

2.3.1 管控机制对比

维度 ResourceQuota LimitRange
管控粒度 命名空间级别(总量) Pod / 容器 / PVC 级别(单实例)
主要目的 防止资源过度使用 防止资源浪费或配置遗漏
默认值注入 不支持 支持(default / defaultRequest)
约束类型 硬限制(hard limit) 最小/最大/比值约束
检查时机 Pod创建时(准入控制) Pod创建时(准入控制)
典型场景 多租户资源隔离 统一容器资源规格

2.3.2 最佳实践与避坑指南

  • 先创建LimitRange,再创建ResourceQuota:如果先创建ResourceQuota而未设置LimitRange,可能导致部分Pod因缺少资源请求而被拒绝(因为ResourceQuota要求所有Pod必须设置requests)。
  • 合理设置maxLimitRequestRatio:防止用户将requests设置得极低而limits设置得极高,导致调度器低估实际资源需求,造成节点过载。
  • 使用scopes精细化配额:通过spec.scopes字段,可以为不同QoS类别的Pod设置不同的配额。例如,对BestEffort Pod设置较低的内存配额,对Guaranteed Pod设置较高的CPU配额。
  • 监控配额使用率:定期检查kubectl get resourcequota -n <namespace> -o yaml中的status.used字段,及时发现配额瓶颈。
关键结论:在Kubernetes集群升级场景中,ResourceQuota和LimitRange的配置正确性直接影响升级后的Pod调度与运行稳定性。测试验证阶段必须覆盖以下场景:
(1) 升级后配额总量是否被意外修改;
(2) LimitRange默认值是否与升级后的节点资源规格兼容;
(3) 多命名空间之间的配额隔离是否在升级后依然有效。