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

作者:王庆璨 张凯

前言

Kubernetes已经成为目前事实标准上的容器集群管理平台。它为容器化应用提供了自动化部署、运维、资源调度等全生命周期管理功能。经过3年多的快速发展,Kubernetes在稳定性、扩展性和规模化方面都有了长足进步。 尤其是Kubernetes控制平面的核心组件日臻成熟。而作为决定容器能否在集群中运行的调度器Kube-scheduler,更是由于长久以来表现稳定,且已能满足大部分Pod调度场景,逐渐不被开发人员特别关注。

伴随着Kubernetes在公有云以及企业内部IT系统中广泛应用,越来越多的开发人员尝试使用Kubernetes运行和管理Web应用和微服务以外的工作负载。典型场景包括机器学习和深度学习训练任务,高性能计算作业,基因计算工作流,甚至是传统的大数据处理任务。此外,Kubernetes集群所管理的资源类型也愈加丰富,不仅有GPU,TPU和FPGA,RDMA高性能网络,还有针对领域任务的各种定制加速器,比如各种AI芯片,NPU,视频编解码器等。开发人员希望在Kubernetes集群中能像使用CPU和内存那样简单地声明式使用各种异构设备。

总的来说,围绕Kubernetes构建一个容器服务平台,统一管理各种新算力资源,弹性运行多种类型应用,最终把服务按需交付到各种运行环境(包括公共云、数据中心、边缘节点,甚至是终端设备),已然成为云原生技术的发展趋势。

阿里云容器服务团队结合多年Kubernetes产品化与客户支持经验,对Kube-scheduler进行了大量扩展和改进,逐步使其在多种场景下依然能稳定、高效地调度复杂工作负载类型。

《进击的Kubernetes调度系统》系列文章将把我们的经验、技术思考和实现细节全面地展现给Kubernetes用户和开发者,期望帮助大家更好地了解Kubernetes调度系统的强大能力和未来发展方向。

早期方案

首先,让我们来了解一下Kubernetes社区都有过哪些提升调度器扩展能力的方案。

要统一管理和调度异构资源与更多复杂工作负载类型,首先面对挑战的就是Kube-scheduler。在Kubernetes社区里关于提升调度器扩展能力的讨论一直不断。sig-scheduling给出的判断是,越多功能加入,使得调度器代码量庞大,逻辑复杂,导致维护的难度越来越大,很多bug难以发现、处理。而对于使用了自定义调度的用户来说,跟上每一次调度器功能更新,都充满挑战。

在阿里云,我们的用户遇到了同样的挑战。Kubernetes原生调度器循环处理单个Pod容器的固定逻辑,无法及时、简单地支持用户在不同场景的需求。所以针对特定的场景,我们会基于原生Kube-scheduler扩展自己的调度策略。

最初对于Kube-scheduler进行扩展的方式主要有两种,一种是调度器扩展(Scheduler Extender), 另外一种是多调度器(Multiple schedulers)。接下来我们对这两种方式分别进行介绍和对比。

Scheduler Extender

社区最初提供的方案是通过Extender的形式来扩展scheduler。Extender是外部服务,支持Filter、Preempt、Prioritize和Bind的扩展,scheduler运行到相应阶段时,通过调用Extender注册的webhook来运行扩展的逻辑,影响调度流程中各阶段的决策结果。


以Filter阶段举例,执行过程会经过2个阶段:

  1. scheduler会先执行内置的Filter策略,如果执行失败的话,会直接标识Pod调度失败。
  2. 如何内置的Filter策略执行成功的话,scheduler通过Http调用Extender注册的webhook, 将调度所需要的Pod和Node的信息发送到到Extender,根据返回filter结果,作为最终结果。
     

scheduler-extender.svg
 

我们可以发现Extender存在以下问题:

  1. 调用Extender的接口是HTTP请求,受到网络环境的影响,性能远低于本地的函数调用。同时每次调用都需要将Pod和Node的信息进行marshaling和unmarshalling的操作,会进一步降低性能。
  2. 用户可以扩展的点比较有限,位置比较固定,无法支持灵活的扩展,例如只能在执行完默认的Filter策略后才能调用。

基于以上介绍,Extender的方式在集群规模较小,调度效率要求不高的情况下,是一个灵活可用的扩展方案,但是在正常生产环境的大型集群中,Extender无法支持高吞吐量,性能较差。

Multiple schedulers

Scheduler在Kubernetes集群中其实类似于一个特殊的Controller,通过监听Pod和Node的信息,给Pod挑选最佳的节点,更新Pod的spec.NodeName的信息来将调度结果同步到节点。所以对于部分有特殊的调度需求的用户,有些开发者通过自研Custom Scheduler来完成以上的流程,然后通过和default scheduler同时部署的方式,来支持自己特殊的调度需求。


1588144283202-b3734bbe-b06d-4c65-81b2-d17bf44b521e.svg

Custom Scheduler会存在一下问题:

  1. 如果与default scheduler同时部署,因为每个调度器所看到的资源视图都是全局的,所以在调度决策中可能会在同一时刻在同一个节点资源上调度不同的Pod,导致节点资源冲突的问题。
  2. 有些用户将调度器所能调度的资源通过Label划分不同的池子,可以避免资源冲突的现象出现。但是这样又会导致整体集群资源利用率的下降。
  3. 有些用户选择通过完全自研的方式来替换default scheduler,这种会带来比较高的研发成本,以及Kubernetes版本升级后可能存在的兼容性问题。

Scheduler Extender的性能较差可是维护成本较小,Custom Scheduler的研发和维护的成本特别高但是性能较好,这种情况是开发者面临这种两难处境。这时候Kubernetes Scheduling Framework V2横空出世,给我们带来鱼和熊掌可以兼得的方案。

 


1588518816965-3d62377d-4167-4d00-a935-4d38c562fa0d.jpeg

新一代调度框架 Scheduling Framework之解析

社区也逐渐的发现开发者所面临的困境,为了解决如上问题,使Kube-scheduler扩展性更好、代码更简洁,社区从Kubernetes 1.16版本开始, 构建了一种新的调度框架Kubernetes Scheduling Framework的机制。

Scheduling Framework在原有的调度流程中, 定义了丰富扩展点接口,开发者可以通过实现扩展点所定义的接口来实现插件,将插件注册到扩展点。Scheduling Framework在执行调度流程时,运行到相应的扩展点时,会调用用户注册的插件,影响调度决策的结果。通过这种方式来将用户的调度逻辑集成到Scheduling Framework中。

 


1588770446420-61cadc71-8ef0-43c8-ae23-5941bc23a745.png

Framework的调度流程是分为两个阶段scheduling cycle和binding cycle. scheduling cycle是同步执行的,同一个时间只有一个scheduling cycle,是线程安全的。binding cycle是异步执行的,同一个时间中可能会有多个binding cycle在运行,是线程不安全的。

scheduling cycle

scheduling cycle是调度的核心流程,主要的工作是进行调度决策,挑选出唯一的节点。

Queue sort

// QueueSortPlugin is an interface that must be implemented by "QueueSort" plugins.
// These plugins are used to sort pods in the scheduling queue. Only one queue sort
// plugin may be enabled at a time.
type QueueSortPlugin interface {Plugin// Less are used to sort pods in the scheduling queue.Less(*PodInfo, *PodInfo) bool
}

Scheduler中的优先级队列是通过heap实现的,我们可以在QueueSortPlugin中定义heap的比较函数来决定的排序结构。但是需要注意的是heap的比较函数在同一时刻只有一个,所以QueueSort插件只能Enable一个,如果用户Enable了2个则调度器启动时会报错退出。下面是默认的比较函数,可供参考。

// Less is the function used by the activeQ heap algorithm to sort pods.
// It sorts pods based on their priority. When priorities are equal, it uses
// PodQueueInfo.timestamp.
func (pl *PrioritySort) Less(pInfo1, pInfo2 *framework.QueuedPodInfo) bool {p1 := pod.GetPodPriority(pInfo1.Pod)p2 := pod.GetPodPriority(pInfo2.Pod)return (p1 > p2) || (p1 == p2 && pInfo1.Timestamp.Before(pInfo2.Timestamp))
}

PreFilter

PreFilter在scheduling cycle开始时就被调用,只有当所有的PreFilter插件都返回success时,才能进入下一个阶段,否则Pod将会被拒绝掉,标识此次调度流程失败。PreFilter类似于调度流程启动之前的预处理,可以对Pod的信息进行加工。同时PreFilter也可以进行一些预置条件的检查,去检查一些集群维度的条件,判断否满足pod的要求。

Filter

Filter插件是scheduler v1版本中的Predicate的逻辑,用来过滤掉不满足Pod调度要求的节点。为了提升效率,Filter的执行顺序可以被配置,这样用户就可以将可以过滤掉大量节点的Filter策略放到前边执行,从而减少后边Filter策略执行的次数,例如我们可以把NodeSelector的Filter放到第一个,从而过滤掉大量的节点。Node节点执行Filter策略是并发执行的,所以在同一调度周期中多次调用过滤器。

PostFilter

新的PostFilter的接口定义在1.19的版本会发布,主要是用于处理当Pod在Filter阶段失败后的操作,例如抢占,Autoscale触发等行为。

PreScore

PreScore在之前版本称为PostFilter,现在修改为PreScore,主要用于在Score之前进行一些信息生成。此处会获取到通过Filter阶段的节点列表,我们也可以在此处进行一些信息预处理或者生成一些日志或者监控信息。

Scoring

Scoring扩展点是scheduler v1版本中Priority的逻辑,目的是为了基于Filter过滤后的剩余节点,根据Scoring扩展点定义的策略挑选出最优的节点。
Scoring扩展点分为两个阶段:

  1. 打分:打分阶段会对Filter后的节点进行打分,scheduler会调用所配置的打分策略
  2. 归一化: 对打分之后的结构在0-100之间进行归一化处理

Reserve

Reserve扩展点是scheduler v1版本的assume的操作,此处会对调度结果进行缓存,如果在后边的阶段发生了错误或者失败的情况,会直接进入Unreserve阶段,进行数据回滚。

Permit

Permit扩展点是framework v2版本引入的新功能,当Pod在Reserve阶段完成资源预留之后,Bind操作之前,开发者可以定义自己的策略在Permit节点进行拦截,根据条件对经过此阶段的Pod进行allow、reject和wait的3种操作。allow表示pod允许通过Permit阶段。reject表示pod被Permit阶段拒绝,则Pod调度失败。wait表示将Pod处于等待状态,开发者可以设置超时时间。

binding cycle

binding cycle需要调用apiserver的接口,耗时较长,为了提高调度的效率,需要异步执行,所以此阶段线程不安全。

Bind

Bind扩展点是scheduler v1版本中的Bind操作,会调用apiserver提供的接口,将pod绑定到对应的节点上。

PreBind 和 PostBind

开发者可以在PreBind 和 PostBind分别在Bind操作前后执行,这两个阶段可以进行一些数据信息的获取和更新。

UnReserve

UnReserve扩展点的功能是用于清理到Reserve阶段的的缓存,回滚到初始的状态。当前版本UnReserve与Reserve是分开定义的,未来会将UnReserve与Reserve统一到一起,即要求开发者在实现Reserve同时需要定义UnReserve,保证数据能够有效的清理,避免留下脏数据。

实现自己的调度插件

scheduler-plugins

Kubernetes负责Kube-scheduler的小组sig-scheduling为了更好的管理调度相关的Plugin,新建了项目scheduler-plugins 来方便用户管理不同的插件,用户可以直接基于这个项目来定义自己的插件。接下来我们以其中的Qos的插件来为例,演示是如何开发自己的插件。

QoS的插件主要基于Pod的 QoS(Quality of Service) class 来实现的,目的是为了实现调度过程中如果Pod的优先级相同时,根据Pod的Qos来决定调度顺序,调度顺序是: 1. Guaranteed (requests == limits) 2. Burstable (requests < limits) 3. BestEffort (requests and limits not set)

插件构造

首先插件要定义插件的对象和构造函数

// QoSSort is a plugin that implements QoS class based sorting.
type Sort struct{}// New initializes a new plugin and returns it.
func New(_ *runtime.Unknown, _ framework.FrameworkHandle) (framework.Plugin, error) {return &Sort{}, nil
}

然后,根据我们插件要对应的extention point来实现对应的接口,Qos是作用于QueueSort的部分,所以我们要实现QueueSort接口的函数。如下所示,QueueSortPlugin接口只定义了一个函数Less,所以我们实现这个函数即可。

// QueueSortPlugin is an interface that must be implemented by "QueueSort" plugins.
// These plugins are used to sort pods in the scheduling queue. Only one queue sort
// plugin may be enabled at a time.
type QueueSortPlugin interface {Plugin// Less are used to sort pods in the scheduling queue.Less(*PodInfo, *PodInfo) bool
}

实现的函数如下。默认的default QueueSort在比较的时候,首先比较优先级,然后再比较pod的timestamp。我们重新定义了Less函数,在优先级相同的情况下,通过比较Qos来决定优先级。

// Less is the function used by the activeQ heap algorithm to sort pods.
// It sorts pods based on their priority. When priorities are equal, it uses
// PodInfo.timestamp.
func (*Sort) Less(pInfo1, pInfo2 *framework.PodInfo) bool {p1 := pod.GetPodPriority(pInfo1.Pod)p2 := pod.GetPodPriority(pInfo2.Pod)return (p1 > p2) || (p1 == p2 && compQOS(pInfo1.Pod, pInfo2.Pod))
}func compQOS(p1, p2 *v1.Pod) bool {p1QOS, p2QOS := v1qos.GetPodQOS(p1), v1qos.GetPodQOS(p2)if p1QOS == v1.PodQOSGuaranteed {return true} else if p1QOS == v1.PodQOSBurstable {return p2QOS != v1.PodQOSGuaranteed} else {return p2QOS == v1.PodQOSBestEffort}
}

插件注册

我们在启动的main函数中注册自己定义的插件和相应的构造函数

// cmd/main.go
func main() {rand.Seed(time.Now().UnixNano())command := app.NewSchedulerCommand(app.WithPlugin(qos.Name, qos.New),)if err := command.Execute(); err != nil {os.Exit(1)}
}

代码编译

$ make

Scheduler启动

kube-scheduler启动时,配置./manifests/qos/scheduler-config.yaml中kubeconfig的路径,启动时传入集群的kubeconfig文件以及插件的配置文件即可。

$ bin/kube-scheduler --kubeconfig=scheduler.conf --config=./manifests/qos/scheduler-config.yaml

至此,相信大家已经通过我们的介绍和示例了解了Kubernetes Scheduling Framework的架构和开发方法。

后续工作

Kubernetes Scheduling Framework作为调度器的新架构方向,在可扩展性和定制化方面进步很大。基于此Kubernetes可以逐步承载更多类型的应用负载了, 一个平台一套IT架构和技术堆栈的愿景向前演进。同时为了更好的支持数据计算类型的任务迁移到Kubernetes平台中,我们也在努力将数据计算类型中常用Coscheduling/Gang Scheduling、Capacity Scheduling、Dominant Resource Fairness和多队列管理等特性,通过Scheduling Framework的插件机制来融入到原生的Kube-scheduler中。
接下来,本系列文章将围绕AI、大数据处理和高规格计算资源集群等场景,介绍我们是如何开发相应调度器插件的。敬请期待。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTP系列学习(笔记三):HTTP的发展历程思维导图

HTTP&#xff08;HyperText Transfer Protocol&#xff09;是万维网&#xff08;World Wide Web&#xff09;的基础协议。 0.9版本&#xff1a; 1.0版本&#xff1a; 1.1版本&#xff1a; 2.0版本&#xff1a; 2.0进化版本&#xff1a; 为了便于浏览记忆&#xff0c;整理了一份…

为什么说Serverless是云的未来?

作者 | 不瞋 阿里云高级技术专家 每隔几年&#xff0c;IT 界就会出现新突破性的进展。回望整个计算机技术发展史&#xff0c;我们会发现“抽象、解耦、集成”的主题贯穿其中。产业每一次的抽象、解耦、集成&#xff0c;都将创新推向新的高度&#xff0c;也催生出庞大的市场和…

(企业级)HBuilder X 安装蓝叠安卓模拟器

文章目录1. 下载蓝叠模拟器2. 设置 adb链接和root3. 设置竖屏4. 设置uni-app adb 环境变量5. 配置 HBuilderX adb5. 运行6.效果图7.常见模拟器1. 下载蓝叠模拟器 https://www.bluestacks.cn/ 2. 设置 adb链接和root 3. 设置竖屏 4. 设置uni-app adb 环境变量 在 HBuilderX…

小困惑,关于 Serverless 函数计算的字体安装

来源 | Serverless作者 | 孙飞宇头图 | 下载于视觉中国前言首先介绍下在本文出现的几个比较重要的概念&#xff1a;函数计算&#xff08;Function Compute&#xff09;&#xff1a;函数计算是一个事件驱动的服务&#xff0c;通过函数计算&#xff0c;用户无需管理服务器等运行情…

一文带你了解MySQL中的各种锁机制!

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; MySQL中的锁机制,按粒度分为行级锁,页级锁,表级锁&#xff0c;其中按用法还分为共享锁和排他锁. 行级锁 行级锁是Mysql中锁…

for循环中let,var 的经典面试题:for循环中 console.log(i)详解

同学们在刚准备面试时肯定见过一道经典面试题&#xff1a; for(var i 0; i < 10; i) {setTimeOut(function(){console.log(i)}) } // 输出 10 10 10 10 10 10 10 10 10 10for(let i 0; i < 10; i) {setTimeOut(function(){console.log(i)}) } // 输出 0 1 2 3 4 5 6 7…

后疫情时代,银行从数字化转型到智能化“迁徙”

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 全球数据智能趋势一览 笔者在搜索了众多机构发表的数据智能发展趋势报告&#xff0c;并做了筛选和甄别后&#xff0c;参考了公…

普通二本学校软件工程专业本科毕业的女生,没有考研,选择直接就业现如今过得怎样呐?

第一篇程序人生 在进入大学之前买的联想笔记本电脑被我之前放在窗户边&#xff0c;一个月之前去上班的时候忘记关窗户&#xff0c;下大雨给淋雨进水了&#xff0c;刚好开机密码的几个键盘失灵了&#xff0c;上周末在网上买了一个键盘&#xff0c;终于可以开机了&#xff0c;为…

阿里云交通数据中台解决方案打造“数字化生产力”

数字经济时代&#xff0c;计算、分析、处理等作为“关键生产要素”已成为行业和社会的共识。但是对于交通领域而言&#xff0c;以往端到端的方式进行平台搭建和应用开发已不能适应数字爆炸和产品快速迭代的要求。交通行业在计算分析方面面临着信息采集难、样式杂、变化快、价值…

一次讲清楚,七种分布式事务的解决方案

来源 | moon聊技术责编 | 寇雪芹头图 | 下载于视觉中国什么是分布式事务分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器「分别位于不同的分布式系统的不同节点之上」。一个大的操作由N多的小的操作共同完成。而这些小的操作又分布在不同的服务上。针…

SpringCloud应用在Kubernetes上的最佳实践—开发篇

作者 | 孤弋 阿里云高级技术专家&#xff0c;负责 EDAS 的开发和用户体验优化工作。 前言 近年来&#xff0c;云原生、Kubernetes、微服务、SpringCloud 这些名词在技术圈内不绝于耳&#xff0c;数据显示&#xff0c;使用 SpringCloud 作为微服务的框架&#xff0c;同时选择…

支持批任务的Coscheduling/Gang scheduling

作者&#xff1a;王庆璨 张凯 进击的Kubernetes调度系统&#xff08;一&#xff09;&#xff1a;Scheduling Framework 进击的Kubernetes调度系统&#xff08;二&#xff09;&#xff1a;支持批任务的Coscheduling/Gang scheduling 前言 首先我们来了解一下什么是Coscheduli…

ESLint is disabled since its execution has not been approved or denied yet

我的vs code有安装eslint插件&#xff0c;但是不这道为什么这两天很多代码校验都不起作用了 一顿操作猛如虎&#xff0c;最后发现代码开始的时候有一条黄线 爆出了一个错误 ESLint is disabled since its execution has not been approved or denied yet. Use the light bulb…

13种重要的云原生工具,让交付过程更快

来源 | SDNLAB责编 | 寇雪芹头图 | 下载于视觉中国SUSE收购RancherPure Storage收购PortworxVeeam收购KastenVMware收购OctarineMirantis收购Lens IDE思科收购Banzai CloudNew Relic收购Pixie Labs云原生市场趋于整合........以上是过去一年云原生行业发生的并购案&#xff0c;…

后疫情时代企业将加速向云服务迁移

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; LogicMonitor的新调查结果表明&#xff0c;COVID-19已成为企业快速实施云迁移的强大催化剂&#xff0c;尽管整体情况仍在发展…

会话拦截限制一台手机登录

文章目录1. 流程图2. 流程简述1. 流程图 2. 流程简述 1.前端传递userId和token2.后端接收userId和token3.校验userId和token是否为空4.校验任一为空&#xff0c;则提示“请登录后再继续操作&#xff01;”5.不为空&#xff0c;通过UserId从redis中获取token6.redis中的token与…

HTML a链接下载文件之图片,文件,乱码等问题

我们在做需求的时候&#xff0c;经常会遇到下载文件 前端下载文件一般分为两种方式&#xff1a; 使用 a 链接进行下载&#xff1a; <a herf"url" >下载</a>向后端发送请求进行下载&#xff1a; methods:{downloadReport(item,index){let date item.…

冗余云计算连接:保持组织运行

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 在过去的几个月中&#xff0c;人们目睹了组织将其劳动力转移到“在家工作”模式和远程操作的情况。微软公司报告其云计算服务…

杭州湾跨海大桥视频上云,夯实智慧高速“云基建

现阶段&#xff0c;高速公路监控设备覆盖已经有普遍提高&#xff0c;但监控设施的覆盖仅完成了视频的监控功能&#xff0c;没有实现分析提醒功能。传统人工巡检方式工作量大且容易发生事件遗漏、事故发现不及时导致二次事故、人工视频巡检工作量大无法做到实时检测、监控中心绝…

移动端一键登录注册

文章目录1. 用户名密码一键注册登录流程2. 手机号一键注册登录流程1. 用户名密码一键注册登录流程 2. 手机号一键注册登录流程