4. ResourceQuota实战
ResourceQuota 是 OpenShift 中作用于 Namespace 级别的资源总量约束对象。它和 LimitRange 的分工需要先厘清:LimitRange 管的是“单个 Pod 或容器默认给多少、最多给多少”,而 ResourceQuota 管的是“整个 Namespace 里所有对象加起来最多能用多少”。两者配合使用,才能既约束单点又约束总量。本节围绕一个名为 team-alpha 的 Namespace,完整走一遍配额定义、生效验证、超限行为和调整流程。
一、配额对象与约束维度
ResourceQuota 的约束分为两类。第一类是计算资源配额,如 requests.cpu、limits.cpu、requests.memory、limits.memory,它们统计的是 Namespace 内所有 Pod 的 requests/limits 之和。第二类是对象数量配额,如 pods、services、persistentvolumeclaims、configmaps、secrets 等,统计的是对象个数。
有一个关键前提:一旦 Namespace 中存在带 requests.cpu 或 limits.cpu 的 ResourceQuota,之后创建的 Pod 就必须显式声明对应的 requests/limits,否则会被拒绝。这是新手最容易踩的坑——配额不是“超了才拦”,而是“没声明就不让建”。
二、编写并应用配额
先创建 Namespace,再定义 ResourceQuota。以下 YAML 是本节使用的完整示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
services: "5"
persistentvolumeclaims: "4"
应用后查看配额状态:
oc apply -f team-alpha-quota.yaml
oc describe resourcequota team-alpha-quota -n team-alpha
describe 输出中会同时列出 Resource、Used、Hard 三列。刚创建时 Used 全为 0,Hard 即上面定义的值。这个 Used 是实时统计的,每次创建或删除对象都会刷新。
三、验证配额生效
验证分两步。第一步,创建一个未声明 requests/limits 的 Pod,观察是否被拒绝:
oc run test-nolimit --image=registry.access.redhat.com/ubi9/ubi-minimal \
--restart=Never -n team-alpha
预期返回类似 Error from server (Forbidden): pods "test-nolimit" is forbidden: failed quota: team-alpha-quota: must specify limits.cpu,limits.memory,requests.cpu,requests.memory。这说明配额已生效,且强制要求声明资源。
第二步,创建一个声明了资源但会超限的 Pod。假设当前 requests.cpu 已用 2.5,剩余 1.5,我们申请 2:
apiVersion: v1
kind: Pod
metadata:
name: test-over
namespace: team-alpha
spec:
containers:
- name: app
image: registry.access.redhat.com/ubi9/ubi-minimal
command: ["sleep", "3600"]
resources:
requests:
cpu: "2"
memory: 2Gi
limits:
cpu: "2"
memory: 4Gi
提交后会被拒绝,错误信息形如 exceeded quota: team-alpha-quota, requested: requests.cpu=2, used: requests.cpu=2500m, limited: requests.cpu=4。注意这里报的是“请求量 + 已用量 > 硬限制”,而不是“单个 Pod 太大”。
四、超限行为与常见误区
超限行为可以归纳为三点:
- 创建即拒绝:无论是 Pod、Service 还是 PVC,只要新增后总量超过 hard 值,API Server 直接返回 403 Forbidden。
- 已存在对象不受影响:调小配额不会驱逐已有 Pod,但会导致后续无法新建,直到用量降到新配额以下。
- 更新也可能被拦:如果修改已有 Pod 的 requests 使其总量超限,同样会被拒绝。
常见误区是认为“配额只对新建生效,改改就行”。实际上,如果 Namespace 已有配额且你删掉了某个 Pod 的 resources 字段,更新操作也会因“must specify”被拒绝。因此配额一旦启用,所有工作负载模板都必须带上资源声明。
五、配额调整流程
调整配额不是简单改数字,需要先评估再执行。推荐流程如下:
- 用
oc describe resourcequota -n team-alpha查看当前 Used 与 Hard 的差距。 - 确认要调整的维度,例如把 requests.cpu 从 4 提到 6。
- 直接
oc edit resourcequota team-alpha-quota -n team-alpha或重新 apply 修改后的 YAML。 - 再次 describe,确认 Hard 已更新且 Used 不变。
- 尝试创建之前被拒绝的 Pod,验证新配额下能否成功。
需要注意:调大配额通常立即生效;调小配额时,如果当前 Used 已高于新 Hard,配额对象本身可以保存成功,但 Namespace 会处于“超配额”状态,任何新建操作都会被拒绝,直到用量自然下降。因此调小前务必确认现有用量。
六、可直接使用的配额检查清单
下表可作为日常运维时的快速核对表,字段均对应真实配额维度:
| 检查项 | 命令 / 观察点 | 判断标准 |
|---|---|---|
| 配额是否存在 | oc get resourcequota -n <ns> | 至少一条记录 |
| CPU/内存用量 | oc describe resourcequota | Used < Hard,留有余量 |
| Pod 数量 | 同上,看 pods 行 | Used 接近 Hard 时预警 |
| Service 数量 | 同上,看 services 行 | 避免因配额阻塞发布 |
| PVC 数量 | 同上,看 persistentvolumeclaims 行 | 结合存储容量规划 |
| 工作负载是否声明资源 | 抽查 Deployment/Pod YAML | 必须含 requests 与 limits |
把这张清单固化到 CI 流水线或命名空间开通流程中,可以在对象创建前就发现配额风险,而不是等到发布失败才排查。ResourceQuota 的价值不在于“限制”,而在于让 Namespace 的资源账目始终清晰可查、可预期。