3. 资源配额(ResourceQuota)基础:Namespace级别资源限制的原理与YAML定义

在 Kubernetes 集群中,资源配额(ResourceQuota)是控制平面实施资源治理的核心策略对象。它作用于 Namespace 级别,为命名空间内的所有 Pod 和容器设定资源消耗的上限,防止单个应用或团队过度占用集群资源,从而保障多租户环境下的公平调度与稳定性。

3.1 资源配额的工作原理

ResourceQuota 通过准入控制器(Admission Controller)在资源创建或更新时进行校验。当用户尝试在命名空间内创建 Pod、Service、PersistentVolumeClaim 等对象时,Kubernetes API Server 会检查当前命名空间的资源使用量是否已超过配额限制。如果超过,请求将被拒绝,并返回错误信息。

核心机制: ResourceQuota 是 硬限制(Hard Limit),一旦达到配额上限,后续的资源创建请求将被立即拒绝,直到现有资源被释放或配额被提升。

配额可以限制两类资源:

  • 计算资源: CPU、内存(requests 和 limits)
  • 存储资源: 存储容量、PVC 数量
  • 对象数量: Pod、Service、ConfigMap、Secret 等 Kubernetes 对象的数量

3.2 ResourceQuota YAML 定义详解

以下是一个典型的 ResourceQuota 定义,展示了如何限制命名空间内的计算资源和对象数量:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: data-pipeline
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "3"
    configmaps: "10"
    secrets: "10"
字段 说明 示例值
requests.cpu 所有 Pod 的 CPU requests 总和上限 4(核心)
requests.memory 所有 Pod 的内存 requests 总和上限 8Gi
limits.cpu 所有 Pod 的 CPU limits 总和上限 8(核心)
limits.memory 所有 Pod 的内存 limits 总和上限 16Gi
pods 命名空间内允许的最大 Pod 数量 10
services 命名空间内允许的最大 Service 数量 5
persistentvolumeclaims 命名空间内允许的最大 PVC 数量 3
最佳实践: 在 Helm Chart 的 values.yaml 中定义配额参数,通过模板动态生成 ResourceQuota 对象,实现环境差异化配置。例如,开发环境使用较小配额,生产环境使用较大配额。

3.3 资源配额与 Pod 资源声明的关系

ResourceQuota 要求命名空间内的每个 Pod 必须显式声明资源 requests 和 limits。如果 Pod 未声明资源限制,且命名空间存在 ResourceQuota,则 Pod 创建将被拒绝。这一机制强制了资源声明的规范性。

以下 SVG 展示了 ResourceQuota 在 Pod 创建流程中的校验逻辑:

ResourceQuota 准入校验流程 ResourceQuota 准入校验流程 用户创建 Pod API Server 接收请求 准入控制器校验 ? 配额充足 → 创建成功 配额不足 → 拒绝请求 说明:准入控制器检查当前 Namespace 资源使用量 + 请求量 ≤ 配额上限 若 Pod 未声明 requests/limits,且命名空间存在 ResourceQuota,则直接拒绝

3.4 配额作用域(Scope)与精细化控制

ResourceQuota 支持通过 scopes 字段实现更精细的控制,允许针对特定类型的 Pod 设置不同的配额限制。常用的作用域包括:

作用域 描述 适用场景
BestEffort 仅限制 QoS 为 BestEffort 的 Pod 限制低优先级、无资源声明的测试 Pod
NotBestEffort 限制 QoS 非 BestEffort 的 Pod 保障生产级 Pod 的资源配额
Terminating 限制设置了 activeDeadlineSeconds 的 Pod 批处理任务(Job)的资源控制
NotTerminating 限制未设置 activeDeadlineSeconds 的 Pod 长期运行的服务(Deployment)

以下示例展示了如何为 NotTerminating 和 BestEffort 的 Pod 分别设置不同的配额:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: pods-high-priority
  namespace: data-pipeline
spec:
  hard:
    pods: "6"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
  scopes:
    - NotTerminating
    - NotBestEffort
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: pods-low-priority
  namespace: data-pipeline
spec:
  hard:
    pods: "4"
  scopes:
    - BestEffort
注意: 当使用作用域时,配额只对匹配该作用域的 Pod 生效。不匹配的 Pod 不受该配额限制。多个 ResourceQuota 对象可以共存于同一命名空间,Kubernetes 会累加所有匹配的配额限制。

3.5 配额监控与调试

部署 ResourceQuota 后,可以通过以下命令查看当前命名空间的资源使用情况:

# 查看命名空间配额定义
kubectl get resourcequota -n data-pipeline

# 查看配额使用详情
kubectl describe resourcequota compute-quota -n data-pipeline

# 输出示例:
# Name:            compute-quota
# Namespace:       data-pipeline
# Resource         Used  Hard
# --------         ---   ---
# requests.cpu     2     4
# requests.memory  4Gi   8Gi
# limits.cpu       4     8
# limits.memory    8Gi   16Gi
# pods             5     10

通过 Used 列可以快速判断当前资源消耗是否接近配额上限,为 Helm 部署时的资源规划提供数据支撑。

3.6 在 Helm Chart 中集成 ResourceQuota

在 Helm Chart 中,建议将 ResourceQuota 作为可选组件,通过 values.yaml 控制是否启用:

# values.yaml
resourceQuota:
  enabled: true
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"

对应的模板文件 templates/resourcequota.yaml:

{{- if .Values.resourceQuota.enabled }}
apiVersion: v1
kind: ResourceQuota
metadata:
  name: {{ include "my-chart.fullname" . }}-quota
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "my-chart.labels" . | nindent 4 }}
spec:
  hard:
    {{- toYaml .Values.resourceQuota.hard | nindent 4 }}
{{- end }}
Helm 集成建议: 将 ResourceQuota 与 Helm 的 --namespace 参数结合,确保配额对象始终部署到正确的命名空间。同时,在 Chart 的 README 中明确标注配额默认值,方便运维人员按需调整。