kube-schduler

根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上去。

启动之后会一直监听 API Server,获取到 PodSpec.NodeName 为空的 Pod,对每个 Pod 都会创建一个 binding。

------------- 原始的扩展调度器的方法 ------

1.魔改kube-schduler

clone 官方 kube-schedule,然后对其进行代码级更改。

2.自行实现调度器

实现一个新的调度器,配置 pod.spec.schedulerName 来选择使用哪一个调度器。

--------------------------------------------------------

1.插件注册

包括树内插件和树外插件。

每个插件都实现了一个或多个扩展点。

在生成调度器profile时,针对每个扩展点,指定要使用的插件。

1.1 树内插件

1.2 树外插件

在通过新的调度框架进行扩展时,需要自己实现一个调度器。

我们可以使用kube-schduler的代码,将我们实现的插件作为树外插件传递进去。

2.运行机制

2.1 老的调度框架:两阶段

Kubernetes 调度器介绍-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生 (qikqiak.com)

整个调度过程分两步:预选(Predicates)和优选(Policies)。

2)kube-schderl中的extender接口

提供了HTTPExtender实现。

作用是利用http访问用户的extender服务。

2.2 新的调度框架

1)扩展点

2)新的调度框架与extender的融合

PreEnqueue

在将 Pod 被添加到内部活动队列之前被调用。

在此队列中 Pod 被标记为准备好进行调度。

注意:

只有当所有 PreEnqueue 插件返回 Success 时,Pod 才允许进入活动队列。

否则,它将被放置在内部无法调度的 Pod 列表中,并且不会获得 Unschedulable 状态。

sort

用于对调度队列中的 Pod 进行排序。

队列排序插件本质上提供 Less(Pod1, Pod2) 函数。

一次只能启动一个队列插件。

PreFilter
Filter

用于过滤出不能运行该 Pod 的节点。

对于每个节点, 调度器将按照其配置顺序调用这些过滤插件。如果任何过滤插件将节点标记为不可行, 则不会为该节点调用剩下的过滤插件。

extender.Filter
PreScore生成一个可共享状态供 Score 插件使用。
Score

对通过过滤阶段的节点进行排序。

调度器将为每个节点调用每个评分插件。

调度器将根据配置的插件权重 合并所有插件的节点分数。

extenders.Prioritize
PostFilter

仅在该 Pod 没有可行的节点时调用。

如果任何 PostFilter 插件标记节点为“Schedulable”, 则其余的插件不会调用。

作用:

1)抢占,试图通过抢占其他 Pod 的资源使该 Pod 可以调度。

--

DefaultPreemption插件

1) 确保当前pod有权抢占其他POD

2)找到一些可选方案

   可选方案:[节点1,需要驱逐的pod]/[节点2,需要驱逐的pod]

3)调用注册的extender.ProcessPreemption来过滤调一部分可选方案

4) 找到最佳方案

5)

 - 驱逐受害者pod

- Reject the victim pods if they are in waitingPod map

- 清理low-priority pods的nominatedNodeName状态

Reserve

发生在调度器实际将一个 Pod 绑定到其指定节点之前。

两个方法:

1) Reserve 

2)Unreserve

Permit

用于防止或延迟 Pod 的绑定。

插件可以做以下三件事之一:

waitOnPermit
PreBind

用于执行 Pod 绑定前所需的所有工作。

作用:

一个 PreBind 插件可能需要制备网络卷并且在允许 Pod 运行在该节点之前 将其挂载到目标节点上

extender.Bind
Bind

各 Bind 插件按照配置顺序被调用。

Bind 插件可以选择是否处理指定的 Pod。 如果某 Bind 插件选择处理某 Pod,剩余的 Bind 插件将被跳过

PostBind

可用于清理相关的资源。

3. 启动参数

通过 --config 参数指定调度器将使用哪些参数。(同时配置老/新框架)

algorithmSource设置了默认的调度器配置。

Profiles在此基础上,开启/关闭插件,设置插件的参数,最终生成新的调度器。

Extender在此基础上,为每个调度器新增功能。

例子:

3.1 algorithmSource调度算法源

如果为空,使用默认provider。

1) policy

也可以通过-policy-config-file指定文件地址。

主要是针对老框架。

例子:

老框架整合到新调度框架:

将老的“预选”和“优选”的插件,分配到调度框架的各个阶段。

(一个插件可能涉及多个阶段)

以前的框架,没有以下阶段,添加默认插件。

extender配置信息:

2)provider

针对新框架。

目前,kube-schduler有两个。

对应的是调度框架。

DefaultProvider:

列举了,在各个阶段使用的插件。

schedulerapi.Plugins{
		QueueSort: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: queuesort.Name},
			},
		},
		PreFilter: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: noderesources.FitName},
				{Name: nodeports.Name},
				{Name: podtopologyspread.Name},
				{Name: interpodaffinity.Name},
				{Name: volumebinding.Name},
				{Name: computeresource.Name},
			},
		},
		Filter: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: nodeunschedulable.Name},
				{Name: nodename.Name},
				{Name: tainttoleration.Name},
				{Name: nodeaffinity.Name},
				{Name: nodeports.Name},
				{Name: noderesources.FitName},
				{Name: volumerestrictions.Name},
				{Name: nodevolumelimits.EBSName},
				{Name: nodevolumelimits.GCEPDName},
				{Name: nodevolumelimits.CSIName},
				{Name: nodevolumelimits.AzureDiskName},
				{Name: volumebinding.Name},
				{Name: volumezone.Name},
				{Name: podtopologyspread.Name},
				{Name: interpodaffinity.Name},
				{Name: computeresource.Name},
				{Name: localreplicas.Name},
				{Name: fitipresource.Name},
			},
		},
		PostFilter: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: defaultpreemption.Name},
			},
		},
		PreScore: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: interpodaffinity.Name},
				{Name: podtopologyspread.Name},
				{Name: tainttoleration.Name},
			},
		},
		Score: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: noderesources.BalancedAllocationName, Weight: 1},
				{Name: imagelocality.Name, Weight: 1},
				{Name: interpodaffinity.Name, Weight: 1},
				{Name: noderesources.LeastAllocatedName, Weight: 1},
				{Name: nodeaffinity.Name, Weight: 1},
				{Name: nodepreferavoidpods.Name, Weight: 10000},
				// Weight is doubled because:
				// - This is a score coming from user preference.
				// - It makes its signal comparable to NodeResourcesLeastAllocated.
				{Name: podtopologyspread.Name, Weight: 2},
				{Name: tainttoleration.Name, Weight: 1},
				{Name: computeresource.Name, Weight: 1},
			},
		},
		Reserve: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: volumebinding.Name},
			},
		},
		PreBind: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: volumebinding.Name},
			},
		},
		Bind: &schedulerapi.PluginSet{
			Enabled: []schedulerapi.Plugin{
				{Name: defaultbinder.Name},
			},
		},
	}
}

ClusterAutoscalerProvider

3.2 Profiles

一个Profiles对应一个调度器。kube-schduler进程中可以定义多个调度器。

如果schedulerName=Pod的spec.schedulerName,则Pod使用此方案调度。

3.3 extender

支持 Predicate、Priority、Bind、preemption扩展点。

4. 使用extender进行扩展

直接在默认调度器上,进行扩展。

如果kube-schduler进程,设置了多个调度器。那么会扩展所有调度器。

缺点:

  • 通信成本:数据在默认调度程序和调度器扩展程序之间以 http(s)传输,在执行序列化和反序列化的时候有一定成本
  • 有限的扩展点:扩展程序只能在某些阶段的末尾参与,例如“ Filter”“ Prioritize”,它们不能在任何阶段的开始或中间被调用
  • 减法优于加法:与默认调度程序传递的节点候选列表相比,我们可能有一些需求需要添加新的候选节点列表,但这是比较冒险的操作,因为不能保证新节点可以通过其他要求,所以,调度器扩展程序最好执行“减法”(进一步过滤),而不是“加法”(添加节点)
  • 缓存共享:上面只是一个简单的测试示例,但在真实的项目中,我们是需要通过查看整个集群的状态来做出调度决策的,默认调度程序可以很好地调度决策,但是无法共享其缓存,这意味着我们必须构建和维护自己的缓存

4.1 创建extender服务器

1) 创建一个http server,针对以下路径提供对应的handler

2)针对predicates(过滤)

入参:

出参:

3)针对priorities

入参:

同2

出参:

实现:

使用算法,为每个节点打分。

4)针对bind

入参:

出参:

5)编译并部署

4.2 修改kube-schduler的配置文件

--config=/etc/kubernetes/scheduler-extender.yaml

在extendr处进行注册。

5.使用新的调度框架进行扩展

缺点:需要在pod上指定要使用的调度器。

5.1 实现对应的扩展点

5.2 将插件注册到调度器中

相当于在kube-schduler注册了树外插件。

自己独立起一个仓库,调用kube-schduler的代码。

5.3 部署

实现完成后,编译打包成镜像即可,然后我们就可以当成普通的应用用一个 Deployment 控制器来部署。

通过 --config 参数来配置我们的调度器。新的调度器名字为sample-scheduler。在默认调度器的基础上,在preFilter/filter/preBind阶段新增自己的插件。

5.4 使用

指定要使用的调度器名字。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值