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 协同工作:
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> 提供人类可读的摘要。