kubernetes(K8s)学习笔记(第十一期):集群资源与弹性(下篇):资源配额与限制——ResourceQuota + LimitRange

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 让你"定好规矩"------这就是集群资源管理的"安全网"和"标准尺"。

本期学习路径

text 复制代码
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、内存、存储容量

对象数量配额

资源 说明
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.cpurequests.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.requestsresources.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