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

目录

  1. 引子:从“资源管理的第三个层次”说起
  2. ResourceQuota
  3. LimitRange
  4. 总结与知识点一览表

引子:从“资源管理的第三个层次”说起

在第十期开篇,我们提出了 Kubernetes 资源管理的三个层次:

层次问题K8s 组件状态
监控层资源用了多少?Metrics Server✅ 第十期已讲
扩缩层资源不够怎么办?HPA✅ 第十期已讲
约束层如何防止超用?ResourceQuota / LimitRange本期讲解

在第十期中,我们通过 Metrics Server 获得了资源“可见性”,通过 HPA 实现了资源“自动调配”。但还有一个关键问题没有解决:如何防止某个命名空间或某个容器占用过多资源,影响集群中其他工作负载的正常运行?

ResourceQuota 和 LimitRange 的关系:

想象一下,你是一个公寓管理员(集群管理员),有很多个租户(命名空间)。你需要管理的是:

  • ResourceQuota 就像是 “整栋楼的用水用电额度” ——每个单元(命名空间)的总用水量(总 CPU/内存)不能超过某个限额。
  • LimitRange 就像是 “每户人家的水龙头规格” ——每家(每个容器)的水龙头不能太小(min)也不能太大(max),如果租户自己没装水龙头,管理员会给他一个标准的(default)。

两者分工明确:

  • ResourceQuota 管“总量”——防止一个租户用光整栋楼的资源
  • LimitRange 管“个体”——防止一个水龙头要么开不了要么爆水管

本期就来分别介绍这两个组件。

一句话概括本期的价值:ResourceQuota 让你“管住总量”,LimitRange 让你“定好规矩”——这就是集群资源管理的“安全网”和“标准尺”。

本期学习路径:

ResourceQuota(限制命名空间总资源用量)
    ↓
LimitRange(为单个容器设置默认资源值)
    ↓
request/limit 的配置实验

一、ResourceQuota

1.1 为什么需要 ResourceQuota?

在多租户或多人共享的 Kubernetes 集群中,一个常见的问题是:某个用户或团队可能会消耗过多的集群资源,导致其他用户的应用无法正常运行。

ResourceQuota(资源配额)正是为了解决这个问题而设计的。

核心作用:ResourceQuota 用于限制命名空间(Namespace) 中可以创建的资源总量,防止单个命名空间消耗过多集群资源。

ResourceQuota 的工作方式:

  1. 集群管理员为每个命名空间创建一个或多个 ResourceQuota 对象
  2. 用户在该命名空间下创建资源时,配额系统会实时检查资源使用情况
  3. 如果创建请求会导致资源用量超过配额限制,请求会被拒绝(HTTP 403)
  4. 配额限制是累加的——同一个命名空间中的多个 ResourceQuota 对象共同生效

1.2 配额类型

Kubernetes 的 ResourceQuota 可以限制两类资源:

类型说明示例
对象数量限制 Kubernetes 资源的数量pods、services、secrets、configmaps 等
计算资源限制物理或虚拟资源容量CPU、内存、存储容量

对象数量配额:

资源说明
podsPod 总数
servicesService 总数
secretsSecret 总数
configmapsConfigMap 总数
persistentvolumeclaimsPVC 总数
deployments.appsDeployment 总数
replicasets.appsReplicaSet 总数
jobs.batchJob 总数
cronjobs.batchCronJob 总数

实施对象数量配额可以提高 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

创建对象数量配额:

root@master30:~# kubectl create quota myquota --hard=pods=2,services=3,secrets=5,persistentvolumeclaims=10

查看 ResourceQuota:

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 文件创建:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: myquota
spec:
  hard:
    persistentvolumeclaims: "10"
    pods: "2"
    secrets: "5"
    services: "3"
测试配额效果
# 尝试创建 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

修改配额:

# 将 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 配额):

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):

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - name: web
    image: httpd
    ports:
    - containerPort: 80

结果:Pod 创建被拒绝

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):

apiVersion: v1
kind: ResourceQuota
metadata:
  name: myquota
spec:
  hard:
    requests.cpu: 1000m
    requests.memory: "2048Mi"

Pod 示例(requests 超过配额):

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - name: web
    image: httpd
    resources:
      requests:
        cpu: 2000m
        memory: 4096Mi

结果:Pod 创建被拒绝

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 在配额范围内):

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - name: web
    image: httpd
    resources:
      requests:
        cpu: 200m
        memory: 1024Mi
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资源说明
Containercpu、memory限定单个容器的 CPU/内存
Podcpu、memory限定 Pod 中所有容器 CPU/内存的总和
PersistentVolumeClaimstorage限定 PVC 申请的存储空间大小

关键理解:LimitRange 的作用对象是单个资源(一个容器、一个 Pod、一个 PVC),而 ResourceQuota 的作用对象是命名空间级别的资源总和。两者配合使用,形成完整的资源管理方案——LimitRange 管“个体”,ResourceQuota 管“总量”。

2.2 LimitRange 配置

LimitRange 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:

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:

apiVersion: v1
kind: Pod
metadata:
  name: stress
spec:
  containers:
  - name: stress
    image: progrium/stress
    args: ['-c','1']

查看 Pod 资源:

root@master30:~# kubectl apply -f pod-without-limits.yaml
root@master30:~# kubectl get pod stress -o yaml | grep -A6 resources
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 值

spec:
  containers:
  - name: web
    image: nginx
    resources:
      limits:
        cpu: 1.1
        memory: 1100Mi
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 值

spec:
  containers:
  - name: web
    image: nginx
    resources:
      limits:
        cpu: 60m
        memory: 60Mi
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

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 值

spec:
  containers:
  - name: web
    image: nginx
    resources:
      requests:
        cpu: 1600m
        memory: 600Mi
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 值

spec:
  containers:
  - name: web
    image: nginx
    resources:
      requests:
        cpu: 60m
        memory: 60Mi
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

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 的存储大小,适用于需要控制存储用量的场景。

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 对比

对比项ResourceQuotaLimitRange
作用范围命名空间级别(资源总量)单个资源级别(容器/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 常用命令速查

操作命令
创建 ResourceQuotakubectl create quota <name> --hard=<key>=<value>
查看 ResourceQuotakubectl get resourcequotas / kubectl describe quota <name>
修改 ResourceQuotakubectl patch resourcequotas <name> -p '{"spec":{"hard":{"pods":10}}}'
删除 ResourceQuotakubectl delete resourcequota <name>
创建 LimitRangekubectl apply -f limits.yaml
查看 LimitRangekubectl get limitranges / kubectl describe limitrange <name>
删除 LimitRangekubectl 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,再配 ResourceQuotaLimitRange 确保所有 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
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐