Kubernetes之Scheduler源码分析1.8.3

本文详细解析了Kubernetes Scheduler的工作流程,从入口函数到调度策略,包括节点过滤、优先级判断和资源分配策略。重点介绍了findNodeThatFit()方法的过滤条件,如资源需求、亲和性、端口冲突等,并详细阐述了多个关键的打分算法,如PodFitsResources()。通过对scheduler源码的分析,展示了如何确保Pod被合理地调度到合适的Node上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K8S的scheduler的主要作用是将用户申请的pods调度到合适的node节点上。具体的来说,就是它通过监听API server提供的watch等接口,获取到未调度的pods和node的相关信息,通过对node的筛选,选择出最合适的也就是优先级最高的node节点,将其与pods进行绑定,并将绑定的结果固化到etcd中去。下面就通过走读源码来详细解析一下scheduler的流程:

scheduler的脑图:

 

源码解析:

 

main函数的入口:

 

func main() {
    //新建schedulerserver,它主要是读取master地址和kubeconf文件
    s := options.NewSchedulerServer()
 
    .......
    //启动参数结构体新建以后,开始执行主函数RUN
    if err := app.Run(s); err != nil {
        glog.Fatalf("scheduler app failed to run: %v", err)
    }

 

 

Run函数的入口(Run函数一单启动起来之后就不会在退出,一直以一个进程的身份运行在后台,当检测到有pods未进行调度的时候直接启动):

func Run(s *options.SchedulerServer) error {
 
    ........
    //新建scheduler它主要是分为两步:1.创建Scheduler需求的各种结构体,如监听器,node,pods的信息等 2.根据获取的信息新建一个scheduler对象,利用这个对象来开启调度。
    sched, err := CreateScheduler(
        s,
        kubecli,
        informerFactory.Core().V1().Nodes(),
        podInformer,
        informerFactory.Core().V1().PersistentVolumes(),
        informerFactory.Core().V1().PersistentVolumeClaims(),
        informerFactory.Core().V1().ReplicationControllers(),
        informerFactory.Extensions().V1beta1().ReplicaSets(),
        informerFactory.Apps().V1beta1().StatefulSets(),
        informerFactory.Core().V1().Services(),
        recorder,
    )
 
    ........
    //根据上面创建的scheduler的对象来调用Run函数来启动调度过程。
    run := func(stopCh <-chan struct{}) {
        sched.Run()
        <-stopCh
    }
 
    ........
}


创建scheduler对象:

 

 

 

func CreateScheduler(...../*传递进来的参数*/.....) (*scheduler.Scheduler, error) {
     
   //调用NewConfigFactory()函数来构建各种结构体
   configurator := factory.NewConfigFactory(
        s.SchedulerName,
        kubecli,
        nodeInformer,
        podInformer,
        pvInformer,
        pvcInformer,
        replicationControllerInformer,
        replicaSetInformer,
        statefulSetInformer,
        serviceInformer,
        s.HardPodAffinitySymmetricWeight,
        utilfeature.DefaultFeatureGate.Enabled(features.EnableEquivalenceClassCache),
    )
 
    .......
 
    //根据新建的scheduler结构体创建scheduler对象
    return scheduler.NewFromConfigurator(configurator, func(cfg *scheduler.Config) {
        cfg.Recorder = recorder
    })
}


scheduler各种结构体的构建:

 

 

 

 

func NewConfigFactory(...../*传递进来的参数*/.....) scheduler.Configurator {
 
 
    ......
    //所有的pods和node的信息都会先记录在schedulerCache中,这样做的目的是,可以一次性的先获取所有的pods和node的信息不用再反复的从etcd中读取,这样会节约很多的时间提高一定的效率,这个New()方法是用来将已经绑定好的pods和node信息固化到etcd中的,它是一个多线程的操作,30s启动一次,默认最多可以起16个线程同时去处理这件事情。
    schedulerCache := schedulercache.New(30*time.Second, stopEverything)
 
    c := &ConfigFactory{
        client:                         client,
        podLister:                      schedulerCache,
        podQueue:                       cache.NewFIFO(cache.MetaNamespaceKeyFunc),
        
        //注意这些lister,他们用来获取各种资源列表,它们会和 apiserver 保持实时同步
        nodeLister                      nodeInformer.Lister(),
        pVLister:                       pvInformer.Lister(),
        pVCLister:                      pvcInformer.Lister(),
        serviceLister:                  serviceInformer.Lister(),
        controllerLister:               replicationControllerInformer.Lister(),
        replicaSetLister:               replicaSetInformer.Lister(),
        statefulSetLister:              statefulSetInformer.Lister(),
  
 
        schedulerCache:                 schedulerCache,
        
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值