3. 资源配额基础:Kubernetes ResourceQuota 概念、作用域、默认配额

ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制命名空间(Namespace)级别的聚合资源消耗。在冷启动削峰场景中,ResourceQuota 是防止单个签名任务或镜像拉取风暴耗尽集群资源的“第一道闸门”。

3.1 ResourceQuota 核心概念

ResourceQuota 通过 准入控制器(Admission Controller) 在资源创建/更新时拦截请求,检查命名空间内已使用资源总量是否超过配额上限。其核心能力包括:

  • 计算资源限制:CPU、内存的 requests 与 limits 总和上限。
  • 存储资源限制:PVC 总容量、StorageClass 级别限制。
  • 对象数量限制:Pod、Service、ConfigMap、Secret 等 API 对象的最大数量。
  • 扩展资源限制:GPU、FPGA 等自定义设备配额。
关键原则:ResourceQuota 是“尽力而为”的软限制 + “硬性拒绝”的硬限制。一旦命名空间内资源使用量达到配额上限,后续创建请求将被直接拒绝(HTTP 403 Forbidden),不会触发驱逐或抢占。

3.2 作用域(Scope)与匹配规则

ResourceQuota 支持按 作用域(Scope) 对资源类型进行精细化控制,避免“一刀切”导致关键组件无法启动。常见作用域包括:

作用域名称 匹配对象 典型用途
BestEffort QoS 为 BestEffort 的 Pod 限制低优先级批处理任务
NotBestEffort QoS 为 Burstable 或 Guaranteed 的 Pod 保障生产级工作负载
Terminating 设置了 activeDeadlineSeconds 的 Pod 限制 CI/CD 构建任务
NotTerminating 未设置 activeDeadlineSeconds 的 Pod 限制常驻服务
PriorityClass 指定 PriorityClass 名称的 Pod 按优先级隔离配额
最佳实践:在冷启动削峰场景中,建议为 Cosign 签名 Pod 设置独立的 PriorityClass(如 cosign-high),并创建匹配该 PriorityClass 作用域的 ResourceQuota,确保签名任务不会与业务 Pod 争抢资源。

3.3 默认配额与 LimitRange 联动

ResourceQuota 本身不设置 Pod 级别的默认资源请求/限制。若命名空间内未显式设置 Pod 的 resources.requests 或 resources.limits,ResourceQuota 将无法准确计算使用量。此时需要 LimitRange 配合:

  • LimitRange 为命名空间内未指定资源需求的 Pod 注入默认值。
  • ResourceQuota 基于注入后的值进行准入校验。
apiVersion: v1
kind: LimitRange
metadata:
  name: cosign-default-limits
  namespace: cosign-signing
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "200m"
      memory: "128Mi"
    type: Container
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: cosign-quota
  namespace: cosign-signing
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "20"
    count/deployments.apps: "5"
    count/services: "10"
  scopeSelector:
    matchExpressions:
    - operator: In
      scopeName: PriorityClass
      values: ["cosign-high"]

3.4 资源配额架构与数据流

下图展示了 ResourceQuota 在 Kubernetes API 请求链路中的位置,以及 LimitRange 如何与 ResourceQuota 协同工作:

ResourceQuota 准入控制与数据流 kubectl / 客户端 API Server 准入控制器链 etcd LimitRange 注入 ResourceQuota 校验 作用域匹配 数据流说明 1. 客户端提交 Pod 创建请求(可能未指定资源 requests/limits) 2. LimitRange 注入器自动填充默认资源值 3. ResourceQuota 校验器计算命名空间内已使用资源 + 新请求资源 4. 若超出配额上限,请求被拒绝;否则写入 etcd

3.5 多维度配额配置示例

以下是一个面向 Cosign 签名命名空间的完整 ResourceQuota 配置,涵盖计算资源、对象数量和扩展资源:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cosign-multi-dimension-quota
  namespace: cosign-signing
spec:
  hard:
    # 计算资源
    requests.cpu: "8"
    requests.memory: "16Gi"
    limits.cpu: "16"
    limits.memory: "32Gi"
    # 存储资源
    requests.storage: "100Gi"
    persistentvolumeclaims: "10"
    # 对象数量
    pods: "50"
    services: "10"
    configmaps: "20"
    secrets: "20"
    count/deployments.apps: "10"
    count/jobs.batch: "30"
    # 扩展资源(假设使用 NVIDIA GPU)
    requests.nvidia.com/gpu: "2"
注意:ResourceQuota 的 hard 字段中,requests.storage 和 persistentvolumeclaims 是独立维度。即使 PVC 数量未超限,若总存储请求超过 requests.storage,新的 PVC 创建也会被拒绝。

3.6 配额冲突与调试

当 ResourceQuota 拒绝请求时,Kubernetes 会返回明确的错误信息。常见错误及排查方法:

错误信息 原因 解决方案
exceeded quota: ... 资源总量超出配额上限 检查 kubectl describe quota 查看当前使用量
must specify limits.cpu Pod 未设置资源限制,且 LimitRange 未配置 创建 LimitRange 或显式设置 Pod 资源
scope selector mismatch Pod 的 PriorityClass 与作用域不匹配 检查 scopeSelector 表达式与 Pod 的 PriorityClass 名称
forbidden: quota usage exceeds 即使加上新资源也会立即超限 清理命名空间中未使用的资源或扩容配额
调试命令:kubectl get quota -n <namespace> -o yaml 可查看配额当前使用量(status.used 字段);kubectl describe quota -n <namespace> 提供人类可读的摘要。