ResourceQuota用于在命名空间级别硬性限制资源总量,仅在创建新资源时拦截超额申请,不预留资源、不影响已运行Pod;启用requests配额时,所有新建Pod必须显式声明resources.requests,否则被拒绝。

ResourceQuota 不是用来“保证资源可用”,而是用来“拒绝超额申请”——它不会预留资源,也不会影响已运行的 Pod,只在创建新资源时做硬性拦截。
ResourceQuota 的生效前提:必须带 requests/limits
如果命名空间启用了 requests.cpu 或 requests.memory 配额,所有新建 Pod(包括 Deployment、StatefulSet 等控制器创建的底层 Pod)都必须显式声明 resources.requests。否则 Admission Controller 会直接拒绝,报错类似:
error: failed to create resource: Forbidden: exceeded quota: team-alpha-quota, requested: requests.memory=1Gi, used: requests.memory=0, limited: requests.memory=128Gi
常见踩坑点:
- 忘记给容器写
resources字段,尤其是用 Helm chart 或旧模板部署时 - 只写了
limits没写requests,而配额规则检查的是requests总和(如requests.memory) - 用
kubectl run临时调试 Pod,没加--requests参数,被静默拒绝
配额对象里 hard 字段的实际含义
hard 是总量上限,不是“最小保障”,也不是“节点级预留”。比如这个配置:
spec:
hard:
requests.memory: "64Gi"
requests.cpu: "16"
requests.nvidia.com/gpu: "2"
它表示该命名空间下所有 Pod 的 requests 值加起来不能超过这些数。但要注意:
- 即使集群空闲,只要当前已用
requests.memory达到 64Gi,新 Pod 就无法创建 - 如果某 Pod 申请了
requests.memory: 32Gi,但节点只剩 24Gi 可分配,调度失败,但配额检查仍通过——配额不关心是否真能调度成功 -
limits.memory和limits.cpu可单独配额,但实际中很少用;绝大多数场景只限制requests
为什么 ResourceQuota + LimitRange 要一起用
ResourceQuota 控制“总量”,LimitRange 控制“单个 Pod 的默认值和边界”。两者配合才能避免漏防:
- 只设 ResourceQuota:用户可能提交一个没写
resources的 Pod,被拒;也可能写一个requests.memory: 1Mi的 Pod,轻松绕过总量控制(因为太小,加一堆也能凑不满限额) - 只设 LimitRange:能强制补默认值,但无法阻止用户故意写超大
requests(比如直接写requests.memory: 60Gi) - 推荐组合:
LimitRange设默认requests和最大limits,ResourceQuota设命名空间总上限
例如,LimitRange 可防止用户漏写 resources:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-alpha
spec:
limits:
- default:
memory: 2Gi
cpu: 500m
defaultRequest:
memory: 1Gi
cpu: 250m
type: Container
排查配额拒绝时的关键命令
当创建失败,先确认是不是配额问题:
- 查当前命名空间的配额状态:
kubectl get resourcequota -n team-alpha -o wide - 看已用/剩余量:
kubectl describe resourcequota team-alpha-quota -n team-alpha,重点关注Used和Hard行 - 检查具体哪个资源卡住了:
kubectl get pods -n team-alpha --show-labels,再结合kubectl top pods -n team-alpha看真实用量(注意:top 显示的是实际使用,不是 requests) - 创建失败时,错误信息里一般会明确指出违反哪条
hard规则,比如exceeded quota: requests.cpu
真正容易被忽略的是:ResourceQuota 对已存在的 Pod 完全无感,它只管“新增”。所以扩容、滚动更新、自动伸缩触发的新 Pod 才受控,老 Pod 即使内存泄漏吃光节点,配额也不会干预。











