kubernetes(K8s)学习笔记(第十一期):集群资源与弹性(下篇):资源配额与限制------ResourceQuota + LimitRange
本笔记为 Kubernetes 系列第十一期,聚焦集群资源配额与限制。涵盖:ResourceQuota 命名空间资源配额(对象数量/计算资源)、LimitRange 容器资源默认值与限制范围、request/limit 的配置实验。所有命令和 YAML 示例均已经过整理和注释。全文约 4100 字 ,包含 15 个 YAML 示例 、35+ 命令示例 和 9 张对比表格,是 Kubernetes 集群资源管理的重要补充。
更多kubernetes系列知识:kubernetes从入门到进阶
知识衔接:上一期:kubernetes(K8s)学习笔记(第十期):集群资源与弹性(上篇):监控与自动扩缩------Metrics Server + HPA
--- Compiled and Authored by Whisky --- July 2 nd, 2026
目录
- 引子:从"资源管理的第三个层次"说起
- ResourceQuota
- LimitRange
- 总结与知识点一览表
引子:从"资源管理的第三个层次"说起
在第十期开篇,我们提出了 Kubernetes 资源管理的三个层次:
| 层次 | 问题 | K8s 组件 | 状态 |
|---|---|---|---|
| 监控层 | 资源用了多少? | Metrics Server | ✅ 第十期已讲 |
| 扩缩层 | 资源不够怎么办? | HPA | ✅ 第十期已讲 |
| 约束层 | 如何防止超用? | ResourceQuota / LimitRange | 本期讲解 |
在第十期中,我们通过 Metrics Server 获得了资源"可见性",通过 HPA 实现了资源"自动调配"。但还有一个关键问题没有解决:如何防止某个命名空间或某个容器占用过多资源,影响集群中其他工作负载的正常运行?
ResourceQuota 和 LimitRange 的关系:
想象一下,你是一个公寓管理员(集群管理员),有很多个租户(命名空间)。你需要管理的是:
- ResourceQuota 就像是 "整栋楼的用水用电额度" ------每个单元(命名空间)的总用水量(总 CPU/内存)不能超过某个限额。
- LimitRange 就像是 "每户人家的水龙头规格" ------每家(每个容器)的水龙头不能太小(min)也不能太大(max),如果租户自己没装水龙头,管理员会给他一个标准的(default)。
两者分工明确:
- ResourceQuota 管"总量"------防止一个租户用光整栋楼的资源
- LimitRange 管"个体"------防止一个水龙头要么开不了要么爆水管
本期就来分别介绍这两个组件。
一句话概括本期的价值:ResourceQuota 让你"管住总量",LimitRange 让你"定好规矩"------这就是集群资源管理的"安全网"和"标准尺"。
本期学习路径:
text
ResourceQuota(限制命名空间总资源用量)
↓
LimitRange(为单个容器设置默认资源值)
↓
request/limit 的配置实验
一、ResourceQuota
1.1 为什么需要 ResourceQuota?
在多租户或多人共享的 Kubernetes 集群中,一个常见的问题是:某个用户或团队可能会消耗过多的集群资源,导致其他用户的应用无法正常运行。
ResourceQuota(资源配额)正是为了解决这个问题而设计的。
核心作用 :ResourceQuota 用于限制命名空间(Namespace) 中可以创建的资源总量,防止单个命名空间消耗过多集群资源。
ResourceQuota 的工作方式:
- 集群管理员为每个命名空间创建一个或多个 ResourceQuota 对象
- 用户在该命名空间下创建资源时,配额系统会实时检查资源使用情况
- 如果创建请求会导致资源用量超过配额限制,请求会被拒绝(HTTP 403)
- 配额限制是累加的------同一个命名空间中的多个 ResourceQuota 对象共同生效
1.2 配额类型
Kubernetes 的 ResourceQuota 可以限制两类资源:
| 类型 | 说明 | 示例 |
|---|---|---|
| 对象数量 | 限制 Kubernetes 资源的数量 | pods、services、secrets、configmaps 等 |
| 计算资源 | 限制物理或虚拟资源容量 | CPU、内存、存储容量 |
对象数量配额:
| 资源 | 说明 |
|---|---|
pods |
Pod 总数 |
services |
Service 总数 |
secrets |
Secret 总数 |
configmaps |
ConfigMap 总数 |
persistentvolumeclaims |
PVC 总数 |
deployments.apps |
Deployment 总数 |
replicasets.apps |
ReplicaSet 总数 |
jobs.batch |
Job 总数 |
cronjobs.batch |
CronJob 总数 |
实施对象数量配额可以提高 Kubernetes 集群稳定性,避免 etcd 数据库无限增长,还可以避免占用节点上其他功能资源(如 IP 地址)。
计算资源配额:
| 资源名称 | 说明 |
|---|---|
requests.cpu |
所有 Pod 的 CPU 请求总和上限 |
requests.memory |
所有 Pod 的内存请求总和上限 |
limits.cpu |
所有 Pod 的 CPU 限制总和上限 |
limits.memory |
所有 Pod 的内存限制总和上限 |
requests.storage |
所有 PVC 的存储请求总和上限 |
单位说明:
- CPU:1 CPU 核心 = 1000m(millicores)
- memory :支持两种进制
- Ki | Mi | Gi | Ti:1024 进制(如 1Gi = 1024Mi)
- k | M | G | T:1000 进制(如 1G = 1000M)
- 默认单位是字节
1.3 配额管理
创建 ResourceQuota
创建对象数量配额:
bash
root@master30:~# kubectl create quota myquota --hard=pods=2,services=3,secrets=5,persistentvolumeclaims=10
查看 ResourceQuota:
bash
root@master30:~# kubectl get resourcequotas
NAME AGE REQUEST LIMIT
myquota 10s persistentvolumeclaims: 0/10, pods: 0/2, secrets: 1/5, services: 0/3
root@master30:~# kubectl describe quota myquota
Name: myquota
Namespace: quota
Resource Used Hard
-------- ---- ----
persistentvolumeclaims 0 10
pods 0 2
secrets 1 5
services 0 3
通过 YAML 文件创建:
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: myquota
spec:
hard:
persistentvolumeclaims: "10"
pods: "2"
secrets: "5"
services: "3"
测试配额效果
bash
# 尝试创建 3 个副本的 Deployment(配额限制 pods=2)
root@master30:~# kubectl create deployment web --image=nginx --replicas=3
deployment.apps/web created
# 查看 Pod 状态------只有 2 个 Pod 成功创建
root@master30:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-96d5df5c8-dl7qk 1/1 Running 0 40s
web-96d5df5c8-j7fhh 1/1 Running 0 40s
# 第 3 个 Pod 因配额限制创建失败
root@master30:~# kubectl describe rs web-96d5df5c8
...
Warning FailedCreate replicaset/web-96d5df5c8 Error creating: pods "web-96d5df5c8-xg6c9" is forbidden: exceeded quota: myquota, requested: pods=1, used: pods=2, limited: pods=2
修改配额:
bash
# 将 pod 配额从 2 增加到 10
root@master30:~# kubectl patch resourcequotas myquota -p '{"spec":{"hard":{"pods":10}}}'
# 重新扩展 ReplicaSet
root@master30:~# kubectl scale rs web-96d5df5c8 --replicas=3
# 验证------第 3 个 Pod 成功创建
root@master30:~# kubectl get pods | wc -l
4
1.4 计算资源配额
如果命名空间启用了计算资源配额(如 requests.cpu、requests.memory),用户必须为 Pod 中的容器设定 request 和 limit 值,否则配额系统将拒绝 Pod 的创建。
为什么必须指定 request 和 limit? 配额系统需要知道每个 Pod"预定"了多少资源,才能准确计算当前已使用的资源量。如果 Pod 没有声明资源请求,配额系统无法判断该 Pod 会占用多少资源,因此只能拒绝创建。
实验:未指定计算资源
配额示例(设置了 CPU 和内存的 request/limit 配额):
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: myquota
spec:
hard:
persistentvolumeclaims: "10"
pods: "2"
secrets: "5"
services: "3"
requests.cpu: 1000m
requests.memory: "2048Mi"
limits.cpu: 1000m
limits.memory: "2048Mi"
Pod 示例(未指定 resources):
yaml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: httpd
ports:
- containerPort: 80
结果:Pod 创建被拒绝
bash
root@master30:~# kubectl apply -f pod-without-quota.yaml
Error from server (Forbidden): error when creating "pod-without-quota.yaml": pods "web" is forbidden: failed quota: myquota: must specify limits.cpu for: web; limits.memory for: web; requests.cpu for: web; requests.memory for: web
关键理解 :一旦命名空间配置了计算资源配额,所有 Pod 都必须显式指定
resources.requests和resources.limits。这是强制性的,不是可选的。
实验:请求超过配额上限
配额示例(只限制 requests):
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: myquota
spec:
hard:
requests.cpu: 1000m
requests.memory: "2048Mi"
Pod 示例(requests 超过配额):
yaml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: httpd
resources:
requests:
cpu: 2000m
memory: 4096Mi
结果:Pod 创建被拒绝
bash
root@master30:~# kubectl apply -f pod-request-1.yaml
Error from server (Forbidden): error when creating "pod-request-1.yaml": pods "web" is forbidden: exceeded quota: myquota, requested: requests.cpu=2,requests.memory=4Gi, used: requests.cpu=0,requests.memory=0, limited: requests.cpu=1,requests.memory=2Gi
Pod 示例(requests 在配额范围内):
yaml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: web
image: httpd
resources:
requests:
cpu: 200m
memory: 1024Mi
bash
root@master30:~# kubectl apply -f pod-request-2.yaml
root@master30:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 43s
# 查看配额使用情况
root@master30:~# kubectl describe resourcequotas myquota
Name: myquota
Namespace: quota
Resource Used Hard
-------- ---- ----
requests.cpu 200m 1
requests.memory 1Gi 2Gi
二、LimitRange
2.1 为什么需要 LimitRange?
在前面的实验中我们了解到,如果命名空间设置了计算资源配额,所有 Pod 都必须指定 request 和 limit。但是,如果用户忘记指定这些值,配额系统会直接拒绝 Pod 创建,导致用户体验不佳。
LimitRange 的作用 :为命名空间中的 Pod/容器设置默认的 request 和 limit 值,从而解决这个问题。
核心作用 :LimitRange 用于限定单个 Pod 或容器的资源请求和限制的默认值、最小值和最大值。
LimitRange 支持的资源类型:
| Type | 资源 | 说明 |
|---|---|---|
Container |
cpu、memory | 限定单个容器的 CPU/内存 |
Pod |
cpu、memory | 限定 Pod 中所有容器 CPU/内存的总和 |
PersistentVolumeClaim |
storage | 限定 PVC 申请的存储空间大小 |
关键理解 :LimitRange 的作用对象是单个资源 (一个容器、一个 Pod、一个 PVC),而 ResourceQuota 的作用对象是命名空间级别的资源总和。两者配合使用,形成完整的资源管理方案------LimitRange 管"个体",ResourceQuota 管"总量"。
2.2 LimitRange 配置
LimitRange YAML 示例:
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: mylimit
spec:
limits:
- type: Container
max:
memory: 1024Mi
cpu: 1
min:
memory: 128Mi
cpu: 100m
default:
memory: 512Mi
cpu: 500m
defaultRequest:
memory: 256Mi
cpu: 200m
| 字段 | 说明 |
|---|---|
default |
容器未指定 limit 时的默认值(上限) |
defaultRequest |
容器未指定 request 时的默认值 |
max |
容器可使用的资源最大值 |
min |
容器可使用的资源最小值 |
重要约束 :min <= defaultRequest <= default <= max
查看 LimitRange:
bash
root@master30:~# kubectl apply -f limits.yaml
root@master30:~# kubectl get limitranges
NAME CREATED AT
mylimit 2021-09-09T04:09:15Z
root@master30:~# kubectl describe limitranges mylimit
Name: mylimit
Namespace: quota
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 1 200m 500m -
Container memory 128Mi 1Gi 256Mi 512Mi -
2.3 实验:未指定 resources
实验目标:创建不指定资源的 Pod,观察 LimitRange 自动填充默认值。
Pod YAML:
yaml
apiVersion: v1
kind: Pod
metadata:
name: stress
spec:
containers:
- name: stress
image: progrium/stress
args: ['-c','1']
查看 Pod 资源:
bash
root@master30:~# kubectl apply -f pod-without-limits.yaml
root@master30:~# kubectl get pod stress -o yaml | grep -A6 resources
yaml
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 200m
memory: 256Mi
结论:未指定 resources 时,LimitRange 自动填充了默认值(default 和 defaultRequest)。
2.4 实验:只指定 limit 值
结论 :只指定 limit 值时,必须满足 min < limit < max;request 会自动设置为与 limit 相同的值,而不是 defaultRequest。
示例 2-1:limit 值大于 max 值
yaml
spec:
containers:
- name: web
image: nginx
resources:
limits:
cpu: 1.1
memory: 1100Mi
bash
root@master30:~# kubectl apply -f limit.yml
Error from server (Forbidden): error when creating "limit.yml": pods "web" is forbidden: [maximum cpu usage per Container is 1, but limit is 1100m, maximum memory usage per Container is 1Gi, but limit is 1181116006400m]
示例 2-2:limit 值小于 min 值
yaml
spec:
containers:
- name: web
image: nginx
resources:
limits:
cpu: 60m
memory: 60Mi
bash
root@master30:~# kubectl apply -f limit.yml
Error from server (Forbidden): error when creating "limit.yml": pods "web" is forbidden: [minimum cpu usage per Container is 100m, but request is 60m, minimum memory usage per Container is 128Mi, but request is 60Mi]
示例 2-3:min < limit < max
yaml
spec:
containers:
- name: web
image: nginx
resources:
limits:
cpu: 600m
memory: 600Mi
结论:
- 创建的容器 limits 值必须满足:
min < 指定的 limit < max - 当只指定 limits 值时,requests 值与 limits 值保持一致,而不是 defaultRequest
2.5 实验:只指定 request 值
结论 :只指定 request 值时,必须满足 min < request < limit;limit 会自动使用 default 值。
示例 3-1:request 大于 max 值
yaml
spec:
containers:
- name: web
image: nginx
resources:
requests:
cpu: 1600m
memory: 600Mi
bash
root@master30:~# kubectl apply -f limit.yml
The Pod "web" is invalid:
* spec.containers[0].resources.requests: Invalid value: "1600m": must be less than or equal to cpu limit
示例 3-2:request 小于 min 值
yaml
spec:
containers:
- name: web
image: nginx
resources:
requests:
cpu: 60m
memory: 60Mi
bash
root@master30:~# kubectl apply -f limit.yml
Error from server (Forbidden): error when creating "limit.yml": pods "web" is forbidden: [minimum cpu usage per Container is 100m, but request is 60m, minimum memory usage per Container is 128Mi, but request is 60Mi]
示例 3-3:min < request < limit
yaml
spec:
containers:
- name: web
image: nginx
resources:
requests:
cpu: 400m
memory: 400Mi
结论:
- 创建的容器 requests 值必须满足:
min < requests < limits - 当只指定 requests 值时,limits 值与 default 值保持一致
2.6 LimitRange for PVC(补充)
LimitRange 还可以限制 PVC 的存储大小,适用于需要控制存储用量的场景。
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: storagelimits
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 2Gi
min:
storage: 1Gi
作用:限制该命名空间中 PVC 申请的存储大小必须在 1Gi 到 2Gi 之间。
三、总结与知识点一览表
3.1 回到"资源管理的第三个层次"
在开篇的引子中,我们提出了资源管理的三个层次。至此,三个层次已经全部讲完:
| 层次 | 问题 | K8s 组件 | 状态 |
|---|---|---|---|
| 监控层 | 资源用了多少? | Metrics Server | ✅ 第十期已讲 |
| 扩缩层 | 资源不够怎么办? | HPA | ✅ 第十期已讲 |
| 约束层 | 如何防止超用? | ResourceQuota / LimitRange | ✅ 本期已讲 |
一句话回顾本期:我们通过 ResourceQuota 实现了"管住总量",通过 LimitRange 实现了"定好规矩"------这就是集群资源管理的"安全网"和"标准尺"。
3.2 ResourceQuota vs LimitRange 对比
| 对比项 | ResourceQuota | LimitRange |
|---|---|---|
| 作用范围 | 命名空间级别(资源总量) | 单个资源级别(容器/Pod/PVC) |
| 控制内容 | 资源用量的上限 | 资源请求的默认值、最小值和最大值 |
| 主要目的 | 防止命名空间超用 | 防止单个容器超用或未指定资源 |
| 是否强制 | ✅ 强制(超限则拒绝) | ✅ 强制(不符合 min/max 则拒绝) |
| 两者关系 | 管"总量" | 管"个体" |
3.3 核心配置字段速查
| 字段 | 含义 | 适用对象 |
|---|---|---|
max |
资源最大值 | LimitRange |
min |
资源最小值 | LimitRange |
default |
默认 limit 值 | LimitRange |
defaultRequest |
默认 request 值 | LimitRange |
hard |
配额硬限制 | ResourceQuota |
requests.cpu/memory |
资源请求配额 | ResourceQuota |
limits.cpu/memory |
资源限制配额 | ResourceQuota |
3.4 常用命令速查
| 操作 | 命令 |
|---|---|
| 创建 ResourceQuota | kubectl create quota <name> --hard=<key>=<value> |
| 查看 ResourceQuota | kubectl get resourcequotas / kubectl describe quota <name> |
| 修改 ResourceQuota | kubectl patch resourcequotas <name> -p '{"spec":{"hard":{"pods":10}}}' |
| 删除 ResourceQuota | kubectl delete resourcequota <name> |
| 创建 LimitRange | kubectl apply -f limits.yaml |
| 查看 LimitRange | kubectl get limitranges / kubectl describe limitrange <name> |
| 删除 LimitRange | kubectl delete limitrange <name> |
3.5 配额与限制协同工作示意图
text
┌─────────────────────────────────────────────────────────────┐
│ 命名空间 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ResourceQuota(总量天花板) │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ Pod 1(LimitRange 管个体) │ │ │
│ │ │ request: 200m CPU / 256Mi 内存 │ │ │
│ │ │ limit: 500m CPU / 512Mi 内存 │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ Pod 2(LimitRange 管个体) │ │ │
│ │ │ request: 200m CPU / 256Mi 内存 │ │ │
│ │ │ limit: 500m CPU / 512Mi 内存 │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ Pod 3(LimitRange 管个体) │ │ │
│ │ │ request: 200m CPU / 256Mi 内存 │ │ │
│ │ │ limit: 500m CPU / 512Mi 内存 │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ │ 总 Request: 600m CPU / 768Mi 内存 │ │
│ │ 总 Limit: 1500m CPU / 1536Mi 内存 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.6 常见错误排查
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
Pod 创建失败,提示 exceeded quota |
命名空间配额已用尽 | 检查配额使用情况,删除不必要资源或提高配额 |
Pod 创建失败,提示 must specify limits.cpu |
命名空间有配额但 Pod 未指定 resources | 为 Pod 添加 resources 配置,或配置 LimitRange 默认值 |
Pod 创建失败,提示 minimum cpu usage is xxx |
资源值小于 LimitRange 的 min 值 | 调整资源值到 min 以上 |
Pod 创建失败,提示 maximum cpu usage is xxx |
资源值大于 LimitRange 的 max 值 | 调整资源值到 max 以下 |
kubectl describe quota 显示 Used 接近 Hard |
配额即将耗尽 | 提前规划扩容或清理资源 |
3.7 生产环境最佳实践
| 实践 | 说明 |
|---|---|
| 先配 LimitRange,再配 ResourceQuota | LimitRange 确保所有 Pod 都有 request/limit,ResourceQuota 才能有效工作 |
| 为每个命名空间设置合理的配额 | 根据团队规模和应用需求,设置合理的 CPU/内存配额 |
| 定期审查配额使用情况 | 使用 kubectl describe quota 定期检查配额使用率 |
| 预留系统资源 | 不要将集群所有资源都分配给配额,为系统组件预留一部分 |
| 配额不是越多越好 | 合理的配额有助于提高资源利用率,避免浪费 |
下一期预告:Kubernetes(K8s)学习笔记(第十二期):集群健康与安全------探针 + 认证授权。涵盖:Health Check(liveness/readiness/startup 探针)、认证管理(X509 证书)、授权管理(RBAC)、服务账户(ServiceAccount)。
--- Compiled and Authored by Whisky --- July 2 nd, 2026