专栏首页乔边故事Kubernetes的调度器介绍

Kubernetes的调度器介绍

一、原理介绍

Kubernetes中的调度器是kube-scheduler,每次我们在创建Pod的时候都是通过kube-scheduler的调度算法将其调度到合适的Node上。

其工作流程主要如下:

  1. 在集群中所有Node中,根据调度算法挑选出可以运行该Pod的所有Node;
  2. 在上一步的基础上,再根据调度算法给筛选出的Node进行打分,筛选出分数最高的Node进行调度;
  3. 将Pod的spec.nodeName填上调度结果的Node名字;

其工作原理如下图:

由上图可知,Kubernetes的调度器核心是两个相互独立的控制循环。 1、Informer Path 其主要作用是启动一个Informer来监听Etcd中Pod,Node,Service等与调度器相关的API对象的变化。当一个Pod被创建出来后,就被通过Informer Handler将待调度的Pod放入调度队列中,默认情况下,Kubernetes的调度策略是一个优先级队列,并且当集群信息发生变化的时候,调度器还会对调度队列里的内容进行一些特殊操作。而且Kubernetes的默认调度器还负责对调度器缓存(scheduler cache)进行更新,以执行调度算法的执行效率。

2、Scheduler Parh 其主要逻辑是不断从队列中出一个Pod,然后调用Predicates进行过滤,然后得到一组Node(也就是可运行Pod的所有Node信息,这些信息都是来自scheduler cache),接下来调用Priorities对筛选出的Node进行打分,然后分数最高的Node会作为本次调度选择的对象。调度完成后,调度器需要将Pod的spec.nodeName的值修改为调度的Node名字,这个步骤称为Bind。

但是在Bind阶段,Kubernetes默认调度器只会更新scheduler cache中的信息,这种基于乐观假设的API对象更新方式被称为Assume。在Assume之后,调度器才会向API Server发起更新Pod的请求,来真正完成Bind操作。如果本次Bind失败,等到scheduler cache更新之后又会恢复正常。

正是由于有Assume的原因,当一个Pod完成调度需要在某个Node节点运行之前,kubelet还会进行一部Admit操作来验证该Pod是否能够运行在该Node上,作为kubelet的二次验证。

常用的预算策略有:

  • CheckNodeCondition
  • GeneralPredication:

HostName, PodFitsHostPort, MatchNodeSelector, PodFitsResources

  • NoDiskConflict

二、优先级和抢占机制

正常情况下,当一个Pod调度失败后,它会被搁置起来,直到Pod被更新,或者集群状态发生变化,调度器才会对这个Pod进行重新调度。但是有的时候我们不希望一个高优先级的Pod在调度失败就被搁置,而是会把某个Node上的一些低优先级的Pod删除,来保证高优先级的Pod可以调度成功。

Kubernetes中优先级是通过ProrityClass来定义,如下:

apiVersion: scheduling.k8s.io/v1beta1kind: PriorityClassmetadata:  name: high-priorityvalue: 1000000globalDefault: falsedescription: "This priority class should be used for high priority service pods only."

其中的value就是优先级数值,数值越大,优先级越高。优先级是一个32bit的整数,最大值不超过10亿,超过10亿的值是被Kubernetes保留下来作为系统Pod使用的,就是为了保证系统Pod不会被抢占。另外如果globalDefault的值设置为 true的话表明这个PriorityClass的值会成为系统默认值,如果是false就表示只有在申明这个PriorityClass的Pod才会拥有这个优先级,而对于其他没有申明的,其优先级为0。

如下就是一个Pod使用PriotityClass:

apiVersion: v1kind: Podmetadata:  name: nginx  labels:    env: testspec:  containers:  - name: nginx    image: nginx    imagePullPolicy: IfNotPresent  priorityClassName: high-priority

上面的PriotiryClassName就是定义我们的PriorityClass,当这个Pod提交给Kubernetes之后,Kubernetes的PriorityAdmissionController会自动将这个Pod的spec.priority字段设置为我们定义的值。而当这个Pod拥有这个优先级之后,高优先级的Pod就可能比低优先级的Pod先出队,从而尽早完成调度。

而当一个高优先级的Pod调度失败后,其抢占机制就会被触发,这时候调度器就会试图从当前的集群中寻找一个节点,使得这个节点上的一个或多个低优先级的Pod被删除,然后这个高优先级的Pod就可以被调度到这个节点上。 当抢占发生时,这个高优先级Pod并不会立即调度到即将抢占的节点上,调度器只会将这个Pod的spec.nominatedNodeName的值设置为被抢占节点的Node名字,然后这个Pod会重新进入下一个调度周期,然后会在这个周期内决定这个Pod被调度到哪个节点上。在这个重新调度期间,如果有一个更高的优先级Pod也要抢占这个节点,那么调度器就会清空原Pod的nominatedNodeName的值,而更高优先级的Pod将会抢占这个值。

实现原理: Kubernetes用两个队列来实现抢占算法:ActiveQ和unschedulableQ。

  1. ActiveQ:凡是在ActiveQ里的Pod,都是下一个周期需要调度的对象,所以当Kubernetes创建一个新的Pod,这个Pod就会被放入ActiveQ里;
  2. unschedulableQ:专门用来存放调度失败的Pod;

那么如果一个Pod调度失败,调度器就会将其放入unschedulableQ里,然后调度器会检查这个调度失败的原因,分析并确认是否可以通过抢占来解决此次调度问题,如果确定抢占可以发生,那么调度器就会把自己缓存的所有信息都重新复制一份,然后使用这个副本来模拟抢占过程。如果模拟通过,调度器就会真正开始抢占操作了:

  1. 调度器会检查牺牲者列表,清空这些Pod所携带的nominatedNodeName字段;
  2. 调度器会把抢占者的nominatedNodeName的字段设置为被抢占的Node名字;
  3. 调度器会开启Goroutine,同步的删除牺牲者;

接下来调度器就会通过正常的调度流程,把抢占者调度成功。在这个过程中,调度器会对这个Node,进行两次Predicates算法:

  1. 假设上述抢占者已经运行在这个节点上,然后运行Predicates算法;
  2. 调度器正常执行Predicates算法;

只有上述者两个都通过的情况下,这个Node和Pod才会被 绑定。

END.

本文分享自微信公众号 - 乔边故事(qiaobiangushi),作者:乔克

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • kubernetes常用控制器之StatefulSet

    实例之间的不等关系以及实例对外数据有依赖关系的应用,就被称为"有状态应用"。 所谓实例之间的不等关系即对分布式应用来说,各实例,各应用之间往往有比较大的依赖关系...

    极客运维圈
  • Nginx容器配置如何热更新?

    Nginx作为WEB服务器被广泛使用。其自身支持热更新,在修改配置文件后,使用nginx -s reload命令可以不停服务重新加载配置。然而对于Dockeri...

    极客运维圈
  • Kubernetes中网络控制器之NetworkPolicy

    在Kubernetes中,网络隔离功能是通过叫NetworkPolicy的API对象来描述的。 如下一个完整的NetworkPolicy定义:

    极客运维圈
  • Kubernetes Scheduler学习总结

    Kubenetes 的 Scheduler 的作用主要是将等待被调度的 Pod 按照特定的调度算法那和带哦度策略绑定到集群中合适的 Node 上,这个绑定的动作...

    runzhliu
  • 干货 | 10W+ K8s容器数量下,携程如何打造统一弹性调度体系

    本文作者为携程Cloud Container团队的鸿飞,静雪,诗燕。该团队负责K8s容器平台的研发和优化工作,专注于推动基础设施云原生架构升级,以及创新产品的研...

    携程技术
  • 第一次!Apple Watch+微信=……

    北京时间3月10日凌晨, 美国旧金山芳草地艺术中心, 苹果新品发布会。 熬夜的果粉们,突然在屏幕上看到一个熟悉的身影:是的,你没看错,苹果的发布会上第一次出现并...

    腾讯大讲堂
  • 排障集锦:九九八十一难之第十二难!mysql 主从同步error: The slave I/O thread stops because master and slave have equa

    error: The slave I/O thread stops because master and slave have equal MySQL serv...

    不吃小白菜
  • 【LeetCode】1217. Play with Chips

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    韩旭051
  • PerfDog可以助力高帧率游戏生态更全面发展

    Ace2拥有强大的配置:高通骁龙865 SOC、LPDDR5高速内存、4D恒冷散热、65W有线+40W无线快速充电等;

    WeTest质量开放平台团队
  • 没想到啊!2599元的Java干货今天免费送

    2018年,互联网行业风起云涌,IT工程师如果仅凭传统开发思维,无法突破固有知识体系,终将会被社会所淘汰。既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给...

    哲洛不闹

扫码关注云+社区

领取腾讯云代金券