- 经过上面的阶段过滤后选择打分最高的 Node 节点和 Pod 进行 binding 操作,然后将结果存储到 etcd 中 最后被选择出来的 Node 节点对应的 kubelet 去执行创建 Pod 的相关操作(当然也是 watch APIServer 发现的) 。
// pkg/scheduler/framework/plugins/registry.go// NewInTreeRegistry 使用所有内部插件构建注册表 。// 外部插件可以通过 WithFrameworkOutOfTreeRegistry 选项注册额外的插件 。func NewInTreeRegistry() runtime.Registry { fts := plfeature.Features{EnableDynamicResourceAllocation:feature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation),EnableReadWriteOncePod:feature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod),EnableVolumeCapacityPriority:feature.DefaultFeatureGate.Enabled(features.VolumeCapacityPriority),EnableMinDomainsInPodTopologySpread:feature.DefaultFeatureGate.Enabled(features.MinDomainsInPodTopologySpread),EnableNodeInclusionPolicyInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread),EnableMatchLabelKeysInPodTopologySpread:feature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodTopologySpread),EnablePodSchedulingReadiness:feature.DefaultFeatureGate.Enabled(features.PodSchedulingReadiness), } registry := runtime.Registry{dynamicresources.Name:runtime.FactoryAdapter(fts, dynamicresources.New),selectorspread.Name:selectorspread.New,imagelocality.Name:imagelocality.New,tainttoleration.Name:tainttoleration.New,nodename.Name:nodename.New,nodeports.Name:nodeports.New,nodeaffinity.Name:nodeaffinity.New,podtopologyspread.Name:runtime.FactoryAdapter(fts, podtopologyspread.New),nodeunschedulable.Name:nodeunschedulable.New,noderesources.Name:runtime.FactoryAdapter(fts, noderesources.NewFit),noderesources.BalancedAllocationName: runtime.FactoryAdapter(fts, noderesources.NewBalancedAllocation),volumebinding.Name:runtime.FactoryAdapter(fts, volumebinding.New),volumerestrictions.Name:runtime.FactoryAdapter(fts, volumerestrictions.New),volumezone.Name:volumezone.New,nodevolumelimits.CSIName:runtime.FactoryAdapter(fts, nodevolumelimits.NewCSI),nodevolumelimits.EBSName:runtime.FactoryAdapter(fts, nodevolumelimits.NewEBS),nodevolumelimits.GCEPDName:runtime.FactoryAdapter(fts, nodevolumelimits.NewGCEPD),nodevolumelimits.AzurediskName:runtime.FactoryAdapter(fts, nodevolumelimits.NewAzureDisk),nodevolumelimits.CinderName:runtime.FactoryAdapter(fts, nodevolumelimits.NewCinder),interpodaffinity.Name:interpodaffinity.New,queuesort.Name:queuesort.New,defaultbinder.Name:defaultbinder.New,defaultpreemption.Name:runtime.FactoryAdapter(fts, defaultpreemption.New),schedulinggates.Name:runtime.FactoryAdapter(fts, schedulinggates.New), } return registry}
从上面我们可以看出调度器的一系列算法由各种插件在调度的不同阶段来完成,下面我们就先来了解下调度框架 。调度框架调度框架定义了一组扩展点,用户可以实现扩展点定义的接口来定义自己的调度逻辑(我们称之为扩展),并将扩展注册到扩展点上,调度框架在执行调度工作流时,遇到对应的扩展点时,将调用用户注册的扩展 。调度框架在预留扩展点时,都是有特定的目的,有些扩展点上的扩展可以改变调度程序的决策方法,有些扩展点上的扩展只是发送一个通知 。
我们知道每当调度一个 Pod 时,都会按照两个过程来执行:调度过程和绑定过程 。
调度过程为 Pod 选择一个合适的节点,绑定过程则将调度过程的决策应用到集群中(也就是在被选定的节点上运行 Pod),将调度过程和绑定过程合在一起,称之为调度上下文(scheduling context) 。需要注意的是调度过程是?
?同步?
?运行的(同一时间点只为一个 Pod 进行调度),绑定过程可异步运行(同一时间点可并发为多个 Pod 执行绑定) 。调度过程和绑定过程遇到如下情况时会中途退出:
- 调度程序认为当前没有该 Pod 的可选节点
- 内部错误
扩展点(Extension Points)下图展示了调度框架中的调度上下文及其中的扩展点,一个扩展可以注册多个扩展点,以便可以执行更复杂的有状态的任务 。
推荐阅读
- C++ 自适应函数符和函数适配器
- 釉里红|故宫陶瓷馆:独立展柜里的瓷器,是不是都价值连城
- |历代的“礼仪玉器”:(3)玉圭
- 你可以信任由编译器优化的代码吗?
- |瓷器观音瓶(观音尊)鉴赏
- 更换玻璃升降器多少钱?玻璃升降器的故障及保养介绍
- 关于包管理器Npm、Yarn和Pnpm的一些总结
- Kubernetes 策略引擎 Kyverno 使用
- APT 如何运用JAVA注解处理器
- |清代矾红彩金鱼纹饰瓷器有什么美好寓意?