Kubernetes 版本:v1.32
到这一章,Unit 3 的主题就从“单个 Pod 怎么被调度”进一步升级为“多个业务一起跑时,集群资源该怎么治理”。
现实里的 Kubernetes 集群,很少只有一个团队在用。更常见的情况是:
- 核心链路服务和普通业务混跑;
- 在线服务和离线任务共用节点;
- 多个团队共享一个大集群;
- 大家都想优先拿到资源。
这时候,光靠 request / limit 已经不够了。你还需要回答两类更高层的问题:
- 谁更优先被调度?
- 谁最多能占多少资源?
前者靠 PriorityClass,后者靠 ResourceQuota 与 LimitRange。
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”了,而是真正开始具备管理集群调度与资源策略的能力。
📝 版权声明:本文为原创技术博客,转载请注明出处。
如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!