2. Kubernetes 资源配额基础:ResourceQuota 对象定义、作用域、与 LimitRange 的区别

在 Kubernetes 集群中,资源配额(ResourceQuota)是保障多租户环境下资源公平性与稳定性的核心机制。对于 Argo CD 渐进式发布场景而言,理解 ResourceQuota 的定义、作用域及其与 LimitRange 的差异,是评估发布过程中资源容量是否充足、是否会触发调度失败的前提。

2.1 ResourceQuota 对象定义

ResourceQuota 是一个命名空间级别的 API 对象,用于限制该命名空间中所有 Pod 或 PVC 等资源的累计使用量上限。当命名空间内的资源总量超过配额时,Kubernetes 会拒绝新的创建请求,并返回 403 Forbidden 错误。

以下是一个典型的 ResourceQuota 定义示例:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    persistentvolumeclaims: "10"
    pods: "50"
    count/deployments.apps: "10"
    count/services: "20"

关键字段说明:

字段 类型 说明
spec.hard map[string]Quantity 定义资源硬限制,超过即拒绝
requests.cpu / requests.memory Quantity 所有 Pod 的 request 总和上限
limits.cpu / limits.memory Quantity 所有 Pod 的 limit 总和上限
pods Quantity 命名空间中允许的最大 Pod 数量
count/<resource>.<group> Quantity 特定资源对象(如 Deployment、Service)的数量上限
渐进式发布关联: 当 Argo CD 执行蓝绿发布或金丝雀发布时,会临时创建额外的 Pod 副本。如果命名空间的 pods 配额或 requests.cpu 配额不足,新版本 Pod 将无法调度,导致发布卡住或回滚。

2.2 ResourceQuota 作用域

ResourceQuota 支持通过 spec.scopeSelector 限定配额生效的范围,从而实现更精细的资源管控。常见的作用域包括:

  • Terminating:仅统计 spec.activeDeadlineSeconds >= 0 的 Pod(通常为 Job 或批处理任务)。
  • NotTerminating:仅统计 spec.activeDeadlineSeconds 为 nil 的 Pod(长期运行服务)。
  • BestEffort:仅统计 QoS 等级为 BestEffort 的 Pod(未设置 request/limit)。
  • NotBestEffort:仅统计 QoS 等级非 BestEffort 的 Pod(设置了 request 或 limit)。
  • PriorityClass:按 PriorityClass 名称筛选,例如 scopeName: PriorityClass 配合 operator: In 和 values: ["high-priority"]。

作用域组合示例:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: batch-quota
  namespace: production
spec:
  hard:
    requests.cpu: "2"
    requests.memory: "4Gi"
  scopeSelector:
    matchExpressions:
      - scopeName: Terminating
        operator: Exists
      - scopeName: NotBestEffort
        operator: Exists

上述配额仅对 Terminating 且非 BestEffort 的 Pod 生效,适用于批处理任务场景。

注意: 作用域配置不当可能导致配额统计遗漏。例如,如果只对 NotTerminating 设置了配额,而渐进式发布中临时创建的 Pod 被标记为 Terminating,则这些 Pod 将不受配额约束,可能引发资源争抢。

2.3 ResourceQuota 与 LimitRange 的区别

ResourceQuota 和 LimitRange 都是 Kubernetes 的资源管控机制,但职责不同。下表从多个维度进行对比:

对比维度 ResourceQuota LimitRange
作用范围 命名空间级别,限制所有 Pod/PVC 的累计总量 命名空间级别,限制单个 Pod/Container 的最小/最大值
核心功能 防止资源总量超限,保障租户隔离 防止单个容器资源过大或过小,提供默认值
触发条件 创建新资源时检查总量是否超过 hard 限制 创建/更新 Pod 时校验单个容器规格是否在 min/max 范围内
默认值 不提供默认值,仅做上限约束 可设置 default 和 defaultRequest,为未显式设置资源的容器注入默认值
典型场景 多团队共享集群、生产环境容量规划 防止开发人员忘记设置资源限制、控制单个 Pod 资源上限
与渐进式发布的关系 直接影响新版本 Pod 能否被调度(总量不足则失败) 影响单个 Pod 的资源规格是否符合命名空间规范

两者通常配合使用:LimitRange 确保每个 Pod 的资源规格在合理范围内,ResourceQuota 确保所有 Pod 的总和不超过命名空间预算。

最佳实践: 在 Argo CD 管理的命名空间中,建议同时配置 ResourceQuota 和 LimitRange。ResourceQuota 用于控制渐进式发布期间的总资源消耗上限,LimitRange 用于确保金丝雀 Pod 或蓝绿 Pod 的资源规格符合预期,避免因单个 Pod 资源过大而挤占其他服务。

2.4 ResourceQuota 与 LimitRange 协同工作示意图

下图展示了 ResourceQuota 和 LimitRange 在命名空间中的协同关系:

ResourceQuota 与 LimitRange 协同工作示意图 命名空间:production ResourceQuota 限制累计总量 pods: 50, cpu: 8, mem: 16Gi LimitRange 限制单个容器规格 min: 0.1cpu/128Mi, max: 2cpu/4Gi Pod A (稳定版) request: 0.5cpu/1Gi Pod B (金丝雀) request: 0.5cpu/1Gi Pod C (蓝绿) request: 1.0cpu/2Gi LimitRange 确保每个 Pod 的 request/limit 在 0.1cpu/128Mi ~ 2cpu/4Gi 之间 ResourceQuota 确保所有 Pod 的累计 request.cpu ≤ 8, request.memory ≤ 16Gi

2.5 渐进式发布中的配额评估要点

在 Argo CD 渐进式发布场景下,评估 ResourceQuota 容量时需重点关注以下指标:

  1. 临时副本数:金丝雀发布或蓝绿发布期间,新旧版本 Pod 会同时存在。需计算最大并发副本数是否超过 pods 配额。
  2. 资源预留:新版本 Pod 的 requests 总和 + 旧版本 Pod 的 requests 总和 ≤ requests.cpu / requests.memory 配额。
  3. PVC 配额:如果新版本需要创建 PVC(如 StatefulSet 场景),需检查 persistentvolumeclaims 配额是否充足。
  4. 对象计数配额:count/deployments.apps、count/services 等配额可能限制 Argo CD 创建临时 Service 或 Deployment。
评估公式: 渐进式发布所需资源 = 旧版本 Pod 资源总量 + 新版本 Pod 资源总量 × 金丝雀比例(或蓝绿并行副本数)。确保该值 ≤ ResourceQuota 的 hard 限制,否则需调整发布策略或临时提升配额。