kube-scheduler工作原理

Kube-scheduler调度概述

Kubemetes Scheduler 在整个系统中承担了承上启下的重要功能,承上是指它负责接收Controller Manager 创建的新Pod,为其安排一个落脚的家(目标 Node);启下是指安置工作完成后,目标 Node 上的 kubelet 服务进程接管后继工作,负责 Pod 生命周期中的下半生。

具体来说,Kubernetes Scheduler的作用是将待调度的Pod按照特定的调度算法和调度策略绑定到集群的某个合适的Node上,并将绑定信息存储到etcd中。

在整个调度过程中设计三个调度对象,分别是:带调度的Pod列表、可用的Node列表、调度算法策略。

简单地说,就是通过调度算法策略为待调度Pod列表中每个Pod 从Node 列表中选择一个最适合的 Node 。随后节点上的kubelet通过API Server监听到Kubernetes scheduler产生的Pod绑定事件,获取对应的Pod清单,下载image镜像,并启动容器。

流程图如下:

 

关键问题

我们已经弄清楚kube-scheduler在做调度这件事。那问题来了,

  1. 为什么要做调度这件事呢?
  2. Kube-scheduler是怎么解决调度这个问题的?
  3. kube-scheduler又是如何通过代码去实现的呢?

为什么要做调度

如果只是单个节点,我认为操作系统自身的调度机制能够帮助我们解决了资源分配的问题。但是大的环境下我们采用了分布式服务,将进程部署在多台节点上组成一个集群提供服务。这时候资源如何进行分配就成了一个问题。这是一个大的背景。那我们从技术角度上去看,你无非就是要将进程部署到不同节点嘛,随机分配下不就好了吗,还需要用个调度吗?我们知道不同的业务功能在微服务的情况下可能对应不同的进程,不同的业务逻辑对于进程的资源要求也会不一样。如何我们随机分配进程到节点上,很容易就出现各个节点资源不平均,最终导致整个系统的不稳定。

如何进行调度

一般情况下,我们可能会考虑,根据资源的要求去判断节点资源是否满足,如果满足则指定为该节点。咋一看好像问题不大,那实际上pod的调度却要考虑到方方面面

  1. pod的资源依赖类型过多,CPU,内存,磁盘,网络带宽等,这些都需要我们考虑进去
  2. 如果只是简单的判断,也同样容易造成某个节点出现资源过载的情况,是否能够各个节点资源使用保持一个相对平衡的状态
  3. 当需要调度的pod数量和资源节点数过多的时候,我们是否能够进行一个高效正确的调度决策?

调度流程

controller-manager创建了deployment对应的pod资源,而这个pod实际上却不知道应该去哪个节点上。那kube-scheduler实际要做的可以看成三个步骤。

  1. 获取未调度podList
  2. 通过调度算法选择一个合适的node
  3. 选择完成后,通过apiserver更新数据

 重点是第二个步骤,调度算法是如何选择一个合适的node呢?

整个调度的一个过程:

  1. 预选阶段,过滤节点,调度器用一组规则过滤掉不符合要求的 Node 节点,比如 Pod 设置了资源的 request,那么可用资源比 Pod 需要的资源少的主机显然就会被过滤掉
  2. 优选阶段,为节点的优先级打分,将上一阶段过滤出来的 Node 列表进行打分,调度器会考虑一些整体的优化策略,比如把 Deployment 控制的多个 Pod 副本分布到不同的主机上,使用最低负载的主机等等策略
  3. 没有合适的node判断是否启动抢占机制
  4. 更新本地缓存,指定pod的nodename为调度计算出来的节点
  5. 最后通完成一个bind步骤。

预选阶段,优选阶段和抢占机制是整个调度的重要实现逻辑,我们可以具体看看这几个机制具体是怎样的。

预选阶段

预选策略(Predicates)

过滤条件包含如下:

PodFitsHostPorts:检查Pod容器所需的HostPort是否已被节点上其它容器或服务占用。如果已被占用,则禁止Pod调度到该节点。

PodFitsHost:检查Pod指定的NodeName是否匹配当前节点。

PodFitsResources:检查节点是否有足够空闲资源(例如CPU和内存)来满足Pod的要求。

PodMatchNodeSelector:检查Pod的节点选择器(nodeSelector)是否与节点(Node)的标签匹配

NoVolumeZoneConflict:对于给定的某块区域,判断如果在此区域的节点上部署Pod是否存在卷冲突。

NoDiskConflict:根据节点请求的卷和已经挂载的卷,评估Pod是否适合该节点。

MaxCSIVolumeCount:决定应该附加多少CSI卷,以及该卷是否超过配置的限制。

CheckNodeMemoryPressure:如果节点报告内存压力,并且没有配置异常,那么将不会往那里调度Pod。

CheckNodePIDPressure:如果节点报告进程id稀缺,并且没有配置异常,那么将不会往那里调度Pod。

CheckNodeDiskPressure:如果节点报告存储压力(文件系统已满或接近满),并且没有配置异常,那么将不会往那里调度Pod。

CheckNodeCondition:节点可以报告它们有一个完全完整的文件系统,然而网络不可用,或者kubelet没有准备好运行Pods。如果为节点设置了这样的条件,并且没有配置异常,那么将不会往那里调度Pod。

PodToleratesNodeTaints:检查Pod的容忍度是否能容忍节点的污点。

CheckVolumeBinding:评估Pod是否适合它所请求的容量。这适用于约束和非约束PVC。

优选阶段

 优选策略(Priorities)

过滤条件包含如下:

SelectorSpreadPriority:对于属于同一服务、有状态集或副本集(Service,StatefulSet or ReplicaSet)的Pods,会将Pods尽量分散到不同主机上。

InterPodAffinityPriority:策略有podAffinity和podAntiAffinity两种配置方式。简单来说,就说根据Node上运行的Pod的Label来进行调度匹配的规则,匹配的表达式有:In, NotIn, Exists, DoesNotExist,通过该策略,可以更灵活地对Pod进行调度。

LeastRequestedPriority:偏向使用较少请求资源的节点。换句话说,放置在节点上的Pod越多,这些Pod使用的资源越多,此策略给出的排名就越低。

MostRequestedPriority:偏向具有最多请求资源的节点。这个策略将把计划的Pods放到整个工作负载集所需的最小节点上运行。

RequestedToCapacityRatioPriority:使用默认的资源评分函数模型创建基于ResourceAllocationPriority的requestedToCapacity。

BalancedResourceAllocation:偏向具有平衡资源使用的节点。

NodePreferAvoidPodsPriority:根据节点注释scheduler.alpha.kubernet .io/preferAvoidPods为节点划分优先级。可以使用它来示意两个不同的Pod不应在同一Node上运行。

NodeAffinityPriority:根据preferredduringschedulingignoredingexecution中所示的节点关联调度偏好来对节点排序。

TaintTolerationPriority:根据节点上无法忍受的污点数量,为所有节点准备优先级列表。此策略将考虑该列表调整节点的排名。

ImageLocalityPriority:偏向已经拥有本地缓存Pod容器镜像的节点。

ServiceSpreadingPriority:对于给定的服务,此策略旨在确保Service的Pods运行在不同的节点上。总的结果是,Service对单个节点故障变得更有弹性。

EqualPriority:赋予所有节点相同的权值1。

EvenPodsSpreadPriority:实现择优 pod的拓扑扩展约束

 抢占机制

抢占 (Preemption) 指的是终止低优先级的 Pods 以便高优先级的 Pods 可以 调度运行的过程。

Pod 被创建后会进入队列等待调度。 调度器从队列中挑选一个 Pod 并尝试将它调度到某个节点上。 如果没有找到满足 Pod 的所指定的所有要求的节点,则触发对悬决 Pod 的抢占逻辑。 让我们将悬决 Pod 称为 P。抢占逻辑试图找到一个节点, 在该节点中删除一个或多个优先级低于 P 的 Pod,则可以将 P 调度到该节点上。 如果找到这样的节点,一个或多个优先级较低的 Pod 会被从节点中驱逐。 被驱逐的 Pod 消失后,P 可以被调度到该节点上。

调度流程概览

Policy

Scheduler 的调度策略启动配置目前支持三种方式,配置文件 / 命令行参数 / ConfigMap。调度策略可以配置指定调度主流程中要用哪些过滤器 (Predicates)、打分器 (Priorities) 、外部扩展的调度器 (Extenders),以及最新支持的 SchedulerFramwork 的自定义扩展点 (Plugins)。

Informer

Scheduler 在启动的时候通过 K8s 的 informer 机制以 List+Watch 从 kube-apiserver 获取调度需要的数据例如:Pods、Nodes、Persistant Volume(PV), Persistant Volume Claim(PVC) 等等,并将这些数据做一定的预处理作为调度器的的 Cache。

调度流水线

通过 Informer 将需要调度的 Pod 插入 Queue 中,Pipeline 会循环从 Queue Pop 等待调度的 Pod 放入 Pipeline 执行。

调度流水线 (Schedule Pipeline) 主要有三个阶段:Scheduler Thread,Wait Thread,Bind Thread。

  1. Scheduler Thread 阶段: 从如上的架构图可以看到 Schduler Thread 会经历 Pre Filter -> Filter -> Post Filter-> Score -> Reserve,可以简单理解为 Filter -> Score -> Reserve。

Filter 阶段用于选择符合 Pod Spec 描述的 Nodes;Score 阶段用于从 Filter 过后的 Nodes 进行打分和排序;Reserve 阶段将 Pod 跟排序后的最优 Node 的 NodeCache 中,表示这个 Pod 已经分配到这个 Node 上, 让下一个等待调度的 Pod 对这个 Node 进行 Filter 和 Score 的时候能看到刚才分配的 Pod。

  1. Wait Thread 阶段: 这个阶段可以用来等待 Pod 关联的资源的 Ready 等待,例如等待 PVC 的 PV 创建成功,或者 Gang 调度中等待关联的 Pod 调度成功等等;
  1. Bind Thread 阶段: 用于将 Pod 和 Node 的关联持久化 Kube APIServer。

整个调度流水线只有在 Scheduler Thread 阶段是串行的一个 Pod 一个 Pod 的进行调度,在 Wait 和 Bind 阶段 Pod 都是异步并行执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes(简称K8s)是一个用于自动化容器操作的开源平台。它主要由一系列核心组件组成,包括kube-apiserver、kube-schedulerkube-controller-manager和kubelet,以及用于存储和网络的etcd和kube-proxy。 首先,kube-apiserver是Kubernetes的核心组件之一,它提供了Kubernetes API的接口,用于管理集群的各种操作和资源。 其次,kube-scheduler负责决定将哪个Pod分配到哪个Node上运行。它会根据节点资源的使用情况、健康状况和Pod的约束条件等因素进行调度决策。 kube-controller-manager包含了多个控制器,用于监控并保证集群中的各种资源的状态保持在预期的状态。例如,Replication Controller用于对应用程序进行水平扩展和自动恢复,Namespace Controller用于管理命名空间,Service Account和Endpoint Controller则用于管理Service和Endpoint等资源。 kubelet是运行在每个Node上的代理组件,它负责管理Node上的容器和Pod。它会从kube-apiserver获取Pod的配置信息,并根据这些信息来管理容器的生命周期,同时还会主动上报节点的状态和资源使用情况给kube-apiserver。 etcd是Kubernetes中的分布式键值存储系统,用于存储集群的状态和配置信息。它为整个集群的各种组件提供数据的持久性存储和共享。 kube-proxy是负责在集群的Node节点上实现Kubernetes Service的代理组件。它通过监听kube-apiserver中Service和Endpoint的变化,动态地将访问Service的请求转发到后端的Pod上。 总体来说,Kubernetes工作原理是基于Master-Slave架构的,Master节点上的核心组件负责管理整个集群的状态和配置,而Node节点上的kubelet和kube-proxy则负责管理容器和服务的运行。通过这些组件之间的协同工作,Kubernetes实现了容器的自动化部署、伸缩、调度和管理,提供了高可用、高效、可靠的容器环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值