2. 资源配额概念:Kubernetes ResourceQuota 定义、作用域与核心字段解析

在 Kubernetes 多租户或团队共享集群的场景中,资源配额(ResourceQuota)是防止“资源抢占”和“噪声邻居”的第一道防线。它通过声明式策略限制命名空间(Namespace)级别的资源消耗总量,确保单一应用或团队不会耗尽集群资源。

2.1 ResourceQuota 定义与工作原理

ResourceQuota 是 Kubernetes 内置的准入控制(Admission Control)机制。当用户创建或更新 Pod、Service、PersistentVolumeClaim 等对象时,API Server 会检查当前命名空间内的资源使用量是否超出配额限制。若超出,请求将被拒绝并返回错误。

核心工作流程:
  1. 管理员在命名空间内创建 ResourceQuota 对象。
  2. 用户提交 Pod/Service/PVC 创建请求。
  3. API Server 准入控制器(ResourceQuota Admission Controller)拦截请求。
  4. 计算当前命名空间已使用资源总量 + 请求资源量。
  5. 若总和 ≤ 配额上限,允许创建;否则拒绝并返回 403 Forbidden。
ResourceQuota 准入控制流程 用户提交请求 API Server 拦截 配额检查 允许/拒绝 关键说明 • 配额检查发生在对象创建/更新时,不适用于已存在的资源。 • 配额计算基于请求值(requests),而非限制值(limits)。 • 若命名空间未创建 ResourceQuota,则无资源上限约束。

2.2 作用域(Scope)与资源类型

ResourceQuota 支持按作用域(Scope)精细化控制。作用域决定了配额适用于哪些资源对象,以及何时生效。

作用域(Scope) 适用对象 典型场景
BestEffort QoS 等级为 BestEffort 的 Pod 限制低优先级、无资源预留的批处理任务
NotBestEffort QoS 等级非 BestEffort 的 Pod(Burstable/Guaranteed) 保障生产级应用资源不被抢占
Terminating 设置了 spec.activeDeadlineSeconds 的 Pod 限制有运行时长上限的 Job/CronJob
NotTerminating 未设置 spec.activeDeadlineSeconds 的 Pod 限制常驻服务(Deployment/StatefulSet)
PriorityClass 指定了特定 PriorityClass 的 Pod 按优先级隔离资源池
最佳实践: 使用 NotBestEffort + NotTerminating 组合作用域,可以精确限制生产级常驻服务的资源总量,同时允许 BestEffort 的临时任务使用剩余资源。

2.3 核心字段解析

ResourceQuota 的 spec.hard 字段定义了资源上限。支持以下核心字段:

2.3.1 计算资源(Compute Resources)

字段名 单位 说明
requests.cpu Core(如 10) 所有 Pod 的 CPU 请求总和上限
requests.memory 字节(如 20Gi) 所有 Pod 的内存请求总和上限
limits.cpu Core(如 20) 所有 Pod 的 CPU 限制总和上限
limits.memory 字节(如 40Gi) 所有 Pod 的内存限制总和上限

2.3.2 存储资源(Storage Resources)

字段名 单位 说明
requests.storage 字节(如 100Gi) 所有 PVC 的存储请求总和上限
persistentvolumeclaims 整数(如 10) PVC 对象数量上限
<storage-class-name>.storageclass.storage.k8s.io/requests.storage 字节 指定 StorageClass 的存储请求总和上限

2.3.3 对象数量(Object Count Quotas)

字段名 说明
pods Pod 对象数量上限
services Service 对象数量上限
configmaps ConfigMap 对象数量上限
secrets Secret 对象数量上限
replicationcontrollers ReplicationController 对象数量上限
services.nodeports NodePort 类型 Service 数量上限
services.loadbalancers LoadBalancer 类型 Service 数量上限

2.4 完整 ResourceQuota 示例

以下 YAML 定义了一个生产级命名空间的资源配额:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    # 计算资源
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    # 存储资源
    requests.storage: "100Gi"
    persistentvolumeclaims: "10"
    # 对象数量
    pods: "50"
    services: "10"
    configmaps: "20"
    secrets: "20"
    services.nodeports: "5"
    services.loadbalancers: "2"
  scopeSelector:
    matchExpressions:
      - operator: In
        scopeName: PriorityClass
        values:
          - high-priority
注意: 若同时设置了 spec.hard 和 scopeSelector,则配额仅适用于匹配 scopeSelector 的资源。上例中,配额仅对 high-priority PriorityClass 的 Pod 生效。

2.5 配额冲突与调试

当配额被拒绝时,Kubernetes 会返回类似以下错误:

Error from server (Forbidden): pods "my-pod" is forbidden: exceeded quota: production-quota, requested: requests.memory=2Gi, used: requests.memory=19.5Gi, limited: requests.memory=20Gi

使用以下命令查看当前配额使用情况:

# 查看配额定义
kubectl get resourcequota -n production

# 查看配额使用详情
kubectl describe resourcequota production-quota -n production

# 查看命名空间资源使用量
kubectl get --raw /api/v1/namespaces/production/status | jq '.status'
ResourceQuota 核心字段分类 ResourceQuota 计算资源 存储资源 对象数量 requests.cpu / requests.memory limits.cpu / limits.memory requests.storage persistentvolumeclaims pods / services / configmaps secrets / services.nodeports 提示:对象数量配额可防止 API Server 因大量小对象而过载,建议生产环境至少配置 pods 和 services 配额。

2.6 配额设计原则

  • 先粗后细: 初期只配置 CPU/Memory 总量配额,后续根据实际使用情况增加对象数量配额。
  • 区分环境: 开发环境配额可宽松(如 requests.cpu=20),生产环境应严格(如 requests.cpu=10)。
  • 结合 LimitRange: 使用 LimitRange 设置 Pod 默认 requests/limits,避免未设置资源限制的 Pod 绕过配额。
  • 监控告警: 配置 Prometheus 监控配额使用率,当使用量超过 80% 时触发告警。
关键总结: ResourceQuota 是 Kubernetes 多租户资源隔离的基石。通过合理配置计算资源、存储资源和对象数量配额,可以有效防止单个命名空间资源滥用,保障集群整体稳定性。结合作用域(Scope)和 LimitRange,可以实现更精细的资源管控策略。