2. 资源配额(Resource Quota)基础:Kubernetes ResourceQuota 对象详解

在 Kubernetes 多租户或 GitOps 交付环境中,资源配额(Resource Quota)是防止“吵闹邻居”效应、保障集群稳定性的第一道防线。ResourceQuota 是一个命名空间级别的 API 对象,用于限制该命名空间中所有 Pod 和容器的资源消耗总量。理解其工作原理、作用域和常见陷阱,是进行资源校准的前提。

2.1 ResourceQuota 核心概念与对象定义

ResourceQuota 通过声明式配置,为命名空间设置硬性资源上限。当命名空间内的资源使用量超过配额时,Kubernetes API Server 会拒绝后续的创建请求,并返回 403 Forbidden 错误。

以下是一个典型的 ResourceQuota 对象 YAML 定义:

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"
    requests.ephemeral-storage: "50Gi"
    limits.ephemeral-storage: "100Gi"
    persistentvolumeclaims: "10"
    pods: "20"
    services: "10"
    services.loadbalancers: "2"
    services.nodeports: "5"
    configmaps: "10"
    secrets: "10"
    replicationcontrollers: "20"
    resourcequotas: "1"
关键字段说明:
  • spec.hard:定义命名空间内所有资源的总上限,单位遵循 Kubernetes 标准(如 CPU 为核数,Memory 为字节数)。
  • requests:Pod 调度时保证的最小资源量,直接影响调度决策。
  • limits:Pod 运行时允许使用的最大资源量,超出会被 OOM Kill 或 CPU 节流。
  • pods:限制命名空间内可运行的 Pod 总数,防止失控的 Deployment 创建过多副本。

2.2 资源配额作用域(Scope)详解

ResourceQuota 支持通过 spec.scopes 字段对配额进行精细化控制。作用域决定了哪些类型的 Pod 或资源会被计入配额统计。这是 GitOps 交付中避免“配额误判”的核心知识点。

作用域(Scope) 匹配条件 典型使用场景
BestEffort Pod 未设置 requests 和 limits 限制低优先级、可被驱逐的测试 Pod
NotBestEffort Pod 设置了 requests 或 limits 保障生产级 Pod 的资源配额
Terminating Pod 设置了 activeDeadlineSeconds 限制批处理任务(Job)的资源总量
NotTerminating Pod 未设置 activeDeadlineSeconds 限制长期运行的服务(Deployment)
PriorityClass Pod 关联了指定的 PriorityClass 按优先级隔离资源池(如高优 vs 低优)
避坑提示: 当使用 BestEffort 作用域时,必须同时创建 NotBestEffort 配额,否则未设置 requests/limits 的 Pod 将无法被任何配额约束,导致资源失控。

2.3 资源配额与作用域的组合示例

以下示例展示了如何通过两个 ResourceQuota 对象,分别管理“高优先级服务”和“低优先级批处理任务”的资源池:

---
# 高优先级服务配额(NotTerminating + NotBestEffort)
apiVersion: v1
kind: ResourceQuota
metadata:
  name: high-priority-quota
  namespace: team-alpha
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
  scopes:
    - NotTerminating
    - NotBestEffort

---
# 低优先级批处理配额(Terminating + BestEffort)
apiVersion: v1
kind: ResourceQuota
metadata:
  name: batch-quota
  namespace: team-alpha
spec:
  hard:
    pods: "10"
    requests.cpu: "2"
    requests.memory: "4Gi"
  scopes:
    - Terminating
    - BestEffort

2.4 ResourceQuota 与 LimitRange 的协同关系

ResourceQuota 控制“总量”,而 LimitRange 控制“单个 Pod 的边界”。两者必须配合使用,否则会出现以下问题:

  • 只有 ResourceQuota,没有 LimitRange:用户可能创建一个 requests 为 0 的 Pod,瞬间占满整个命名空间的配额。
  • 只有 LimitRange,没有 ResourceQuota:单个 Pod 被限制,但团队可以创建大量 Pod 耗尽集群资源。
对比维度 ResourceQuota LimitRange
作用范围 命名空间级别(总量) Pod/Container 级别(单实例)
默认值 不提供默认值 可设置默认 requests/limits
约束类型 硬性上限(Hard Limit) 最小/最大约束(Min/Max)
典型错误 未设置作用域导致配额不生效 未设置默认值导致 Pod 被拒绝

2.5 资源配额作用域关系图

下图展示了不同作用域如何划分 Pod 类型,以及 ResourceQuota 如何与 LimitRange 协同工作:

ResourceQuota 作用域与协同关系图 ResourceQuota 作用域与 LimitRange 协同关系 Namespace: team-alpha ResourceQuota(总量控制) BestEffort 作用域 Pod 无 requests/limits 低优先级、可驱逐 测试/批处理任务 NotBestEffort 作用域 Pod 有 requests/limits 高优先级、稳定运行 生产级服务 Terminating 作用域 activeDeadlineSeconds Job/CronJob 批处理 有生命周期限制 LimitRange(单实例约束) ResourceQuota 控制总量上限,LimitRange 控制单 Pod 边界,两者缺一不可

2.6 资源配额状态查询与调试

在 GitOps 交付流水线中,验证资源配额是否生效是环境校准的关键步骤。以下命令可帮助快速诊断配额问题:

# 查看命名空间内的所有 ResourceQuota
kubectl get resourcequota -n team-alpha

# 查看配额的使用详情(Used 列显示当前消耗)
kubectl describe resourcequota compute-quota -n team-alpha

# 输出示例:
# Name:            compute-quota
# Namespace:       team-alpha
# Resource         Used  Hard
# --------         ---   ---
# requests.cpu     2     4
# requests.memory  4Gi   8Gi
# limits.cpu       3     8
# limits.memory    6Gi   16Gi
# pods             5     20

# 检查 Pod 是否因配额被拒绝
kubectl get events -n team-alpha --field-selector reason=FailedCreate
GitOps 校准要点:
  • 在 GitOps 仓库中,ResourceQuota 应作为独立 YAML 文件管理,与应用部署清单分离。
  • 使用 kubectl diff 或 ArgoCD 的 diff 功能,在同步前预览配额变更影响。
  • 为每个环境(dev/staging/prod)维护独立的配额配置,避免跨环境复用导致资源争抢。

2.7 常见避坑清单

陷阱 现象 解决方案
未设置 LimitRange Pod 因缺少默认 requests 被 ResourceQuota 拒绝 先创建 LimitRange 设置默认值,再创建 ResourceQuota
作用域冲突 Pod 同时匹配多个互斥作用域,配额统计异常 确保作用域逻辑互斥,如 BestEffort 与 NotBestEffort 不重叠
存储配额遗漏 PVC 创建成功但 Pod 挂载失败 在 ResourceQuota 中显式声明 persistentvolumeclaims 和 requests.storage
配额更新延迟 删除 Pod 后配额未立即释放 等待 kube-controller-manager 同步周期(默认 5 分钟)
跨命名空间资源 DaemonSet 或 ClusterRole 绕过配额 使用 Pod Security Admission 和 OPA/Gatekeeper 补充策略