图解kubernetes调度器核心实现原理大揭秘

本文详细剖析了Kubernetes调度器的工作原理,包括Binder的构建与绑定过程,调度组件的初始化和核心流程,特别是调度、绑定与抢占流程的详细步骤。通过对调度器的数据结构和关键流程的全景图分析,为读者提供了深入的理解。文章还总结了调度器学习过程中的感悟,指出未来调度器优化的方向可能集中在预选阶段。
摘要由CSDN通过智能技术生成

kubernetes调度器之前已经分析过SchedulerCache、ScheduleAlgorithm、SchedulerExtender、Framework等核心数据结构,也分析了优选、调度、抢占流程的核心实现,本文是本系列目前打算的最后一章, 也是当前阶段对调度的学习的一个总结

整个系列文档我已经已经更新到语雀上了地址是,谢谢大家分享加微信一起交流 https://www.yuque.com/baxiaoshi/tyado3/

1. Binder

Binder负责将调度器的调度结果,传递给apiserver,即将一个pod绑定到选择出来的node节点

1.1 构建binder

在scheduler/factory中会构建一个默认的binder

func getBinderFunc(client clientset.Interface, extenders []algorithm.SchedulerExtender) func(pod *v1.Pod) Binder {
    defaultBinder := &binder{client}
    return func(pod *v1.Pod) Binder {
        for _, extender := range extenders {
            if extender.IsBinder() && extender.IsInterested(pod) {
                return extender
            }
        }
        return defaultBinder
    }
}

1.2 binder接口实现

binder接口和简单只需要调用apiserver的pod的bind接口即可完成绑定操作

// Implement Binder interface
var _ Binder = &binder{}

// Bind just does a POST binding RPC.
func (b *binder) Bind(binding *v1.Binding) error {
    klog.V(3).Infof("Attempting to bind %v to %v", binding.Name, binding.Target.Name)
    return b.Client.CoreV1().Pods(binding.Namespace).Bind(binding)
}

1.3 不可思议的bind时机

执行绑定的操作位于Scheudler.bind接口,在调用Framework.RunBindPlugins后,只有当返回的状态不是成功,而是SKIP的时候,才执行bind操作,真的不知道是怎么想的,后续如果加入对应的bind插件,也需要返回SKIP,理解不了大神的思维

    bindStatus := sched.Framework.RunBindPlugins(ctx, state, assumed, targetNode)
    var err error
    if !bindStatus.IsSuccess() {
        if bindStatus.Code() == framework.Skip {
            // 如果所有的插件都skip了菜允许将pod绑定到apiserver
            err = sched.GetBinder(assumed).Bind(&v1.Binding{
                ObjectMeta: metav1.ObjectMeta{Namespace: assumed.Namespace, Name: assumed.Name, UID: assumed.UID},
                Target: v1.ObjectReference{
                    Kind: "Node",
                    Name: targetNode,
                },
            })
        } else {
            err = fmt.Errorf("Bind failure, code: %d: %v", bindStatus.Code(), bindStatus.Message())
        }
    }

2 调度组件核心流程概览

2.1 调度器初始化

2.1.1 调度器参数初始化

调度器的参数的初始化已经都放到defaultSchedulerOptions中了,后续应该更多的都会采用改种方式,避免散落在构建参数的各个阶段

var defaultSchedulerOptions = schedulerOptions{
    schedulerName: v1.DefaultSchedulerName,
    schedulerAlgorithmSource: schedulerapi.SchedulerAlgorithmSource{
        Provider: defaultAlgorithmSourceProviderName(),
    },
    hardPodAffinitySymmetricWeight: v1.DefaultHardPodAffinitySymmetricWeight,
    disablePreemption:              false,
    percentageOfNodesToScore:       schedulerapi.DefaultPercentageOfNodesToScore,
    bindTimeoutSeconds:             BindTimeoutSeconds,
    podInitialBackoffSeconds:       int64(internalqueue.DefaultPodInitialBackoffDuration.Seconds()),
    podMaxBackoffSeconds:           int64(internalqueue.DefaultPodMaxBackoffDuration.Seconds()),
}

2.1.2 插件工厂注册表的初始化

插件工厂注册表的初始化分

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值