首页 / Kubernetes (k8s) 入门教程 / 资源配额

Kubernetes (k8s) 入门教程

资源配额

本教程共 65 篇 · 第 42 篇 · 更新于 2026-08-14 · 约 15 分钟阅读

Kubernetes资源配额ResourceQuotaLimitRange命名空间限制

本节目标:理解 ResourceQuota 和 LimitRange 各自解决什么问题,会用 YAML 给命名空间设总配额和单对象上下限,并知道两者怎么配合,避免一个 Pod 吃光整个团队资源。

前面几章都在讲 Pod 怎么调度、怎么落点。可在真实集群里,还有一关:资源不能让人乱用。一个团队把节点 CPU 全占满,别的团队就没法干活了。这一章的两样东西,专门管”用量上限”。

42-1 为什么需要配额

很多团队共用一套集群。要是没有约束,哪个组手快、敢开大副本,就把资源抢光了。资源配额就是管理员手里的”公平尺”。

它工作在命名空间层面。不同团队待在不同命名空间,每个命名空间各发一份额度。谁超了谁被拦,互不影响。这种隔离可以用 RBAC 等鉴权机制来强制执行。

配额管的是”总量”。比如 A 团队最多用 20 GiB 内存、10 核 CPU,B 团队最多 10 GiB、4 核。剩下的留作预备,谁都不许超。

Note

资源配额由 ResourceQuota 对象定义。一个命名空间里至少有一个 ResourceQuota,配额就对这个命名空间生效了。配额机制在多数发行版里默认开启。

42-2 ResourceQuota 怎么工作

ResourceQuota 的工作方式很直接。管理员为每个命名空间建至少一个 ResourceQuota。用户在命名空间里创建 Pod、Service 等资源时,配额系统实时记账,确保总消耗不突破硬性上限。

如果用户创建或更新资源时踩了配额线,控制平面直接拒绝,返回 HTTP 状态码 403 Forbidden,并附上违反的是哪条约束。

这里有个坑:一旦命名空间对 cpumemory 启用了配额,用户建 Pod 时必须写清 requests 或 limits,否则配额系统可能拒绝接纳。好在可以用 LimitRange 自动补默认值,后文会讲。

Warning

你多半不会直接手建 Pod,而是建 Deployment 这类工作负载对象。配额只拦 Pod,不拦 Deployment。所以一个超量的 Deployment 可能”创建成功”,但它管的那堆 Pod 起不来。这时用 kubectl describe 看 Deployment 状态,能发现卡在哪。

42-3 计算资源的配额

最常见的配额就是限制 CPU、内存这类计算资源的总量。ResourceQuota 支持这些资源名:

  • requests.cpu:所有非终止状态 Pod 的 CPU 请求之和上限。
  • requests.memory:所有非终止状态 Pod 的内存请求之和上限。
  • limits.cpu:所有非终止状态 Pod 的 CPU 限制之和上限。
  • limits.memory:所有非终止状态 Pod 的内存限制之和上限。
  • cpumemory:分别等同于 requests.cpurequests.memory
  • hugepages-<size>:指定尺寸巨页的请求总数上限。

一个实际例子,给命名空间设计算资源配额:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
spec:
  hard:
    requests.cpu: "1"
    requests.memory: "1Gi"
    limits.cpu: "2"
    limits.memory: "2Gi"
    requests.nvidia.com/gpu: 4

这里的 hard 就是硬性上限。最后一行 requests.nvidia.com/gpu: 4 是扩展资源(如 GPU)的配额。扩展资源不允许超卖,所以只配 requests. 前缀即可,没必要同时写 requests 和 limits。

建好后用 kubectl describe quota compute-resources 能看到 Used 和 Hard 两列,实时反映占用情况。

42-4 存储与对象数量的配额

除了算力和内存,配额还能管存储和”能建多少对象”。

存储相关:

  • requests.storage:所有 PVC 的存储请求之和上限。
  • persistentvolumeclaims:命名空间里 PVC 的总数上限。
  • <storage-class-name>.storageclass.storage.k8s.io/requests.storage:针对某个 StorageClass 的存储请求上限。
  • 同理还有该 StorageClass 下的 PVC 数量上限。

比如想给 goldbronze 两种 StorageClass 分别限额:

gold.storageclass.storage.k8s.io/requests.storage: 500Gi
bronze.storageclass.storage.k8s.io/requests.storage: 100Gi

对象数量配额,用来防控制平面被海量对象拖垮。语法是 count/<资源>,核心组资源写 count/pods,非核心组写 count/deployments.apps。常见项:count/podscount/servicescount/secretscount/configmapscount/deployments.apps

也可以直接用简写:podsservicessecretsconfigmapspersistentvolumeclaims,以及 services.loadbalancersservices.nodeports。比如给 pods 设上限,能防止有人建一堆小 Pod 把集群的 Pod IP 耗尽。

Tip

Secret 体积大,一个命名空间塞太多 Secret 可能让 API 服务器和控制器的启动都受影响。给 secrets 设数量配额,是性价比很高的保护。

42-5 配额作用域 scope

ResourceQuota 还能加 scope,只统计符合作用域的资源,作用域取交集生效。v1.36.2 支持这些作用域:

  • BestEffort:只算 QoS 为 BestEffort 的 Pod。
  • NotBestEffort:只算非 BestEffort 的 Pod。
  • Terminating / NotTerminating:按 Pod 是否在终止中区分。
  • PriorityClass:只算引用了特定优先级类的 Pod。
  • CrossNamespacePodAffinity:管”哪些命名空间允许带跨命名空间亲和性条件的 Pod”。
  • VolumeAttributesClass:只算引用特定卷属性类的 PVC。

带作用域的配额还能配 scopeSelector 字段,用 InNotInExistsDoesNotExist 做更细的匹配。比如想彻底禁止某命名空间里出现跨命名空间亲和,可以建一个 CrossNamespacePodAffinity 作用域、pods: "0" 的配额,等于把这类 Pod 数量锁死为 0。

Note

配额和集群容量无关。它是用绝对数值表达的。你给集群加了新节点,命名空间的额度不会自动变大。想要”按比例扩容”,得自己写控制器去动态调每个命名空间的 hard 值。

42-6 LimitRange 是什么

ResourceQuota 管”命名空间总共能用多少”。可它防不住另一个问题:一个 Pod 自己把整块额度吃光。LimitRange 就是来管”单个对象能申请多少”的。

LimitRange 是限制命名空间内,每个适用对象(Pod、容器、PVC)的资源取值区间的策略对象。只要命名空间里至少有一个 LimitRange,Kubernetes 就会对新建的对象做约束。

一个 LimitRange 能做的事:

  • 规定 Pod 或容器能用的最小、最大 CPU 和内存。
  • 规定 PVC 能申请的最小、最大存储。
  • 规定某资源的 request 和 limit 的比值上限。
  • 给没写资源需求的容器自动补上默认 request 和 limit。

42-7 LimitRange 的约束与默认值

管理员在命名空间建一个 LimitRange,用户再来建 Pod 或 PVC。流程分两步:第一步,准入控制器给没设资源需求的容器补默认 request/limit;第二步,跟踪用量,确保没突破 LimitRange 定的最小、最大和比值。

如果创建或更新的对象违反了 LimitRange 的约束,API 服务器的请求会失败,返回 403 Forbidden 并说明踩了哪条线。

LimitRange 有几个行为要点:

  • 验证只在 Pod 准入阶段做,已经跑着的 Pod 不受影响。你改了 LimitRange,旧 Pod 原样继续。
  • 命名空间里若有两个以上 LimitRange,到底用谁的默认值是不确定的,别这么干。
  • 加了针对 cpumemory 的 LimitRange 后,建 Pod 就必须写清这些资源的请求或限制,否则会被系统拒绝。
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-cpu-limit-range
spec:
  limits:
  - default:
      cpu: 500m
      memory: 256Mi
    defaultRequest:
      cpu: 100m
      memory: 128Mi
    max:
      cpu: "1"
      memory: 512Mi
    min:
      cpu: 50m
      memory: 64Mi
    type: Container

这段配置给命名空间里的容器设了默认、最小和最大。写 Pod 时忘填资源,准入控制器就按 defaultRequestdefault 补上;想填超过 max 的,直接被拒。

Warning

LimitRange 不检查它补的默认值是否自洽。如果你把 limit 默认值设得比容器自己写的 request 还小,最终 Pod 会因为”request 大于 limit”而无法调度。配 LimitRange 时留意默认值的合理性。

42-8 两者怎么配合

ResourceQuota 和 LimitRange 是一对搭档,一个管总盘子,一个管单对象,合起来才完整。

典型搭配:命名空间开了 cpumemory 配额,要求每个 Pod 都写资源需求。可你不能指望每个开发都记得写。于是用 LimitRange 自动补默认值——没写的容器,按 LimitRange 给的默认 request/limit 填上,配额系统就不会因”缺字段”而拒人于千里之外。

另外,配额管的是总量,LimitRange 管的是区间,两者都不影响已存在的资源。已经跑着的 Pod,无论你之后怎么改配额或 LimitRange,都保持原状。这点对线上变更很友好,但也意味着”存量”不会自动收敛,需要你另行处理。

Note

本章讲的两样对象都属于集群管理员在命名空间层面做的事。它们和容器自身的 resources 配置、QoS 类密切相关——想深入资源配置,可回看第 15 章的资源限制与 QoS 相关内容。

42-9 一句话回顾

ResourceQuota 回答”这个命名空间总共能用多少”,按总量硬拦;LimitRange 回答”单个 Pod、容器、PVC 能申请多大”,按区间约束并补默认。两者都只在新建对象时生效,都用 403 Forbidden 拒绝越界。把它们配合好,多团队共享集群才既公平又省心。