2. Kubernetes 资源配额基础:ResourceQuota 对象详解、LimitRange 对象详解、命名空间级别的资源管控
2.1 为什么需要命名空间级别的资源管控?
在 Kubernetes 多租户或团队共享集群的场景中,如果没有资源配额约束,单个命名空间或应用可能耗尽集群全部 CPU/内存,导致其他服务不可用。资源管控的核心目标是:公平分配、容量规划、成本核算、稳定性保障。
Kubernetes 提供两个原生 API 对象来实现命名空间级别的资源管控:
- ResourceQuota:限制命名空间内所有 Pod/Container 的资源总量上限(硬配额)。
- LimitRange:为命名空间内未显式设置资源请求/限制的 Pod 或 Container 提供默认值,并约束单个 Pod/Container 的资源上下界。
核心原则: ResourceQuota 控制“总量”,LimitRange 控制“个体”。两者配合使用才能构建完整的资源治理体系。
2.2 ResourceQuota 对象详解
2.2.1 核心概念与作用域
ResourceQuota 是一个命名空间级别的 API 对象,定义了一组资源配额约束。当命名空间内的资源使用量超过配额时,Kubernetes API Server 会拒绝后续的创建请求(Pod、PVC、Service 等)。
ResourceQuota 支持三种作用域(Scope):
| 作用域(Scope) | 含义 | 典型场景 |
|---|---|---|
BestEffort |
仅统计 QoS 为 BestEffort 的 Pod | 限制低优先级批处理任务 |
NotBestEffort |
统计 QoS 非 BestEffort 的 Pod(Burstable/Guaranteed) | 保障生产级服务的资源 |
Terminating / NotTerminating |
按 Pod 是否设置 activeDeadlineSeconds 区分 |
区分长期服务与一次性任务 |
2.2.2 可配资源类型
ResourceQuota 可以限制以下三类资源:
- 计算资源:
requests.cpu、requests.memory、limits.cpu、limits.memory - 存储资源:
requests.storage、persistentvolumeclaims、特定 StorageClass 的存储(如requests.storage/ssd) - 对象数量:
pods、services、configmaps、secrets、replicationcontrollers、resourcequotas等
2.2.3 示例:ResourceQuota YAML
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-a
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
persistentvolumeclaims: "5"
requests.storage: "100Gi"
关键行为: 当命名空间内所有 Pod 的
requests.cpu 总和达到 4 核时,后续任何 Pod 创建请求都会被拒绝,直到有 Pod 被删除释放资源。
2.2.4 配额评估与准入控制
ResourceQuota 的评估发生在 API Server 的准入控制阶段(Admission Control)。每次创建/更新 Pod 时,API Server 会计算当前命名空间内所有同类资源的累计使用量,加上新请求的资源量,与配额上限比较。若超出则返回 403 Forbidden。
使用 kubectl describe resourcequota compute-quota -n team-a 可以查看当前使用量与配额上限的对比:
Name: compute-quota
Namespace: team-a
Resource Used Hard
-------- ---- ----
limits.cpu 3 8
limits.memory 6Gi 16Gi
pods 12 20
requests.cpu 2 4
requests.memory 4Gi 8Gi
2.3 LimitRange 对象详解
2.3.1 为什么需要 LimitRange?
ResourceQuota 只限制总量,但无法约束单个 Pod/Container 的资源规格。如果某个团队创建了一个请求 4 核 CPU 的 Pod,而配额总量只有 4 核,其他 Pod 将无法调度。LimitRange 解决了以下问题:
- 为未设置资源请求/限制的 Pod 提供默认值(Default)。
- 限制单个 Container 或 Pod 的资源上下界(Min/Max)。
- 约束 PVC 的存储请求范围。
2.3.2 LimitRange 的四种限制类型
| 类型(Type) | 作用对象 | 可配字段 |
|---|---|---|
Container |
Pod 内的每个 Container | Min, Max, Default, DefaultRequest, MaxLimitRequestRatio |
Pod |
Pod 级别(所有 Container 总和) | Min, Max |
PersistentVolumeClaim |
PVC 的存储请求 | Min, Max |
2.3.3 示例:LimitRange YAML
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
namespace: team-a
spec:
limits:
- type: Container
max:
cpu: "2"
memory: "4Gi"
min:
cpu: "100m"
memory: "128Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
maxLimitRequestRatio:
cpu: "4"
注意:
maxLimitRequestRatio 用于限制 limits 与 requests 的比例。例如 ratio=4 表示 limits.cpu / requests.cpu ≤ 4,防止过度超卖。
2.3.4 LimitRange 的准入控制行为
当 Pod 创建时,LimitRange 的准入控制器会按以下顺序处理:
- 如果 Container 未设置
resources.requests,则使用defaultRequest。 - 如果 Container 未设置
resources.limits,则使用default。 - 如果 Container 设置的
requests或limits超出min/max范围,则拒绝创建。 - 如果
limits/requests比例超过maxLimitRequestRatio,则拒绝创建。
2.4 ResourceQuota 与 LimitRange 的协同关系
下图展示了在命名空间内,ResourceQuota 与 LimitRange 如何协同工作:
2.5 最佳实践与避坑指南
生产级配置建议:
- 始终为每个命名空间同时配置 ResourceQuota 和 LimitRange,缺一不可。
- ResourceQuota 的
requests应设置为集群容量的 60%~80%,预留缓冲。 - LimitRange 的
default和defaultRequest应匹配团队典型工作负载。 - 使用
kubectl describe quota和kubectl describe limitrange定期审计。
常见陷阱:
- 只配 ResourceQuota 不配 LimitRange → 未设置资源限制的 Pod 可能被拒绝(因为配额无法计算)。
- LimitRange 的
min设置过高 → 小规格 Pod 无法创建。 - ResourceQuota 的
limits与requests比例失衡 → 导致资源碎片。 - 忘记为 StorageClass 设置配额 → 存储资源可能被单个 PVC 耗尽。