返回首页

3.4 PriorityClass 与 ResourceQuota

Kubernetes 版本:v1.32

到这一章,Unit 3 的主题就从“单个 Pod 怎么被调度”进一步升级为“多个业务一起跑时,集群资源该怎么治理”。

现实里的 Kubernetes 集群,很少只有一个团队在用。更常见的情况是:

  • 核心链路服务和普通业务混跑;
  • 在线服务和离线任务共用节点;
  • 多个团队共享一个大集群;
  • 大家都想优先拿到资源。

这时候,光靠 request / limit 已经不够了。你还需要回答两类更高层的问题:

  1. 谁更优先被调度?
  2. 谁最多能占多少资源?

前者靠 PriorityClass,后者靠 ResourceQuotaLimitRange

1. PriorityClass 如何影响调度优先级

官方 v1.32 文档说明,Kubernetes 支持为 Pod 设置优先级;在资源不足时,更高优先级的 Pod 会在调度和抢占决策中获得优势。::cite[208]

1.1 PriorityClass 是什么

PriorityClass 是一个集群级对象,用来定义一个优先级名称和对应的整数值。Pod 通过 priorityClassName 引用它。

简单理解:

  • 数值越高,优先级越高;
  • 高优先级 Pod 在排队和争抢资源时更有优势。

1.2 创建一个 PriorityClass

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 100000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "高优先级业务,资源紧张时可抢占低优先级 Pod"

应用:

kubectl apply -f priorityclass-high.yaml

1.3 Pod 使用 PriorityClass

apiVersion: v1
kind: Pod
metadata:
  name: high-priority-pod
spec:
  priorityClassName: high-priority
  containers:
    - name: app
      image: nginx:1.27
      resources:
        requests:
          cpu: "500m"
          memory: "256Mi"
        limits:
          cpu: "1"
          memory: "512Mi"

这样,high-priority-pod 就被赋予了更高的调度优先级。

2. 抢占机制与高优先级工作负载

2.1 抢占是什么

当高优先级 Pod 因资源不足无法调度时,调度器可能会尝试驱逐一些低优先级 Pod,为高优先级 Pod 腾出空间。官方 Pod Priority and Preemption 文档明确说明了这种机制。::cite[208]

这意味着:

  • 高优先级不是“只排队靠前”;
  • 在资源紧张时,它还可能真正“挤掉”低优先级工作负载。

2.2 preemptionPolicy 的作用

官方 API 参考指出,PriorityClass 可以通过 preemptionPolicy 控制是否允许抢占低优先级 Pod。::cite[211]

常见配置:

  • PreemptLowerPriority:允许抢占低优先级 Pod;
  • Never:拥有高优先级,但不主动抢占别人。

示例:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: non-preempting-high
value: 90000
preemptionPolicy: Never
globalDefault: false
description: "高优先级但不抢占,适合重要但非强制中断型任务"

2.3 哪些工作负载适合高优先级

比较常见的有:

  • 核心入口网关
  • 关键控制面组件
  • 重要告警链路
  • 关键数据库代理
  • 高优先级批处理恢复任务

但要注意:高优先级不是越多越好。如果所有团队都把自己的服务设成最高优先级,那这个机制就失效了。

3. ResourceQuota 与 LimitRange 的作用

3.1 ResourceQuota:限制“一个命名空间总共能用多少”

官方文档指出,当多个用户或团队共享固定规模的集群时,ResourceQuota 可以限制某个命名空间的聚合资源消耗,避免某一方占用过多资源。::cite[209]

也就是说,ResourceQuota 关注的是:

  • 这个 namespace 总共最多能创建多少 Pod;
  • 总 request / total limit 最多能到多少;
  • 某些对象数量是否超限。

示例:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "8"
    requests.memory: 16Gi
    limits.cpu: "16"
    limits.memory: 32Gi
    pods: "30"

这个配额表示:

  • team-a 命名空间里所有 Pod 的 CPU request 总和不能超过 8;
  • 内存 request 总和不能超过 16Gi;
  • Pod 数量不能超过 30。

3.2 LimitRange:限制“单个对象默认该怎么配、最大最小能配多少”

官方 v1.32 文档说明,默认情况下容器的计算资源可以是无界的;LimitRange 用来为命名空间内的对象设置默认 request / limit,以及最小值、最大值等边界。::cite[337]

这和 ResourceQuota 的区别非常关键:

  • ResourceQuota 看的是总量
  • LimitRange 看的是单体规范

3.3 一个 LimitRange 示例

官方任务文档给出了典型示例:可以为容器设置默认 memory request 和默认 memory limit。::cite[338]

下面是一个完整 YAML:

apiVersion: v1
kind: LimitRange
metadata:
  name: default-container-limits
  namespace: team-a
spec:
  limits:
    - type: Container
      default:
        cpu: "500m"
        memory: "512Mi"
      defaultRequest:
        cpu: "200m"
        memory: "256Mi"
      min:
        cpu: "100m"
        memory: "128Mi"
      max:
        cpu: "2"
        memory: "2Gi"

它起到的效果通常有三类:

  • 给没写资源的容器补默认值;
  • 防止有人把资源写得过小;
  • 防止有人把单容器资源写得离谱地大。

4. 实操:同时配置 PriorityClass、Quota、LimitRange

4.1 创建命名空间

apiVersion: v1
kind: Namespace
metadata:
  name: team-a

4.2 应用 ResourceQuota

kubectl apply -f resourcequota-team-a.yaml

4.3 应用 LimitRange

kubectl apply -f limitrange-team-a.yaml

4.4 创建一个业务 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
  namespace: team-a
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-service
  template:
    metadata:
      labels:
        app: api-service
    spec:
      priorityClassName: high-priority
      containers:
        - name: api
          image: nginx:1.27
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: "300m"
              memory: "256Mi"
            limits:
              cpu: "800m"
              memory: "512Mi"

4.5 查看配额使用情况

kubectl describe quota -n team-a

4.6 查看 LimitRange 生效情况

kubectl describe limitrange default-container-limits -n team-a

5. 多团队共享集群时的资源治理思路

这是本章最重要的部分,也是生产环境最有价值的部分。

5.1 先分层,再治理

比较推荐的思路是把业务按层级拆开:

  • 平台系统层:监控、日志、网关、控制组件
  • 核心业务层:直接影响主链路收入或可用性的服务
  • 普通业务层:常规在线服务
  • 离线任务层:批处理、报表、训练、临时任务

然后分别给出:

  • 不同的 PriorityClass
  • 不同的 namespace 配额
  • 不同的默认资源规范

5.2 配额的核心目标不是“卡死”,而是“防止失控”

ResourceQuota 最大的价值,不是让大家都不够用,而是防止:

  • 某个团队误把副本数拉爆;
  • 某个任务一次性占满 CPU / 内存;
  • 关键业务被普通任务拖垮。

5.3 LimitRange 负责兜底规范

很多团队共享集群时,最常见的问题不是故意抢资源,而是YAML 写得不规范

  • 有人忘了写 requests;
  • 有人把 limits 配得过大;
  • 有人写了极端值,导致调度异常。

LimitRange 在这种场景里特别像“门禁”:

  • 不合规的资源配置直接被拦下;
  • 没配资源的对象也能补默认值。

5.4 PriorityClass 要谨慎开放

官方文档也提醒过:如果不是所有用户都可信,恶意用户可能把 Pod 都设成很高优先级,因此管理员可以配合 ResourceQuota 去限制高优先级 Pod 的创建或消耗。::cite[208]

所以在多团队环境里,通常不建议把“最高优先级”开放给所有人自由使用。

6. 一个实用的治理建议表

目标 推荐机制 说明
核心服务优先调度 PriorityClass 提高关键业务的调度优先级
资源紧张时保护关键服务 PriorityClass + 抢占 必要时腾出资源
防止团队占满集群 ResourceQuota 限制 namespace 总量
防止 YAML 乱配资源 LimitRange 设置默认值、最大值、最小值
共享集群公平性 配额 + 分级优先级 技术与治理一起做

7. 学习这一章最容易混淆的点

7.1 PriorityClass 不是资源保证

它决定的是优先级,不是“你一定能拿到足够资源”。如果整个集群真的没有可腾挪空间,高优先级 Pod 仍然可能 Pending。

7.2 ResourceQuota 不是给单个 Pod 用的

它限制的是 namespace 聚合总量,不是单个容器的上下限。

7.3 LimitRange 不是替代 Quota

两者职责不同:

  • Quota 控总量;
  • LimitRange 管单体规则。

生产里通常是两者一起上。

8. 本章小结

这一章可以总结成一句话:

PriorityClass 决定“谁更重要”,ResourceQuota 与 LimitRange 决定“谁最多能用多少、怎么用才合规”。

如果是单团队小集群,这些配置你可能暂时感受不深;但只要进入多人共享、在线离线混部、核心与普通业务共存的场景,这套机制几乎就是资源治理的基础设施。

至此,Unit 3 的核心内容也就串起来了:

  • Chapter 3.1:理解调度器怎么选节点;
  • Chapter 3.2:理解 request / limit / QoS;
  • Chapter 3.3:理解亲和性与污点容忍;
  • Chapter 3.4:理解优先级与资源治理。

把这四章贯通之后,你就不只是“会写 Pod YAML”了,而是真正开始具备管理集群调度与资源策略的能力。


📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

2.4 ConfigMap 与 Secret:配置与敏感信息管理

下一篇

4.3 Service 实现原理:iptables 与 IPVS