Kubernetes调度概念与工作流程

本文深入解析Kubernetes调度程序的工作原理,包括预选(过滤)和优选(打分)阶段,详细介绍了如何为Pod选择节点,涉及过滤策略如资源需求、亲和性和反亲和性,以及调度器的决策流程。同时,探讨了kube-scheduler的启动流程和调度框架的组件交互。
摘要由CSDN通过智能技术生成

kubernetes集群中的调度程序 kube-scheduler 会 watch 未分配节点的新创建的Pod,并未该Pod找到可运行的最佳(特定)节点。那么这些动作或者说这些原理是怎么实现的呢,让我们往下剖析下。

对于新创建的 pod 或其他未调度的 pod来讲,kube-scheduler 选择一个最佳节点供它们运行。但是,Pod 中的每个容器对资源的要求都不同,每个 Pod 也有不同的要求。因此,需要根据具体的调度要求对现有节点进行过滤。

在Kubernetes集群中,满足 Pod 调度要求的节点称为可行节点 ( feasible nodes FN ) 。如果没有合适的节点,则 pod 将保持未调度状态,直到调度程序能够放置它。也就是说,当我们创建Pod时,如果长期处于 Pending 状态,这个时候应该看你的集群调度器是否因为某些问题没有合适的节点了

调度器为 Pod 找到 FN 后,然后运行一组函数对 FN 进行评分,并在 FN 中找到得分最高的节点来运行 Pod。

调度策略在决策时需要考虑的因素包括个人和集体资源需求、硬件/软件/策略约束 ( constraints )、亲和性 ( affinity ) 和反亲和性( anti-affinity )规范、数据局部性、工作负载间干扰等。

如何为pod选择节点?

kube-scheduler 为pod选择节点会分位两部:

Filtering
Scoring

过滤也被称为预选 ( Predicates ),该步骤会找到可调度的节点集,然后通过是否满足特定资源的请求,例如通过 PodFitsResources 过滤器检查候选节点是否有足够的资源来满足 Pod 资源的请求。这个步骤完成后会得到一个包含合适的节点的列表(通常为多个),如果列表为空,则Pod不可调度。

打分也被称为优选( Priorities ),在该步骤中,会对上一个步骤的输出进行打分,Scheduer 通过打分的规则为每个通过 Filtering 步骤的节点计算出一个分数。

完成上述两个步骤之后, kube-scheduler 会将Pod分配给分数最高的 Node,如果存在多个相同分数的节点,会随机选择一个。

kubernetes的调度策略

Kubernetes 1.21之前版本可以在代码 kubernetes\pkg\scheduler\algorithmprovider\registry.go 中看到对应的注册模式,在1.22 scheduler 更换了其路径,对于registry文件更换到了 kubernetes\pkg\scheduler\framework\plugins\registry.go ;对于kubernetes官方说法为, 调度策略是用于“预选” ( Predicates )或 过滤( filtering ) 和 用于 优选( Priorities )或 评分 ( scoring )的

注:kubernetes官方没有找到预选和优选的概念,而Predicates和filtering 是处于预选阶段的动词,而Priorities和scoring是优选阶段的动词。后面用PF和PS代替这个两个词。

上面也提到了, filtering 的目的是为了排除(过滤)掉不满足 Pod 要求的节点。例如,某个节点上的闲置资源小于 Pod 所需资源,则该节点不会被考虑在内,即被过滤掉。在 “Predicates” 阶段实现的 filtering 策略,包括:

  • NoDiskConflict :评估是否有合适Pod请求的卷
  • NoVolumeZoneConflict :在给定zone限制情况下,评估Pod请求所需的卷在Node上是否可用
  • PodFitsResources :检查空闲资源(CPU、内存)是否满足Pod请求
  • PodFitsHostPorts :检查Pod所需端口在Node上是否被占用
  • HostName : 过滤除去, PodSpec 中 NodeName 字段中指定的Node之外的所有Node。
  • MatchNodeSelector :检查Node的 label 是否与 Pod 配置中 nodeSelector 字段中指定的 label 匹配,并且从 Kubernetes v1.2 开始, 如果存在 nodeAffinity 也会匹配。
  • CheckNodeMemoryPressure :检查是否可以在已出现内存压力情况节点上调度 Pod。
  • CheckNodeDiskPressure :检查是否可以在报告磁盘压力情况的节点上调度 Pod

具体对应得策略可以在 kubernetes\pkg\scheduler\framework\plugins\registry.go 看到

通过上面步骤过滤过得列表则是适合托管的Pod,这个结果通常来说是一个列表,如何选择最优Node进行调度,则是接下来打分的步骤步骤。

例如:Kubernetes对剩余节点进行优先级排序,优先级由一组函数计算;优先级函数将为剩余节点给出从 0~10 的分数,10 表示最优,0 表示最差。每个优先级函数由一个正数加权组成,每个Node的得分是通过将所有加权得分相加来计算的。设有两个优先级函数, priorityFunc1 和 priorityFunc2 加上权重因子 weight1 和 weight2 ,那么这个Node的最终得分为: \(finalScore = (w1 \times priorityFunc1) + (w2 \times priorityFunc2)\) 。计算完分数后,选择最高分数的Node做为Pod的宿主机,存在多个相同分数Node情况下会随机选择一个Node。

目前kubernetes提供了一些在打分 Scoring 阶段算法:

  • LeastRequestedPriority :Node的优先级基于Node的空闲部分 \(\frac{capacity\ -\ Node上所有存在的Pod\ -\ 正在调度的Pod请求}{capacity}\) ,通过计算具有最高分数的Node是FN
  • BalancedResourceAllocation :该算法会将 Pod 放在一个Node上,使得在Pod 部署后 CPU 和内存的使用率为平衡的
  • SelectorSpreadPriority :通过最小化资源方式,将属于同一种服务、控制器或同一Node上的Replica的 Pod的数量来分布Pod。如果节点上存在Zone,则会调整优先级,以便 pod可以分布在Zone之上。
  • CalculateAntiAffinityPriority :根据label来分布,按照相同service上相同label值的pod进行分配
  • ImageLocalityPriority :根据Node上镜像进行打分,Node上存在Pod请求所需的镜像优先级较高。

在代码中查看上述的代码

以 PodFitsHostPorts 算法为例,因为是Node类算法,在 kubernetes\pkg\scheduler\framework\plugins\nodeports

调度框架 ( scheduling framework SF ) 是kubernetes为 scheduler设计的一个pluggable的架构。SF 将scheduler设计为 Plugin 式的 API,API将上一章中提到的一些列调度策略实现为 Plugin 。

在 SF 中,定义了一些扩展点 ( extension points EP ),而被实现为Plugin的调度程序将被注册在一个或多个 EP 中,换句话来说,在这些 EP 的执行过程中如果注册在多个 EP 中,将会在多个 EP 被调用。

每次调度都分为两个阶段,调度周期( Scheduling Cycel )与绑定周期( Binding Cycle )。

  • SC 表示为,为Pod选择一个节点; SC 是串行运行的。
  • BC 表示为,将 SC 决策结果应用于集群中; BC 可以同时运行。

调度周期与绑定周期结合一起,被称为 调度上下文 ( Scheduling Context ),下图则是调度上下文的工作流

注:如果决策结果为Pod的调度结果无可用节点,或存在内部错误,则中止 SC 或 BC 。Pod将重入队列重试

图1:Pod的调度上下文

Source: https://kubernetes.io/docs/concepts/scheduling-eviction

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值