其他分享
首页 > 其他分享> > 如何实现schedule水平扩展

如何实现schedule水平扩展

作者:互联网

基于kubernetes调度框架的自定义调度器实现

kube-scheduler 是 kubernetes 的核心组件之一,主要负责整个集群资源的调度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理、更加充分的利用集群的资源,这也是我们选择使用 kubernetes 一个非常重要的理由。如果一门新的技术不能帮助企业节约成本、提供效率,我相信是很难推进的。

调度流程

默认情况下,kube-scheduler 提供的默认调度器能够满足我们绝大多数的要求,我们前面和大家接触的示例也基本上用的默认的策略,都可以保证我们的 Pod 可以被分配到资源充足的节点上运行。但是在实际的线上项目中,可能我们自己会比 kubernetes 更加了解我们自己的应用,比如我们希望一个 Pod 只能运行在特定的几个节点上,或者这几个节点只能用来运行特定类型的应用,这就需要我们的调度器能够可控。

kube-scheduler 的主要作用就是根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上去,是一个独立的二进制程序,启动之后会一直监听 API Server,获取到 PodSpec.NodeName 为空的 Pod,对每个 Pod 都会创建一个 binding。

 

kube-scheduler structrue

这个过程在我们看来好像比较简单,但在实际的生产环境中,需要考虑的问题就有很多了:

考虑到实际环境中的各种复杂情况,kubernetes 的调度器采用插件化的形式实现,可以方便用户进行定制或者二次开发,我们可以自定义一个调度器并以插件形式和 kubernetes 进行集成。

kubernetes 调度器的源码位于 kubernetes/pkg/scheduler 中,大体的代码目录结构如下所示:(不同的版本目录结构可能不太一样)

kubernetes/pkg/scheduler
-- scheduler.go         //调度相关的具体实现
|-- algorithm
|   |-- predicates      //节点筛选策略
|   |-- priorities      //节点打分策略
|-- algorithmprovider
|   |-- defaults         //定义默认的调度器

其中 Scheduler 创建和运行的核心程序,对应的代码在 pkg/scheduler/scheduler.go,如果要查看kube-scheduler 的入口程序,对应的代码在 cmd/kube-scheduler/scheduler.go

自定义调度器

一般来说,我们有4种扩展 Kubernetes 调度器的方法。

  1. 一种方法就是直接 clone 官方的 kube-scheduler 源代码,在合适的位置直接修改代码,然后重新编译运行修改后的程序,当然这种方法是最不建议使用的,也不实用,因为需要花费大量额外的精力来和上游的调度程序更改保持一致。

  2. 第二种方法就是和默认的调度程序一起运行独立的调度程序,默认的调度器和我们自定义的调度器可以通过 Pod 的 spec.schedulerName 来覆盖各自的 Pod,默认是使用 default 默认的调度器,但是多个调度程序共存的情况下也比较麻烦,比如当多个调度器将 Pod 调度到同一个节点的时候,可能会遇到一些问题,

    1. 因为很有可能两个调度器都同时将两个 Pod 调度到同一个节点上去,但是很有可能其中一个 Pod 运行后其实资源就消耗完了;
    2. 并且维护一个高质量的自定义调度程序也不是很容易的,因为我们需要全面了解默认的调度程序,整体 Kubernetes 的架构知识以及各种 Kubernetes API 对象的各种关系或限制。
  3. 第三种方法是调度器扩展程序,这个方案目前是一个可行的方案,可以和上游调度程序兼容,所谓的调度器扩展程序其实就是一个可配置的 Webhook 而已,里面包含 过滤器 和 优先级 两个端点,分别对应调度周期中的两个主要阶段(过滤和打分)。在我们现在的 v1.16 版本中上面的 调度器扩展程序 也已经被废弃了,2022年4月1日后也被移除了。

Kubernetes 开始只提供了 Extender ,通过部署一个 Web 服务实现无侵入式扩展 scheduler插件,但其存在以下几个问题:

  1. **Extender 扩展点的数量是有限的:**在调度期间只有“Filter”和“Prioritize”扩展点。 “Preempt”扩展点在运行默认抢占机制后被调用。“Bind”扩展点用于绑定Pod,且 Bind 扩展点只能绑定一个扩展程序,扩展点会替换掉调度器的 bind 操作。Extender 不能在其他点被调用,例如,不能在运行 predicate 函数之前被调用。
  2. **性能问题:**对扩展程序的每次调用都涉及 JSON 的编解码。调用 webhook(HTTP 请求)也比调用原生函数慢。
  3. **调度器无法通知 Extender 已中止 Pod 的调度。**例如,如果一个 Extender 提供了一个集群资源,而调度器联系了 Extender 并要求它为正在调度的 pod 提供资源的实例,然后调度器在调度 pod 时遇到错误并决定中止调度,那么将很难与扩展程序沟通错误并要求它撤消资源的配置。
  4. 由于当前的Extender作为一个单独的进程运行,因此不能使用调度器的缓存。要么从 API Server构建自己的缓存,要么只处理他们从调度器接收到的信息。
  1. 第四种方法是通过调度框架(Scheduling Framework),Kubernetes v1.15 版本中引入了可插拔架构的调度框架,使得定制调度器这个任务变得更加的容易。调库框架向现有的调度器中添加了一组插件化的 API,该 API 在保持调度程序“核心”简单且易于维护的同时,使得大部分的调度功能以插件的形式存在,而且在我们现在的 v1.16 版本中上面的 调度器扩展程序 也已经被废弃了,2022年4月1日后也被移除了,所以以后调度框架才是自定义调度器的核心方式。

    Scheduling Framework 调度框架是一组新的“插件”API,通过这些 API 允许将许多调度功能使用插件实现,同时保持调度器“核心”简单和可维护。调度器插件必须用 Go 编写,并使用 Kubernetes 调度器代码编译,有一定学习成本。

这里我们可以简单介绍下调度框架(Scheduling Framework)方式的实现。

  TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back     此页面的语言为中文(简体)   翻译为          

标签:schedule,程序,扩展,调度,水平,scheduler,Pod,节点
来源: https://www.cnblogs.com/gaoyuechen/p/16528329.html