通过Karmada实现应用多Kubernetes集群管理--调度器
前面文章介绍了Karmada的控制器流程,了解了Karmada如何实现Kubernetes资源下发到成员集群的。今天我们一起看一下Karmada的调度器,看看Karmada如何实现Kubernetes资源下发调度的。 前面控制器流程里讲过,用户创建了Kubernetes资源对象模板,下发策略和差异策略后,由resourceDetector根据下发策略,创建ResourceBinding绑定资源与策略,再由BindingController根据ResourceBinding,查找并应用OverridePolicy,最终生成创建成员集群资源的Work,由ExecutionController在成员集群中执行Work完成Kubernetes资源操作。 在流程上,Karmada调度器工作在ResourceBinding创建生成后,BindingController控制器工作之前。在功能上,Karmada调度器主要负责Kubernetes资源对象在成员集群的分布,Karmada调度器通过算法得出在哪些成员集群上运行多少个副本数量的结果,将调度结果保存到ResourceBinding的Clusters参数中。 业务流程 1,监听事件加入队列:Informer监听资源绑定ResourceBinding, 下发策略PropagationPolicy事件,将对应的ResourceBinding资源加入工作队列。 2,取出队列中ResourceBinding对象:每秒中开启一个worker,从队列中取出ResourceBinding对象进行处理。循环处理工作队列,直到队列处理结束。 3,获取分布规则:根据ResourceBinding的Annotation中下发策略PropagationPolicy名称,获取下发策略的分布规则。分布规则包括:集群亲和,集群容忍,拓扑分布约束规则以及副本调度策略等信息。 4,判断是否进行ResourceBinding调度:比对新旧分布规则,判断是否需要进行ResourceBinding调度。 5,调度ResourceBinding,计算出成员集群分配副本数量: a,FilterPlugin过滤插件判断集群亲和和容忍是否匹配条件,得到匹配集群。 b,ScorePlugin计算匹配集群的得分,得到集群的优先级。 c,根据SpreadConstraint拓扑分布约束规则,得到最后的下发成员集群。 d,发配副本,副本调度策略类型分两种:Duplicated复制, Divided切分。如果是复制类型,每个成员集群部署与模板相同的资源副本数量。如果是切分类型,可以配置PreferenceWeighted权重优先和PreferenceAggregated聚合优先,前者会根据权重比例来进行切分,后者根据总的副本数量来判断是scaleUP还是scaleDown,再根据成员集群的最大可用副本数来分配副本数量。 6,更新ResourceBinding中的Clusters字段,设置为计算出的成员集群分配副本数量结果。 7,完成了一个ResourceBinding的处理,继续处理下一条。 代码实现 过滤和计分插件 构造调度算法实例,算法插件包括:集群亲和,污点容忍,已安装支持的资源API,已下发集群。 algorithm := core.NewGenericScheduler(schedulerCache, []string{clusteraffinity.Name, tainttoleration.Name, apiinstalled.Name, clusterlocality.Name}) 集群亲和:过滤插件,1,集群名称是否在亲和策略的排除集群列表中。2,集群的标签、字段过滤是否与亲和策略中的标签和字段过滤匹配。返回是否成功结果。 // Filter checks if the cluster matched the placement cluster affinity constraint. func (p *ClusterAffinity) Filter(ctx context.Context, placement *policyv1alpha1.Placement, resource *workv1alpha2.ObjectReference, cluster *clusterv1alpha1.Cluster) *framework.Result { affinity := placement.ClusterAffinity if affinity != nil { if util.ClusterMatches(cluster, *affinity) { return framework.NewResult(framework.Success) } return framework.NewResult(framework.Unschedulable, "cluster is not matched the placement cluster affinity constraint") } // If no clusters specified and it is not excluded, mark it matched return framework.