深度学习批任务处理调度器与kubernetes默认调度器融合


kubernetes集群三步安装深度学习中经常会出现多机多卡的任务,也就是同事会起多个pod,但是这多个pod属于同一个任务。这样就会有一个问题一个任务要起100个pod,每个pod需要一张卡,总共需要100张GPU卡,而集群中只有99张空闲的GPU卡,这样默认的k8s调度器会如何处理?因为默认调度器是一个一个pod调度的,只会检查单个pod资源够不够,这样前99个都能成功,最后一个pod调度失败。 这样非常有可能造成 所以需要在调度时对整个task所需所有资源进行检查,当集群总体资源不够时,一个pod都得不到调度。社区提供了一个能支持这种特性的调度器
但是这个调度器是没办法和原生调度器很好的配合工作的所以我们做的事是将两者特性融合,选择的方法是定制化开发kube-scheduler其实scheduler是可以通过extender扩展的,但是extender还是太弱了,它仅能在预选和优选过程中加入自己的过滤策略,而这对于批处理任务远远不够。需要优选时加batch任务检查
拿到一个pod —> 如果是一个batchpod —> 查询集群资源是否满足batch任务—>否调度失败需要保障batch任务中其它pod能得到调度如果集群资源能满足这个batch任务直接去bind有个问题:
假设调度队列是这样,假设集群中有三个GPU,而batch任务需要三个GPU:所以最终结果是A批任务占用了一个GPU但是整个任务开发云主机域名是调度失败的,那一个GPU还得不到释放所以需要修改pod调度队列里的顺序?让A batch pod连续调度? 没这么简单,pod调度是创建协程并发调度的,这样即便去调整任务队列里pod的顺序也不一定能保证batch任务其它pod能得到优先调度。只要batch pod走到Bind逻辑了就没有回头路了batch任务中所有pod先进行assume调度,其中任意一个失败就清理掉其它已经bind但是还没实际进行调度的pod。 并把所有pod扔回队列,或者直接返回调度失败清理改任务的pod,让上层重新触发?scheduler流程 scheduler/sheduler.go scheduleOne逻辑:选节点->cache assume pod on node-> 创建协程bind所以在assume时去检查,不满足退还已经调度的pod是不可行的,因为之前batch任务中的pod可能已经bind过了, 所以只能batch任务中最后一个pod得到确认才能去bind前面的pod预占用策略
预占用策略: 第一个batch pod任务来时,检查集群资源是不是够,如果够进行预占,把其它几个node打上标记,让接下来pod无法占用其它的node,这样batch任务其实pod过来就有节点可用。回到了不能bind的问题。。。这种问题有两点:如何知道batch任务中其它pod需要什么样的节点,如果pod都一样问题可简化
如果后面的pod失败了,第一个pod还是已经bind,还是会出现一样的问题
最终还是在所有pod assume之前不能bind单个pod综上,需要在几个地方处理队列最好用优先级队列,把正在调度的pod的关联pod优先级提高
选节点时做判断,看集群资源是否够
选好节点assume pod时检查,如果自己不够或者pod组不够就不去bind
问题是之前的pod已经走了bind流程,所以最重要的是如何解决让之前的pod不去bind,延迟bind最终方案 – 延迟绑定方案:在batch任务bind时进行特殊处理使用
batch任务使用,pod增加两个注解:pod加上这两个注解表示属于同一个task, num表示task里有多少pod。本来是再定义一个CRD去描述这个task,耦合会小一些,但是实现麻烦些,需要多监听一个CRD,偷懒就没这样做延迟绑定流程:
batch scheduler接口与成员
Run 起一个协程检查成功的task并塞入队列
RunBind 起一个task绑定协程
PodQuePriority 去动态修改pod队列的优先级,让同task的pod优先调度执行流程:
scheduler/scheduler.go:增加绑定互斥,防止batch任务和普通pod同事binding:should’t use filterFunc, needs nodelistscheduler/util/batch.goscheduler/core/generic_scheduler.go处理资源不足时的情况nodeInfo allocatableResource – requestedResource is avaliavle resourceGPU 是 ScalarResources, 资源名称叫 : NVIDIAGPUResourceName = "nvidia.com/gpu"需要知道已经有哪些pod已经assume过了,把这个数量减掉才是batch任务还需要多少GPUcore/generic_scheduler.gofactory.gothen checkresource :有很多细节资源包这里包含docker nv-docker GPU-device plugin
install.sh…/etc/docker/daemon.jsonkubectl describe node xxx:原生调度器的设计就是pod one by one,所以做这个功能的开发还是改动非常大的,也是比较困难的,工作量不大,但是需要找到一个优雅的方案,
合理的架构比较麻烦,想了很久做了这个侵入不太大的实现方案,欢迎大家一起讨论

相关推荐: 虚拟主机和云服务器的区别

虚拟主机和云服务器的区别1、云服务器可支持弹性扩展,按需付费,而虚拟主机不支持2、云服务器需要手动配置环境,虚拟主机无须配置环境3、云服务器是独享资源,虚拟主机的资源是共享的4、云服务器可远程桌面进行管理,虚拟主机只能采用ftp进行管理虚拟主机、云服务器的操作…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 05/13 18:11
Next 05/13 18:11

相关推荐