kube-scheduler负责整个集群资源的调度功能。根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上,是一个独立的二进制程序,启动之后一直监听API Server。
k8s 调度流程

调度过程一般可以分为三个阶段:
Predicate(预选) -> Priority(优选) -> Select(选定) -> Bind(绑定)- 预选:排除不符合 Pod 运行要求的节点,筛选满足 Pod 调度要求的节点列表
- 优选:通过内部的优选算法为节点打分,获得最高分数的节点即为选中的节点
- 选定:随机选择
- 绑定(Bind):调度器将调度结果通知给 kube-apiserver,更新 Pod 的 .spec.nodeName 字段
预选函数
预选策略需要全部满足,每个预选策略都有一票否则权:
CheckNodeCondition:节点是否正常(如 ip,磁盘等)GeneralPredicatesHostName:检测 Pod 对象是否定义了kubectl explain pods.spec.hostnamePodFitsHostPorts:Pod 绑定在节点的指定端口kubectl explain pods.spec.containers.ports.hostPortMatchNodeSelector:节点的NodeSelector的标签kubectl explain pods.spec.nodeSelectorPodFitsResources:检查 Pod 的资源需求是否能被节点所满足
NoDiskConflict:检查 Pod 依赖的存储卷是否能满足需求,默认未使用PodToleratesNodeTaints:检查 Pod 上的pods.spec.tolerations可容忍的污点是否完全包含节点上的污点PodToleratesNodeNoExecuteTaints:不能执行(NoExecute)的污点,默认未使用CheckNodeLabelPresence:指定的标签再上节点是否存在,默认未使用CheckServiceAffinity:将相同 services 相同的 Pod 尽量放在一起,默认未使用MaxEBSVolumeCount:EBS(AWS 弹性块存储)存储卷的最大数量,默认 39MaxGCEPDVolumeCount:GCE 存储最大数,默认 16MaxAzureDiskVolumeCount:AzureDisk 存储最大数,默认 16CheckVolumeBinding:节点上已绑定或未绑定的 PVCNoVolumeZoneConflict:存储卷对象与 Pod 是否存在冲突CheckNodeMemoryPressure:节点内存是否存在压力过大CheckNodePIDPressure:节点上的 PID 数量是否过大CheckNodeDiskPressure:节点上的磁盘 IO 是否过大MatchInterPodAffinity:节点是否能满足 Pod 的亲和性或反亲和性
优选函数
LeastRequested:空闲量越高得分越高,(cpu((capacity-sum(requested))*10/capacity) + memory((capacity-sum(requested))*10/capacity))/2BalancedResourceAllocation:CPU 和内存资源被占用率相近的胜出NodePreferAvoidPods:节点注解信息scheduler.alpha.kubernetes.io/preferAvoidPodsTaintToleration:将 Pod 对象的pods.spec.tolerations列表项与节点的 taints 列表项进行匹配度检查,匹配条目越,得分越低SeletorSpreading:标签选择器分散度,与当前 Pod 对象通选的标签,所选其它 Pod 越多的得分越低InterPodAffinity:遍历 Pod 对象的亲和性匹配项目,项目越多得分越高NodeAffinity:节点亲和性MostRequested:空闲量越小得分越高,和LeastRequested相反,默认未启用NodeLabel:节点是否存在对应的标签,默认未启用ImageLocality:根据满足当前 Pod 对象需求的已有镜像的体积大小之和,默认未启用
高级调度策略
Gang scheduling(帮派调度)是一种调度算法,主要的原则是保证所有相关联的进程能够同时启动,防止部分进程的异常,导致整个关联进程组的阻塞,例如,您提交一个批量 Job,这个批量 Job 包含多个任务,要么这多个任务全部调度成功,要么一个都调度不成功。这种All-or-Nothing调度场景,就被称作Gang schedulingGang scheduling用于并发系统中将多个相关联的进程调度到不同处理器上同时运行 Coscheduling(协同调度) 是并行系统的一种调度方式,它将相关进程同时(以并行方式)运行在不同的处理器上,主要约束指标是保证所有相关联的进程能够同时启动- Explicit Coscheduling,即 Gang scheduling
- Local Coscheduling
- Implicit Coscheduling
Capacity Scheduling阿里云基于 Scheduling Framework 的扩展机制,在调度侧实现了 Capacity Scheduling 的功能,在确保用户的资源分配的基础上通过资源共享的方式来提升整体资源的利用率
默认调度器实现
kubernetes 的调度器采用插件化的方式实现,源码在 kubernetes/pkg/scheduler,该目录下:
kubernetes/pkg/scheduler/scheduler.go创建和运行的具体代码kubernetes/cmd/kube-scheduler/scheduler.go入口函数
调度器工作流程
- 默认调度器根据指定的参数启动(若使用 kubeadm 搭建的集群,启动配置文件位于
/etc/kubernetes/manifests/kube-schdueler.yaml) - watch apiserver,将 spec.nodeName 为空的 Pod 放入调度器内部的调度队列中
- 从调度队列中 Pop 出一个 Pod,开始一个标准的调度周期
- 从 Pod 属性中检索“硬性要求”(比如 CPU/内存请求值,nodeSelector/nodeAffinity),然后过滤阶段发生,在该阶段计算出满足要求的节点候选列表
- 从 Pod 属性中检索“软需求”,并应用一些默认的“软策略”(比如 Pod 倾向于在节点上更加聚拢或分散),最后,它为每个候选节点给出一个分数,并挑选出得分最高的最终获胜者
- 和 apiserver 通信(发送绑定调用),然后设置 Pod 的 spec.nodeName 属性以表示将该 Pod 调度到的节点
kube-scheduler 配置参考:https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
调度上下文(scheduling context):
- scheduling cycle
- binding cycle
调度框架,需要实现对应的扩展点,相关需要实现的接口见:
- https://github.com/kubernetes/kubernetes/blob/v1.23.3/pkg/scheduler/framework/interface.go#L294
- https://github.com/kubernetes/kubernetes/tree/v1.23.3/pkg/scheduler/framework/plugins/examples
自定义调度器
- 基于 kube-scheduler 源代码修改
- 基于 design-proposals scheduling 的调度器扩展,2022-04-01 or the release of Kubernetes 1.24 会被移除
- Scheduling Framework:Kubernetes v1.15 中引入的
可插拔架构的调度框架。推荐实现方式 - aliyun Coscheduling https://developer.aliyun.com/article/766275#slide-14
scheduler-plugins
Kubernetes 负责 kube-scheduler 的小组 sig-scheduling 为了更好的管理调度相关的 Plugin,新建了项目 kubernetes-sigs/scheduler-plugins ,可以直接基于这个项目来定义自己的插件。支持的调度算法
-
Capacity Scheduling
-
Coscheduling
- 实现 QueueSort 插件, 保证在队列中属于同一个 PodGroup 的 Pod 能够排列在一起
- Permit 的延迟绑定的功能,对于不满足 PodGruop Min 限制的 Pod 进行等待,等待积累的 Pod 数目满足足够的数目时,再将同一个 PodGruop 的所有 Pod 创建
-
Node Resources
-
Node Resource Topology
-
Preemption Toleration
-
Trimaran
-
其他
- Extension points
- Binpack Scheduling 减少资源碎片,提升 GPU 的利用率
其他调度器
- Volcano 的目标是创建一个批量计算系统 (batch system),而 kube-batch 只是这个系统中的调度器 (batch scheduler) 部分
- https://github.com/kubernetes-sigs/kube-batch
- Mesos
- Yarn
- Slurm
Volcano
Volcano 是 CNCF 孵化的沙箱项目,调度策略:
- Gang-scheduling
- Fair-share scheduling
- Queue scheduling
- Preemption scheduling
- Topology-based scheduling
- Reclaims
- Backfill
- Resource Reservation
最近更新
最新评论