进击的Kubernetes调度系统(三):支持批任务的Binpack Scheduling

2020 年 8 月 26 日

进击的Kubernetes调度系统(三):支持批任务的Binpack Scheduling

前两篇文章《进击的Kubernetes调度系统 (一):Scheduling Framework》 和《进击的 Kubernetes 调度系统(二):支持批任务的 Coscheduling/Gang scheduling 》分别介绍了 Kubernetes Scheduling Framework 和如何通过扩展 Scheduling Framework 实现 Coscheduling/Gang scheduling 调度策略。当我们的批任务作业在集群里边运行起来之后,随后要关注的就是资源的利用率。特别是对于 GPU 卡的价格昂贵,不希望有资源的浪费。本文将介绍在批任务的调度过程中如何通过 Binpack 的方式,减少资源碎片,提升 GPU 的利用率。


为什么需要 Binpack 功能?


Kubernetes 默认开启的资源调度策略是 LeastRequestedPriority,消耗的资源最少的节点会优先被调度,使得整体集群的资源使用在所有节点之间分配地相对均匀。但是这种调度策略往往也会在单个节点上产生较多资源碎片。


下面拿一个简单的例子来说明这种问题。如下图所示,资源在节点之间平均使用,所以每个节点使用 3 个 GPU 卡,则两个节点各剩余 1GPU 的资源。这是有申请 2GPU 的新作业,提交到调度器,则因为无法提供足够的资源,导致调度失败。



如上这种情况情况,每个节点都有 1 个 GPU 卡空闲,可是又无法被利用,导致资源 GPU 这种昂贵的资源被浪费。如果使用的资源调度策略是 Binpack,优先将节点资源填满之后,再调度下一个节点,则上图所出现的资源碎片问题得到解决。申请 2GPU 的作业被正常调度到节点上,提升了集群的资源使用率。



实现方案



Binpack 实现已经抽象成 Kubernetes Scheduler Framework 的 Score 插件 RequestedToCapacityRatio,用于优选阶段给节点打分。将节点根据自己定义的配置进行打分。具体的实现可以分为两个部分,构建打分函数和打分.


构建打分函数


构建打分函数的过程比较容易理解,就是用户可以自己定义不同的利用率所对应的分值大小,以便影响调度的决策过程。


如果用户设定的对应方式如下所示,即如果资源利用率为 0 的时候,得分为 0 分,当资源利用率为 100 时,得分为 10 分,所以得到的资源利用率越高,得分越高,则这个行为是 Binpack 的资源分配方式。



用户也可以设置成利用率为 0 时,得分为 10 分,利用率为 100 时,得分为 0 分。这样意味着资源利用率越低,则得分越高,这种行为是 spreading 的资源分配方式。



用户除了 2 个点之外也可以新增更多的点,对应关系可以不是线性的关系,例如可以标识资源利用率为 50 时,得分为 8,则会将打分分割为两个区间: 0-50 和 50-100。



打分


用户可以自己定义在 Binpack 计算中所要参考的资源以及权重值,例如可以只是设定 GPU 和 CPU 的值和权重。


resourcetoweightmap:     "cpu": 1    "nvidia.com/gpu": 1
复制代码


然后在打分过程总,会通过计算(pod.Request + node.Allocated)/node.Total 的结果得到对应资源的利用率,并且将利用率带入上文中所述的打分函数中,得到相应的分数。最后将所有的资源根据 weight 值,加权得到最终的分数。


Score = line(resource1_utilization) * weight1 + line(resource2_utilization) * weight2 ....) / (weight1 + weight2 ....)
复制代码


Binpack 使用


配置方法


1、新建/etc/kubernetes/scheduler-config.yaml, 用户可以自行配置其他的 priorities 策略。


apiVersion: kubescheduler.config.k8s.io/v1alpha1kind: KubeSchedulerConfigurationleaderElection:  leaderElect: falseclientConnection:  kubeconfig: "REPLACE_ME_WITH_KUBE_CONFIG_PATH"plugins:  score:    enabled:    - name: RequestedToCapacityRatio      weight: 100    disabled:    - name: LeastRequestedPrioritypluginConfig:- name: RequestedToCapacityRatio  args:    functionshape:      - utilization: 0        score: 0      - utilization: 100        score: 100    resourcetoweightmap: # 定义具体根据哪种资源类型进行binpack操作,多种资源时可以设置weight来进行比重设置      "cpu": 1      "nvidia.com/gpu": 1
复制代码


Demo 演示


接下来我们通过运行 Tensorflow 的分布式作业来进行演示,展示 Binpack 的效果,当前测试集群有 2 台 4 卡的 GPU 机器


1、通过 Kubeflow 的 arena 在已有的 Kubernetes 集群中部署 tf-operator


Arena是基于Kubernetes的机器学习系统开源社区Kubeflow中的子项目之一。Arena用命令行和SDK的形式支持了机器学习任务的主要生命周期管理(包括环境安装,数据准备,到模型开发,模型训练,模型预测等),有效提升了数据科学家工作效率。


git clone https://github.com/kubeflow/arena.gitkubectl create ns arena-systemkubectl create -f arena/kubernetes-artifacts/jobmon/jobmon-role.yamlkubectl create -f arena/kubernetes-artifacts/tf-operator/tf-crd.yamlkubectl create -f arena/kubernetes-artifacts/tf-operator/tf-operator.yaml
复制代码


检查是否部署成功


$ kubectl  get pods -n arena-systemNAME                                READY   STATUS    RESTARTS   AGEtf-job-dashboard-56cf48874f-gwlhv   1/1     Running   0          54stf-job-operator-66494d88fd-snm9m    1/1     Running   0          54s
复制代码


2、用户向集群中提交 Tensorflow 分布式,作业含有 1 个 PS 和 4 个 Worker,每个 Worker 需要 1 个 GPU


apiVersion: "kubeflow.org/v1"kind: "TFJob"metadata:  name: "tf-smoke-gpu"spec:  tfReplicaSpecs:    PS:      replicas: 1      template:        metadata:          creationTimestamp: null          labels:            pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu            pod-group.scheduling.sigs.k8s.io/min-available: "5"        spec:          containers:          - args:            - python            - tf_cnn_benchmarks.py            - --batch_size=32            - --model=resnet50            - --variable_update=parameter_server            - --flush_stdout=true            - --num_gpus=1            - --local_parameter_device=cpu            - --device=cpu            - --data_format=NHWC            image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3            name: tensorflow            ports:            - containerPort: 2222              name: tfjob-port            resources:              limits:                cpu: '1'            workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks          restartPolicy: OnFailure    Worker:      replicas: 4      template:        metadata:          creationTimestamp: null          labels:            pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu            pod-group.scheduling.sigs.k8s.io/min-available: "5"        spec:          containers:          - args:            - python            - tf_cnn_benchmarks.py            - --batch_size=32            - --model=resnet50            - --variable_update=parameter_server            - --flush_stdout=true            - --num_gpus=1            - --local_parameter_device=cpu            - --device=gpu            - --data_format=NHWC            image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3            name: tensorflow            ports:            - containerPort: 2222              name: tfjob-port            resources:              limits:                nvidia.com/gpu: 1            workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks          restartPolicy: OnFailure
复制代码


3、当用户使用 Binpack 功能时,用户提交任务后,4 个 Worker 被调度到同一个 GPU 节点 cn-shanghai.192.168.0.129


$ kubectl get pods -o wideNAME                    READY   STATUS    AGE   IP             NODEtf-smoke-gpu-ps-0       1/1     Running    15s   172.20.0.210   cn-shanghai.192.168.0.129  tf-smoke-gpu-worker-0   1/1     Running    17s   172.20.0.206   cn-shanghai.192.168.0.129   tf-smoke-gpu-worker-1   1/1     Running    17s   172.20.0.207   cn-shanghai.192.168.0.129      tf-smoke-gpu-worker-2   1/1     Running    17s   172.20.0.209   cn-shanghai.192.168.0.129tf-smoke-gpu-worker-3   1/1     Running    17s   172.20.0.208   cn-shanghai.192.168.0.129     
复制代码


4、当用户不使用 Binpack 功能时,用户提交任务后,4 个 Worker 被分配到 cn-shanghai.192.168.0.129 和 cn-shanghai.192.168.0.130 两个节点上,产生资源碎片


$ kubectl get pods -o wideNAME                    READY   STATUS AGE   IP             NODEtf-smoke-gpu-ps-0       1/1     Running    7s    172.20.1.72    cn-shanghai.192.168.0.130tf-smoke-gpu-worker-0   1/1     Running    8s    172.20.0.214   cn-shanghai.192.168.0.129tf-smoke-gpu-worker-1   1/1     Running    8s    172.20.1.70    cn-shanghai.192.168.0.130tf-smoke-gpu-worker-2   1/1     Running    8s    172.20.0.215   cn-shanghai.192.168.0.129tf-smoke-gpu-worker-3   1/1     Running    8s    172.20.1.71    cn-shanghai.192.168.0.130
复制代码


后记


上文中我们介绍了如何利用 Kubernetes 原生的调度策略 RequestedToCapacityRatio 来支持 Binpack Scheduling 的功能,减少资源碎片,提升 GPU 的利用率。使用起来很简单,但是效果很明显。针对 GPU 的资源利用率的提升的课题,我们将在本系列接下来的文章中介绍如何在推理服务下,通过 GPU 共享调度的方法大大的提升 GPU 利用率。


相关阅读:


进击的 Kubernetes 调度系统(一):Scheduling Framework


进击的 Kubernetes 调度系统(二):支持批任务的 Coscheduling/Gang scheduling


2020 年 8 月 26 日 09:50680

评论

发布
暂无评论
发现更多内容

2020,是中国SaaS行业的机遇之年?

ToB行业头条

为什么单元测试不是持续交付的唯一答案

持续集成 单元测试

火焰图:全局视野的Linux性能剖析

Marionxue

Redis基础:redis特点

古月木易

redis

Markdown工具Typora结合gitee码云图床自动上传云端图片

Flychen

Typora markdown gitee

java 后端博客系统文章系统——No4

猿灯塔

企业的数字化转型探索

松子(李博源)

企业架构 数字化 企业数字化转型

MySql的Dockerfile编写

玏佾

ServerlessDays China:无服务器的未来

Michael Yuan

云计算 Serverless 容器 虚拟机 webassembly

第六周作业

赵龙

Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览

YourBatman

spring springboot

你有认真了解过自己的“Java对象”吗

海星

Java JVM

数据库周刊32丨Oracle自治数据库大动作;腾讯云MySQL 8.0上线;华为数据库工程师认证发布;update引起业务卡顿;PostgreSQL安全加固;openGauss单机安装;中国DBA联盟"ACDU"邀您加入……

墨天轮

MySQL 数据库 oracle postgresql

统一物品编码 破解追溯“断链”困局

CECBC区块链专委会

练习 6-1

闷骚程序员

支付公司如何赚钱?支付网关如何设计?

诸葛小猿

微信 支付宝 聚合支付 第三方支付 支付网关

啃碎并发(10):内存模型之内部原理

猿灯塔

《中国区块链产业园15强名录》

CECBC区块链专委会

Redis基础:redis特点

奈学教育

redis

微信小程序使用GoEasy实现websocket实时通讯

GoEasy消息推送

小程序 websocket 即时通讯

我的程序跑了60多小时,就是为了让你看一眼JDK的BUG导致的内存泄漏。

why技术

Java 源码 jdk 并发 bug

一口气讲透一致性哈希(Hash),助力「码农变身」

码农神说

一致性算法 一致性哈希 一致性hash 一致性Hash算法

​中国SaaS处在什么阶段?

ToB行业头条

【融云分析】融云实时音视频 SDK 对智能硬件的视频适配

Geek_116789

架构师是怎样炼成的 6-1

闷骚程序员

Worktile完成新一轮融资,将发力研发管理赛道

Worktile

融资

将设计模式应用到日常的curd中—分离关联查询

LSJ

Java 设计

解读:新基建为区块链带来的新机遇

CECBC区块链专委会

话题讨论|在编程中,有哪些好习惯是应该一直坚持下去的?

InfoQ写作平台

写作平台 话题讨论 话题

猿灯塔:spring Boot Starter开发及源码刨析(四)

猿灯塔

Java 猿灯塔 spring Boot Starter

快来!我从源码中学习到了一招Dubbo的骚操作!

why技术

源码 面试 dubbo 动态代理

进击的Kubernetes调度系统(三):支持批任务的Binpack Scheduling-InfoQ