前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >图解K8s源码 - kube-scheduler篇

图解K8s源码 - kube-scheduler篇

作者头像
才浅Coding攻略
发布于 2022-12-12 10:19:26
发布于 2022-12-12 10:19:26
7410
举报
文章被收录于专栏:才浅coding攻略才浅coding攻略

本篇介绍的是 Kubernetes 系统的核心组件之一——kube-scheduler,它是 k8s 的默认调度器,负责为新创建出来的 pod寻找一个最合适的节点,这里的“最合适”指两种最优解:从集群中的所有节点中找出的全局最优解,和从集群中的部分节点中找出的局部最优解。它们分别可以解决调度器在小型和大型 k8s 集群规模上的性能问题,比如集群中有几百台主机时 kube-scheduler 采用全局最优解,当集群规模大时采用局部最优解。

那“最合适”的含义是指什么呢?它主要是通过两种调度算法的筛选:

  • Predicate(预选):过滤掉不满足条件的节点,选出所有可以运行该 pod 的节点。
  • Scheduler(优选):给上一步得到的结果中的每个节点打分,选出得分最高的节点为最终调度结果。

那怎么表示调度器对一个 pod 调度成功呢?实际上就是将它的 spec.nodeName 字段填上调度结果的节点名字。


Scheduler 调度机制工作原理

Scheduler 是作为单独程序运行的,它在启动之后会一直监听 API Server,获取 spec.nodeName 字段为空的 pod。调度算法执行完之后,调度器将 pod 对象的 nodeName 字段的值改成对应 node 的名字,表明 pod 应该放在哪个节点上。这个步骤在 k8s 中称为 Bind

调度的具体过程可以总结为下图:

Scheduler 实际上就是两个独立的控制循环:

第一个循环(Informer Path)主要目的是启动一系列 informer 来监听(Watch) Etcd 中的 pod、Node、Service 等与调度相关的API对象的变化。比如,一个待调度的 pod 被创建出来之后,调度器就会通过 Pod Informer 的 Handler,将这个待调度的 pod 加入调度队列。

此外,调度器 informer 还要对调度器缓存(Schedule Cache) 进行更新。Predicates 调度算法执行时也是从缓存中取数据,从而提高算法执行效率。

第二个循环(Scheduling Path)主要是不断从调度队列中 pop 出 pod,然后调度器启动多个goroutine,以节点为粒度并发执行 Predicates 算法进行过滤并得到一组节点,即可以运行这个 pod 的宿主机列表。再以 MapReduce 方式并发执行 Priorities 算法为列表中的节点打分,分数从0到10,得分最高的节点会作为这次调度的结果,并完成 Bind 的一系列操作,最后更新 Schedule Cache 里的 pod 和 node 信息。


Scheduler 的优先级和抢占机制

以上是调度机制的工作原理,那如果 pod 调度失败怎么办呢?正常情况下,当一个 pod 调度失败后,就会被暂时搁置处于 pending 状态,直到 pod 被更新或者集群状态发生变化,调度器才会对这个 pod 进行重新调度。但在实际业务场景中存在在线和离线业务之分。如果在线业务的 pod 由于资源不足而调度失败时,在线业务就需要抢占离线业务的资源,此时用到的就是 Scheduler 的优先级和抢占机制了。

  • 优先级:高优先级的 pod 可能比低优先级的 pod 提前出队,从而尽早完成调度过程。
  • 抢占:当一个高优先级的 pod 调度失败时触发调度器的抢占能力,当某个节点上的一个或多个低优先级 pod 被删除之后,待调度的高优先级 pod 就可以被调度到该节点上。

抢占过程简言之就是两步:

  1. 将抢占者 Pod 的 spec.nominatedNodeName 字段设置为被抢占节点的名字。
  2. 在下个调度周期决定是否在被抢占节点上运行。

这样设计的一个重要原因是考虑到调度器只会通过向API Server 发起请求,触发 DELETE API 来删除被抢占的 pod,所以在这些 pod “优雅退出”时间内(默认是30s)其他节点也有可能变成可调度的,或者有新的节点被添加到这个集群中。鉴于优雅退出时期集群的可调度性可能会发生变化,所以把抢占者交给下一个调度周期再处理。

在抢占者等待被调度的过程中,如果有优先级更高的 pod 来抢占同一节点,调度器就会清空原抢占者的 spec.nominatedNodeName 字段,从而允许更高优先级的抢占者执行抢占,这也使得原抢占者本身也有机会去重新抢占其他节点。

那么,Scheduler 的抢占机制是如何设计的呢?一个最重要的设计是调度队列中实现了两个不同的队列:

  • activeQ:存放下一个调度周期需要调度的对象。在集群中新建的 pod 都会入队到 activeQ,调度时也是从 activeQ 中出队。
  • unschedulableQ:存放调度失败的 pod。当 unschedulableQ 里的 pod 更新后,调度器会把这个 pod 移到 activeQ。

抢占基本流程图如下:

  1. 集群中新建的 pod 先放到 activeQ 中经过正常的调度策略进行调度;
  2. 调度失败后,将该 pod 放入 unschedulableQ;
  3. 检查失败原因,已确认抢占能否帮助抢占者找到新节点;
  4. 确定可以抢占后,从 Schedule Cache 中复制所有节点信息,用副本模拟抢占流程(基于影响集群稳定性最小原则,即被抢占的 pod 越少越好,优先级越低越好);
  5. 检查选中的“牺牲者”列表,清理这些 pod 的 nominatedNodeName 字段;
  6. 更新抢占者pod,将 nominatedNodeName 改成第4步选出的 node 名字;
  7. 由于抢占者 pod 已发生了更新,所以给他“重新做人”的机会,重新放入 activeQ 里;
  8. 同时,开启一个新的协程,清理牺牲者 node 上对应的牺牲者 pod。

参考:

《深入剖析kubernetes》

https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/

https://blog.csdn.net/zyxpaomian/article/details/111870568

k8s系列往期文章列表

Kubernetes微服务常见概念及应用

图解K8s源码 - 序章 - K8s组件架构

图解K8s源码 - k8s核心数据结构

图解K8s源码 - kube-apiserver篇

图解K8s源码 - kube-apiserver下的RBAC鉴权机制

图解K8s源码 - kube-controller-manager篇

持续更新中……

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 才浅coding攻略 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
K8S里面的调度整理
K8S是分布式系统里面的操作系统,Pod更像是操作系统里面的进程组,如此以来当一个Pod想要运行的时候,就必须要依赖于K8S的调度策略来完成这些Pod的调度。
灰子学技术
2022/03/29
1.6K0
K8S里面的调度整理
kube-scheduler 优先级与抢占机制源码分析
前面已经分析了 kube-scheduler 的代码逻辑以及 predicates 与 priorities 算法,本节会继续讲 scheduler 中的一个重要机制,pod 优先级与抢占机制(Pod Priority and Preemption),该功能是在 v1.8 中引入的,v1.11 中该功能为 beta 版本且默认启用了,v1.14 为 stable 版本。
田飞雨
2019/12/15
7780
Kubernetes的调度器介绍
Kubernetes中的调度器是kube-scheduler,每次我们在创建Pod的时候都是通过kube-scheduler的调度算法将其调度到合适的Node上。
极客运维圈
2020/03/23
7640
【K8S专栏】Kubernetes调度管理
在日常工作中,每个机场都有调度室,用来管理飞机应该从哪里降落,停在什么地方。在Kubernetes也有这样的调度器,主要作用就是将Pod安排到合适的节点上。
没有故事的陈师傅
2022/09/15
6540
【K8S专栏】Kubernetes调度管理
带你畅游k8s调度器(上):k8s调度器原理解读
k8s 作为云原生最重要的基石之一,她是怎么运作的呢?你是否了解过她是怎么从众多的 node 节点中筛选出符合 pod 的调度节点,这里会从 k8s 的调度原理和流程开始结合源码内容带你了解整个调度过程,并配合一个小的调度实验,让你亲手实现一个简单的k8s调度器。
机械视角
2022/03/14
1.5K0
带你畅游k8s调度器(上):k8s调度器原理解读
深入分析Kubernetes Scheduler的优先级队列
从1.9版本开始,Kubernetes实现了基于Pod优先级的调度队列,一方面提供高优先级的Pod优先被调度的能力,另一方面减轻抢占式调度时潜在的High Priority Pod Starvation的问题,截止Kubernetes 1.10,PriorityPod Feature Gate仍处于Alpha。本文将从源码的层面对PriorityQueue进行深入分析,了解内部的两个Sub-Queue以及在什么情况下操作这两个Sub-Queue的,又是如何操作的,另外也提醒当前实现还可能存在的问题。
Walton
2018/05/13
3.2K2
深入分析Kubernetes Scheduler的优先级队列
【K8s源码品读】011:Phase 1 - kube-scheduler - 了解分配pod的大致流程
在前面,我们了解了Pod调度算法的注册和Informer机制来监听kube-apiserver上的资源变化,今天这一讲,我们就将两者串联起来,看看在kube-scheduler中,Informer监听到资源变化后,如何用调度算法将pod进行调度。
junedayday
2021/08/05
6060
kube-scheduler predicates 与 priorities 调度算法源码分析
在上篇文章kube-scheduler 源码分析中已经介绍了 kube-scheduler 的设计以及从源码角度分析了其执行流程,这篇文章会专注介绍调度过程中 predicates 和 priorities 这两个调度策略主要发生作用的阶段。
田飞雨
2019/12/15
1.3K0
这 8 张图终于把 K8S 调度器讲通透了!
Scheduler 在整个系统中承担了“承上启下”的重要功能。“承上”是指它负责接受 Controller Manager 创建的新 Pod,为其安排 Node;“启下”是指安置工作完成后,目标 Node 上的 kubelet 服务进程接管后续工作。Pod 是 Kubernetes 中最小的调度单元,Pod 被创建出来的工作流程如图所示:
我的小碗汤
2023/03/19
2.7K0
这 8 张图终于把 K8S 调度器讲通透了!
原 深入分析Kubernetes Sche
PriorityQueue PriorityQueue Struct 先看看PriorityQueue的结构定义。 type PriorityQueue struct { lock sync.RWM
Walton
2018/06/20
9180
10.深入k8s:调度的优先级及抢占机制源码分析
上一篇我们将了获取node成功的情况,如果是一个优先pod获取node失败,那么就会进入到抢占环节中,那么抢占环节k8s会做什么呢,抢占是如何发生的,哪些资源会被抢占这些都是我们这篇要研究的内容。
luozhiyun
2020/09/16
1.7K0
10.深入k8s:调度的优先级及抢占机制源码分析
kube-scheduler 源码分析
Kube-scheduler 是 kubernetes 的核心组件之一,也是所有核心组件之间功能比较单一的,其代码也相对容易理解。kube-scheduler 的目的就是为每一个 pod 选择一个合适的 node,整体流程可以概括为三步,获取未调度的 podList,通过执行一系列调度算法为 pod 选择一个合适的 node,提交数据到 apiserver,其核心则是一系列调度算法的设计与执行。
田飞雨
2019/12/15
6210
【K8s源码品读】008:Phase 1 - kube-scheduler - 初探调度的启动流程与算法
聚焦目标 理解kube-scheduler启动的流程 目录 kube-scheduler的启动 Scheduler的注册 了解一个最简单的算法NodeName run // kube-scheduler 类似于kube-apiserver,是个常驻进程,查看其对应的Run函数 func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Option) error { // 根据入参,返回配置cc与调度sch
junedayday
2021/08/05
3240
k8s进阶之pod优先权
Pod 可以有优先级。 优先级表示一个 Pod 相对于其他 Pod 的重要性。 如果一个 Pod 无法被调度,调度程序会尝试抢占(驱逐)较低优先级的 Pod, 以使悬决 Pod 可以被调度。
linus_lin
2024/09/06
1460
k8s进阶之pod优先权
【重识云原生】第六章容器6.3.3节——Kube-Scheduler使用篇
        scheduler是任务调度器,在K8S中实现组件名为kube-scheduler,负责任务调度、选择合适的节点来执行任务。Scheduler 负责决定将 Pod 放在哪个 Node 上运行。Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。它监听 kube-apiserver,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配节点(更新 Pod 的 NodeName 字段)。
江中散人_Jun
2022/09/29
7620
【重识云原生】第六章容器6.3.3节——Kube-Scheduler使用篇
白话K8S核心组件概念
容器是利用了集装箱的思想,把可运行程序打包成可运行、自包含、标准化的镜像。通过K8S能够管理和编排我们打的镜像,举例来说,如果你想运行两个副本,直接在编排文件中配置replicas为2即可,你也可以使用HPA通过检测CPU、内存使用率实现自动扩缩容。
用户5166556
2020/08/20
8240
白话K8S核心组件概念
kube-scheduler调度扩展
Kubernetes 自带了一个默认调度器kube-scheduler,其内置了很多节点预选和优选的调度算法,一般调度场景下可以满足要求。但是在一些特殊场景下,默认调度器不能满足我们复杂的调度需求。我们就需要对调度器进行扩展,以达到调度适合业务场景的目的。
我的小碗汤
2019/05/13
1.5K0
kube-scheduler调度扩展
原 荐 深入分析Kubernetes Sch
Author: xidianwangtao@gmail.com 在Kubernetes 1.8抢占式调度Preemption源码分析中,有好几处我们提到了NominatedPods,当时没有给出足够的分析,今天我们就重点分析一下NominatedPods的意义和原理。 NominatedPods是什么? 当enable PodPriority feature gate后,scheduler会在集群资源资源不足时为preemptor抢占低优先级的Pods(成为victims)的资源,然后preempto
Walton
2018/06/13
1.2K0
Kubernetes K8S之调度器kube-scheduler详解 预选策略(Predicates)优选策略(Priorities)
在 Kubernetes 中,调度是指将 Pod 放置到合适的 Node 节点上,然后对应 Node 上的 Kubelet 才能够运行这些 pod。
踏歌行
2020/10/29
3.3K0
图解K8s源码 - kubelet 篇
我们在之前的文章中介绍了 Master 控制平面中的三大组件:kube-apiserver、kube-controller-manager、kube-scheduler,它们分别负责 k8s 集群的资源访问入口、集群状态管理、集群调度。
才浅Coding攻略
2022/12/12
1.2K0
图解K8s源码 - kubelet 篇
相关推荐
K8S里面的调度整理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档