30. K8s 核心组件讲解——Scheduler

本章讲解知识点

  • Scheduler 概述
  • Scheduler 原理分析
  • Scheduler 旧版本的两阶段调度流程
  • Scheduler Framework

1. Scheduler 概述

Kubernetes Scheduler 是 Kubernetes 集群中的一个核心组件,用于将 Pod 调度到适合的 Node 上运行。在 Kubernetes 中,Pod 是最小的可调度单元,而 Node 则是运行 Pod 的物理或虚拟机器。调度器负责决定每个 Pod 应该在哪个 Node 上运行,以最大程度地利用集群资源,并满足用户定义的调度策略。

Kubernetes Scheduler 通过调度算法和策略来实现 Pod 的调度。调度算法可以是优先级调度、公平调度、权重调度等,而策略可以是节点亲和性、Pod 亲和性、污点容忍等。在进行调度时,Scheduler 会考虑一系列因素,如节点资源利用率、Pod 资源需求、节点亲和性、Pod 亲和性、污点容忍等,来确定最佳的调度方案。

除了默认的调度器之外,Kubernetes 还允许用户使用自定义调度器来满足特定的调度需求,例如将 Pod 调度到 GPU 节点或者将 Pod 调度到特定的地理位置。

Kubernetes Scheduler 通过一个名为 kube-scheduler 的进程提供服务,该进程运行在 Master 上。属于静态 pod。

[root@master mtuser]# kubectl get pod -A | grep kube-sch
kube-system   kube-scheduler-master              1/1     Running   6          26d

<br>

2. Scheduler 原理分析

Kubernetes Scheduler 在整个系统中承担了"承上启下"的重要功能。承上,是指它负责接收 Controller Manager 创建的新 Pod,为其安排一个落脚的“家”, 即目标 Node。当 Kubernetes 集群中出现新的 Pod 时,这些 Pod 会被 Kubernetes API Server 接收到并记录在 Etcd 中,而 Kubernetes Scheduler 会从 API Server 获取待调度的 Pod 列表以及可用的 Node 列表,并根据调度算法和策略将 Pod 绑定到某个合适的 Node 上,同时将绑定信息更新到 Etcd 中启下,是指安置工作完成后,目标 Node 上的 kubelet 服务进程接管后继工作,负责 Pod 生命周期中的“下半生”。当 Scheduler 绑定 Pod 到 Node 后,获取对应的 Pod 清单,下载 Image 镜像,kubelet 服务会检查 Node 上是否存在所需的容器镜像,如果不存在则会从镜像仓库中下载对应的镜像,并创建容器运行 Pod 中定义的容器,然后将 Pod 的状态更新到 API Server 中。如果节点上已经存在所需的容器镜像,则 kubelet 会直接创建容器,并更新 Pod 的状态。

在整个调度过程中涉及三个对象,分别是:待调度 Pod 列表可用 Node 列表,以及调度算法和策略。完整的流程如下所示:

Kubernetes Scheduler 只跟 API Server 打交道,其输入和输出如下:

  • 输入:待调度的 Pod 和全部计算节点的信息。
  • 输出:目标 Pod 要 “安家” 的最优节点(或者暂时不存在)。

<br>

3. Scheduler 旧版本的两阶段调度流程

3.1 总述

Scheduler 两阶段流程分为过滤(Filtering)+ 打分(Scoring),随后就是绑定目标节点,完成调度。

  1. 过滤阶段:即遍历所有目标 Node,通过过滤器 Predicates 筛选出符合要求的候选节点,过滤掉不符合的 Node,例如过滤掉已经被标记为不可调度的节点、资源不足的节点或者无法满足 Pod 硬件需求的节点等,留下符合的 Node 列表,列表通常会有多个候选节点提供调度,从而进入打分阶段;如果列表为空,表示当前没有符合调度的 Node,Pod 会维持在 Pending 状态。
  2. 打分阶段:在过滤阶段通过筛选之后,Scheduler 会对筛选后的节点进行打分(Scoring)。采用优选策略(xxx Priorities)计算出每个候选节点的积分,积分最高者胜出,作为最佳调度节点。Scheduler 就会将 Pod 调度至该节点。

过滤阶段中,Kubernetes Scheduler 使用 Predicates 过滤器来检测每个可用节点的特征,比如磁盘(NoDiskConflict)、主机(PodFitsHost)、节点上的可用端口(PodFitsPorts)、节点标签(CheckNodeLabelPresence)、CPU 和内存资源(PodFitsResources)、服务亲和性(CheckServiceAffinity)等。

打分阶段中,Kubernetes Scheduler 使用 Priorities 优选策略来对满足条件的 Node 节点进行打分。最常用的 Priorities 策略包括 LeastRequestedPriority(选出资源消耗最小的节点)、BalanceResourceAllocation(选出各项资源使用率最均衡的节点)以及 CalculateNodeLabelPriority(优先选择含有指定标签的节点)等。

PredicatesPriority 的组合被称为 Kubernetes Scheduler Policies,是 Kubernetes Scheduler 调度决策的核心机制。

3.2 Predicates 过滤器详细说明

下面对常用 Predicates 过滤器进行说明

1.NoDiskConflict

用于检测一个 Pod 在调度到某个节点时是否会与该节点上已经运行的其他 Pod 发生磁盘冲突。具体而言,该过滤器会检查节点上已经存在的 Pod 使用的挂载路径,如果新的 Pod 与现有的 Pod 的挂载路径冲突,则该节点将被过滤掉,不会被调度器选为目标节点。

2.PodFitsResources

用于检查一个 Node 是否有足够的 CPU 和内存资源来运行一个 Pod。在调度过程中,Pod 通常会指定它的 CPU 和内存资源需求(即 requests)和限制(即 limits)。Scheduler 会根据这些需求和限制,检查每个 Node 上已经被占用和可用的资源,然后过滤掉那些没有足够可用资源的 Node。检测过程如下:

  • 计算备选 Pod 和节点中已存在 Pod 的所有容器的需求资源(内存和 CPU)的总和。
  • 获得备选节点的状态信息,其中包含节点的资源信息。
  • 如果备选 Pod 和节点中已存在 Pod 的所有容器的需求资源(内存和 CPU)的总和,超出了备选节点拥有的资源,则返回 false,表明备选节点不适合备选 Pod,否则返回 true,表明备选节点适合备选 Pod。

3.PodSelectorMatches

用于检查一个 Node 是否满足 Pod 的 Label Selector 条件。当一个 Pod 被创建时,它可以通过设置 Label Selector 来要求 Kubernetes Scheduler 将它调度到特定的 Node 上。PodSelectorMatches 就是用来检查当前 Node 上的标签是否与 Pod 的 Label Selector 匹配,如果匹配成功,则表示该 Node 可以作为 Pod 的调度目标。检测过程如下:

  • 如果 Pod 没有指定 spec.nodeSelector 标签选择器,则返回 true。
  • 否则,获得备选节点的标签信息,判断节点是否包含备选 Pod 的标签选择器 (spec.nodeSelector) 所指定的标签,如果包含,则返回 true,否则返回 false。

4.PodFitsHost

判断备选 Pod 的 spec.nodeName 域所指定的节点名称和备选节点的名称是否一致,如果一致,则返回 true,否则返回 false。

5.CheckNodeLabelPresence

如果用户在配置文件中指定了该策略,则 Scheduler 会通过 RegisterCustomFitPredicate 方法注册该策略。用于检查节点是否有指定的标签。这个策略会根据 Pod 的 spec.nodeSelector 字段指定的节点选择器来筛选出一批符合要求的节点,然后根据 spec.nodeSelectorRequirements 字段来对这批节点进行进一步的筛选。

  • 读取备选节点的标签列表信息。
  • 如果策略配置的标签列表存在于备选节点的标签列表中,且策略配置的 presence 值为 false,则返回 false,否则返回 true;如果策略配置的标签列表不存在于备选节点的标签列表中,且策略配置的 presence 为 true,则返回 false,否则返回 true。

6.CheckServiceAffinity

CheckServiceAffinity 是 Kubernetes Scheduler 中的一个函数,用于检查 Pod 是否满足服务亲和性(Service Affinity)的要求。具体而言,它会检查以下几个方面:

  • Pod 的标签是否满足 PodAffinity 和 PodAntiAffinity 中定义的要求。
  • Pod 是否与当前节点上已经运行的 Pod 存在亲和性或反亲和性关系。
  • Pod 是否与当前节点上的某个服务存在亲和性或反亲和性关系。

7.PodFitsPorts

用于判断节点是否有足够的可用端口以满足 Pod 的端口请求。在 Kubernetes 中,每个 Pod 都可以定义多个容器,每个容器可以分配一个或多个端口来提供服务。当 Pod 被调度到节点上时,调度器需要检查节点上是否有足够的可用端口来分配给 Pod 中的所有容器。

如果节点上没有足够的可用端口,则 Pod 将无法正常运行。PodFitsPorts 函数会检查节点上的可用端口数是否大于或等于 Pod 中所有容器所需的端口数量之和。如果是,则返回 true;否则,返回 false。

3.3 Priorities 详细说明

Scheduler 中的优选策略包含:LeastRequestedPriority、CalculateNodeLabelPriority 和 BalancedResourceAllocation 等。

每个节点通过优选策略时都会算出一个得分,计算各项得分,最终选出得分值最大的节点作为优选的结果(也是调度算法的结果)。

1.LeastRequestedPriority

优先从备选节点列表中选择资源消耗最小的节点(CPU + 内存)。

2.CalculateNodeLabelPriority

用于计算节点之间的优先级,以选择最佳的节点来调度Pod。该函数首先通过检查 PodSpec 中的 nodeSelector 和 nodeAffinity 字段,查找与 Pod 匹配的节点。如果匹配,则返回优先级 1.0;如果未匹配,则返回 0.0。

接下来,如果 Pod 定义了 PodAffinity 或 PodAntiAffinity 规则,则计算这些规则并将其加入到优先级中。如果 PodAffinity 规则满足,则返回优先级 1.0;如果 PodAntiAffinity 规则不满足,则返回 0.0。

最后,函数检查 PodSpec 中的 tolerations 字段,并将其与节点的 taints 匹配。如果所有的污点都被容忍,则将 0.1 添加到优先级中。通过这个计算过程,CalculateNodeLabelPriority 函数返回一个介于 0.0 到 1.0 之间的优先级值,越高表示越适合调度。

3.BalancedRe

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

云计算面试题全解析 文章被收录于专栏

本专刊适合于立志转行云计算的小白,有一定的编程、操作系统、计算机网络、数据结构、算法基础。 本专刊同时也适合于面向云计算(Docker + Kubernetes)求职的从业者。 本专刊囊括了云计算、VMWare、Docker、Kubernetes、Containerd等一系列知识点的讲解,并且最后总

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务