news 2026/6/9 9:59:52

在调度的花园里面挖呀挖

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在调度的花园里面挖呀挖

上文使用koordinator演示gang-scheduling和binpack调度, 已经生效。

4个2卡Pod龟缩在一个节点,另外一个2卡Pod被挤到另外一个节点(每节点上虚拟gpu:8卡)。

此时我们再尝试申请8卡作业,pod会Pending状态。但一旦节点有资源,pod就会自动进入Running状态。

这就是resource.requests/limits 软调度的效果。

1. resource.requests/limits 软调度

上面的调度主要由requests配置来约束。

requests: 是“承诺资源”, kube-scheduler将requests cpu:1 的pod调度到某个node, 就相当于从该node资源池上划走了有一部分资源,这1核会被预定,不再承诺给其他pod,即使你这个pod只用了500m核。

limits: 是资源使用的上限,是由kubelet来强制执行。

2. k8s原生配额ResourceQuota: 硬隔离

当多个团队共享k8s集群节点资源时, 会有某一租户霸占大量资源的可能性。

资源配额就是用来解决这个问题:

资源配额作用在命名空间上(命名空间天生就是多租户概念的载体), 限制了该租户(命名空间)能创建的资源对象(+基础设施资源)的上限, 这个限制是通过api server在资源对象层面做到的。

ResourceQuota 相当于框定某一类资源的可用上限, 有“资源类型”、”配额作用域“ 等过滤资源的选项, 具体请参见ResouceQouta官方。

下面给出一个包含[基础设施资源、扩展资源、资源对象]的ResourceQuota:

apiVersion: v1

kind: ResourceQuota

metadata:

name: mem-cpu-demo

spec:

hard:

requests.cpu: "1"

requests.memory: 1Gi # 需求总量

limits.cpu: "2"

limits.memory: 2Gi # 限额总量

requests.example.com/dongle: 2

pods: "4"

replicationcontrollers: "20"

secrets: "10"

services: "10"

因为扩展资源不可超量分配,故没有必要为扩展资源同时指定requests和limits配置,只需指定requests.xxxx 即可。

因为配额的准入是在apiserver 资源对象层面, 所以当配额不足,不会产生pod处于pending的现象,kubectl命令会给出报错:pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota, 这点与resource.requests/limits 软调度不同。

提示:

ResourceQuota 与集群资源总量是完全独立的。它们通过绝对的单位来配置。

所以,为集群添加节点时,k8s资源配额不会自动赋予每个命名空间消耗更多资源的能力。

3. kueue 任务队列

上文k8s原生resourceQuota 是命名空间级别的硬资源限制,“它只负责限制, 不负责调度”。

在企业级多租户云环境中,为了①高效②灵活 利用集群资源, 需要“协调和调度”的能力。

kueue 这种任务队列就是这个作用,它不谋求替代k8s原生组件作用,工作在k8s原生调度器之上。

kueue是k8s上管理资源池配额和管控job消费资源池配额的任务队列系统,

kueue决定了job什么时候应该等待,什么时候被准入,什么时候job可以被抢占。

什么时候使用kueue?

① 需要弹性计算资源(可随时扩缩容)

② 计算资源是异构资源(架构、可用性、价格等因素)

这里我用自己的想法协助大家理解这①②点:

kueue中构建的clusterQueue引用的资源池配额是逻辑配额, 资源可以跨队列流动 (借用、抢占), 虽然和k8s原生配额一样都不与硬件资源直接挂钩,但很明显相比k8s原生配额更具弹性。

同构资源指的是所有计算节点/设备规格相同, 异构资源是指计算节点/设备规格/特性不同。

image

为什么会存在异构资源?

由业务需求驱动产生的不同设备形态(AI/ML工作负载、边缘计算、科学计算等要求的设备种类、设备规格、设备侧重都不同), 衍生出设备价格也不同。

下图是kueue的作用原理。

image

3.1 资源高度抽象

上面的resource.requests/limits 和k8s原生resourceQuota 都没能跳脱worker 节点资源的概念。

kueue将worker节点上的资源抽象成由特定资源风味(ResourceFlavor)表征的资源池, 框定了某一类含有特定资源类型/规格的节点。

apiVersion: kueue.x-k8s.io/v1beta2

kind: ResourceFlavor

metadata:

name: "vgpu"

spec:

nodeLabels:

instance-type: vgpu

上面名为vgpu的资源风味 框定了带有instance-type=vgpu标签的节点

如果是同构资源,你也可以定义empty resource flavor。

然后基于框定的资源池给某个任务队列分发资源配额。

3.2 资源池的配额 nominalQuota

ClusterQueue 默认是集群级别的对象,定义了集群中某类资源风味的配额。

下面为cluster-queue的全局队列(依托于“default-flavor”资源池)定义了使用配额, 其中为稀缺资源example.com/dongle约束10卡。

命名空间team-a的localQueue引用了该clusterQueue。

apiVersion: kueue.x-k8s.io/v1beta2

kind: ResourceFlavor

metadata:

name: default-flavor ## 对同构资源,定义empty资源风味

---

apiVersion: kueue.x-k8s.io/v1beta2

kind: ClusterQueue

metadata:

name: "cluster-queue"

spec:

namespaceSelector: {} # match all.

resourceGroups:

- coveredResources: ["cpu", "memory", "pods"]

flavors:

- name: "default-flavor"

resources:

- name: "cpu"

nominalQuota: 10

- name: "memory"

nominalQuota: 10Gi

- name: "example.com/dongle"

nominalQuota: 10

---

apiVersion: kueue.x-k8s.io/v1beta2

kind: LocalQueue

metadata:

namespace: team-a

name: team-a-queue

spec:

clusterQueue: cluster-queue

clusterQueue与localQueue的引用关系实现了共享全局资源池的理念。

形成的对象映射关系如下:

image

浅绿色是kueue产生的对象,浅蓝色是用户实际提交的批处理任务。

下面用一个k8s原生job来演示 kueue的工作表现。

apiVersion: batch/v1

kind: Job

metadata:

name: pi3

labels:

kueue.x-k8s.io/queue-name: team-a-queue

spec:

parallelism: 3 # 并行执行次数,默认为1

completions: 3 # 完成次数,默认为parallelism的值

suspend: true # 应该在挂起状态下创建job,由kueue来决定何时启动job

template:

spec:

containers:

- name: pi

image: perl

imagePullPolicy: IfNotPresent

command: [ "perl", "-Mbignum=bpi", "-wle", "print bpi(5000)" ]

resources:

requests:

cpu: "1"

memory: "200Mi"

example.com/dongle: "2"

limits:

cpu: "1"

memory: "200Mi"

example.com/dongle: "2"

restartPolicy: Never

# Job 代表一次性任务,运行完成到停止,它将π计算到5000个位置并将其打印出来。完成大约需要60秒。 之后pod状态是 Completed

这里最重要的是配置是job中的"suspend:true", job应该以挂起状态被创建,由kueue来决定何时启动。

在原生job标签关联localqueue

提交第一个任务,3个Pod占用了6卡;

再立刻启动同样配置的第二个任务,受localqueue中nominalQuota: 10的约束,任务2会pending,等待任务1执行完,释放了example.com/dongle资源,最后进入runing状态跑完任务。

image

分别查看任务1和任务2的准入事件:

image

image

kueue 还有很多特性,读者自行审阅,修行在个人。

① 核心的clusterqueue默认的排队策略是: BestEffortFIFO: 先按优先级排序,再按照创建时间;未被准入的旧任务不会影响后续能被准入的新来任务。

② 支持队列组Cohort, 可实现资源弹性借用

③ 注意队列组、clusterqueue与资源风味的1对多的关系。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/8 21:53:07

高标准农田气象监测设备:风速风向温湿压雨量监测的技术赋能

一.引文高标准农田建设是保障粮食安全、提升农业生产效率的核心举措,而气象要素的精准监测则是实现农田精细化管理的关键支撑。风速、风向、温度、湿度、气压、雨量等气象因子直接影响作物生长发育、病虫害发生及农业灾害防控,对应的专业监测…

作者头像 李华
网站建设 2026/6/8 14:07:57

智能数控滑台:现代制造业的高效引擎

数控滑台作为精密机械加工的核心部件,其性能直接影响生产效率和产品质量。随着智能制造技术的快速发展,数控滑台在自动化生产线、精密仪器加工等领域展现出巨大潜力。数控滑台的关键技术高精度伺服驱动系统确保滑台运动平稳,重复定位精度可达…

作者头像 李华
网站建设 2026/6/9 6:42:16

告别 0 曝光!TikTok 冷启动在算法丛林建信任营地

对TikTok卖家而言,新店启动期充满挑战:内容无人问津、流量受限、账号风险并存,这些“冷启动陷阱”的根源,在于卖家与平台算法之间未能建立初步的信任,成功的关键,是从底层逻辑出发,系统性构建一…

作者头像 李华
网站建设 2026/6/8 10:39:48

专业猎人维修工具套装 高效便捷 9合1多功能 无需

温馨提示:文末有联系方式专业猎人维修工具集 高效便捷 9合1多功能 免使用全新升级的猎人维修工具集,专为专业技术人员打造,集成了九项实用功能于一体,省去频繁切换工具的麻烦。 无需任何额外,安装即用,大幅…

作者头像 李华
网站建设 2026/6/9 6:50:59

vueUse/core 基础与高阶应用指南

vueUse/core 基础与高阶应用指南 解锁 Vue 3 组合式 API 的超级能力 ✨ 引言 在 Vue 3 组合式 API 生态中,vueUse/core 无疑是一颗璀璨的明星。它提供了上百个精心设计的组合式函数,覆盖了从 DOM 操作到状态管理、从网络请求到浏览器 API 等几乎所有前端…

作者头像 李华
网站建设 2026/6/9 8:34:17

【Java毕设源码分享】基于springboot+vue的高校门诊校医院就诊管理系统设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华