Go语言kube-scheduler之scheduler初始化的方法是什么

发布时间:2023-04-24 16:36:50 作者:iii
来源:亿速云 阅读:122

Go语言kube-scheduler之scheduler初始化的方法是什么

目录

  1. 引言
  2. kube-scheduler概述
  3. scheduler初始化流程
  4. scheduler初始化源码分析
  5. scheduler初始化过程中的关键点
  6. 总结
  7. 参考文献

引言

Kubernetes作为当前最流行的容器编排系统,其核心组件之一——kube-scheduler,负责将Pod调度到合适的节点上运行。kube-scheduler的初始化过程是整个调度器启动的关键步骤,涉及到命令行参数解析、配置文件加载、日志系统初始化、客户端初始化、调度器初始化、插件初始化等多个环节。本文将深入探讨kube-scheduler的初始化方法,分析其源码实现,并总结其中的关键点。

kube-scheduler概述

kube-scheduler是Kubernetes集群中的核心组件之一,其主要职责是将新创建的Pod调度到集群中的合适节点上运行。调度器的决策过程基于多种因素,包括资源需求、亲和性、反亲和性、污点和容忍度等。kube-scheduler的设计目标是高效、可扩展和可配置,以满足不同场景下的调度需求。

scheduler初始化流程

kube-scheduler的初始化流程可以分为以下几个步骤:

  1. 命令行参数解析:解析命令行参数,获取调度器的配置信息。
  2. 配置文件加载:加载调度器的配置文件,进一步补充和覆盖命令行参数。
  3. 日志系统初始化:初始化日志系统,确保调度器的日志输出能够正常工作。
  4. 客户端初始化:初始化与Kubernetes API Server的通信客户端,用于获取集群状态和资源信息。
  5. 调度器初始化:初始化调度器核心组件,包括调度队列、调度算法、调度缓存等。
  6. 插件初始化:初始化调度器插件,扩展调度器的功能。
  7. 调度器启动:启动调度器,开始监听和处理Pod调度请求。

命令行参数解析

kube-scheduler的命令行参数解析是通过cobra库实现的。cobra是一个强大的命令行库,支持子命令、参数解析、帮助信息生成等功能。kube-scheduler的命令行参数主要包括调度器的配置文件路径、日志级别、API Server地址等。

func NewSchedulerCommand() *cobra.Command {
    opts := options.NewOptions()
    cmd := &cobra.Command{
        Use: "kube-scheduler",
        Long: `The Kubernetes scheduler is a control plane process which assigns
Pods to Nodes. The scheduler determines which Nodes are valid placements for
each Pod in the scheduling queue according to constraints and available
resources. The scheduler then ranks each valid Node and binds the Pod to
a suitable Node.`,
        Run: func(cmd *cobra.Command, args []string) {
            if err := runCommand(cmd, opts, registryOptions...); err != nil {
                fmt.Fprintf(os.Stderr, "%v\n", err)
                os.Exit(1)
            }
        },
    }

    fs := cmd.Flags()
    namedFlagSets := opts.Flags()
    for _, f := range namedFlagSets.FlagSets {
        fs.AddFlagSet(f)
    }

    return cmd
}

配置文件加载

kube-scheduler的配置文件通常是一个YAML文件,包含了调度器的详细配置信息。配置文件的加载是通过viper库实现的,viper支持多种配置文件格式,包括JSON、TOML、YAML等。配置文件的加载过程会覆盖命令行参数中的默认值。

func loadConfigFile(configFile string) (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
    if configFile == "" {
        return nil, nil
    }

    data, err := ioutil.ReadFile(configFile)
    if err != nil {
        return nil, fmt.Errorf("unable to read config file %q: %v", configFile, err)
    }

    config := &kubeschedulerconfig.KubeSchedulerConfiguration{}
    if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, config); err != nil {
        return nil, fmt.Errorf("unable to decode config file %q: %v", configFile, err)
    }

    return config, nil
}

日志系统初始化

kube-scheduler的日志系统是通过klog库实现的,klog是Kubernetes项目中使用的一个日志库,支持日志级别、日志格式、日志输出等配置。日志系统的初始化通常在调度器启动的早期阶段完成,以确保后续的日志输出能够正常工作。

func initLogs() {
    logFlags := flag.NewFlagSet("logs", flag.ExitOnError)
    klog.InitFlags(logFlags)
    logFlags.Set("logtostderr", "true")
    logFlags.Set("v", "2")
}

客户端初始化

kube-scheduler需要与Kubernetes API Server进行通信,以获取集群状态和资源信息。客户端的初始化是通过client-go库实现的,client-go是Kubernetes官方提供的Go语言客户端库,支持REST API、Informer、Lister等功能。

func createClients(config *rest.Config) (clientset.Interface, informers.SharedInformerFactory, error) {
    client, err := clientset.NewForConfig(config)
    if err != nil {
        return nil, nil, fmt.Errorf("unable to create kube client: %v", err)
    }

    informerFactory := informers.NewSharedInformerFactory(client, 0)
    return client, informerFactory, nil
}

调度器初始化

调度器的初始化是kube-scheduler启动的核心步骤,涉及到调度队列、调度算法、调度缓存等核心组件的初始化。调度器的初始化过程通常包括以下几个步骤:

  1. 调度队列初始化:初始化调度队列,用于存储待调度的Pod。
  2. 调度算法初始化:初始化调度算法,用于评估和选择适合的节点。
  3. 调度缓存初始化:初始化调度缓存,用于存储集群状态和资源信息。
func createScheduler(config *kubeschedulerconfig.KubeSchedulerConfiguration, client clientset.Interface, informerFactory informers.SharedInformerFactory) (*scheduler.Scheduler, error) {
    schedulerCache := internalcache.New(30*time.Second, stopCh)
    schedulerQueue := internalqueue.NewSchedulingQueue()

    schedulerAlgorithm, err := scheduler.NewGenericScheduler(
        schedulerCache,
        schedulerQueue,
        config.AlgorithmSource,
        client,
        informerFactory,
    )
    if err != nil {
        return nil, fmt.Errorf("unable to create scheduler algorithm: %v", err)
    }

    scheduler := scheduler.New(
        client,
        informerFactory,
        schedulerAlgorithm,
        schedulerCache,
        schedulerQueue,
    )

    return scheduler, nil
}

插件初始化

kube-scheduler支持插件机制,允许用户通过插件扩展调度器的功能。插件的初始化通常在调度器初始化之后进行,插件可以注册到调度器的各个扩展点,如预选、优选、绑定等。

func createPlugins(config *kubeschedulerconfig.KubeSchedulerConfiguration) ([]scheduler.Plugin, error) {
    plugins := []scheduler.Plugin{}

    for _, pluginConfig := range config.Plugins {
        plugin, err := scheduler.NewPlugin(pluginConfig.Name, pluginConfig.Args)
        if err != nil {
            return nil, fmt.Errorf("unable to create plugin %q: %v", pluginConfig.Name, err)
        }

        plugins = append(plugins, plugin)
    }

    return plugins, nil
}

调度器启动

调度器的启动是kube-scheduler初始化的最后一步,启动后调度器会开始监听和处理Pod调度请求。调度器的启动过程通常包括以下几个步骤:

  1. 启动调度队列:启动调度队列,开始接收待调度的Pod。
  2. 启动调度算法:启动调度算法,开始评估和选择适合的节点。
  3. 启动调度缓存:启动调度缓存,开始同步集群状态和资源信息。
func runScheduler(scheduler *scheduler.Scheduler, stopCh <-chan struct{}) {
    scheduler.Run(stopCh)
}

scheduler初始化源码分析

NewSchedulerCommand函数

NewSchedulerCommand函数是kube-scheduler的入口函数,负责创建cobra.Command对象并解析命令行参数。该函数的主要作用是初始化调度器的命令行接口,并设置调度器的运行逻辑。

func NewSchedulerCommand() *cobra.Command {
    opts := options.NewOptions()
    cmd := &cobra.Command{
        Use: "kube-scheduler",
        Long: `The Kubernetes scheduler is a control plane process which assigns
Pods to Nodes. The scheduler determines which Nodes are valid placements for
each Pod in the scheduling queue according to constraints and available
resources. The scheduler then ranks each valid Node and binds the Pod to
a suitable Node.`,
        Run: func(cmd *cobra.Command, args []string) {
            if err := runCommand(cmd, opts, registryOptions...); err != nil {
                fmt.Fprintf(os.Stderr, "%v\n", err)
                os.Exit(1)
            }
        },
    }

    fs := cmd.Flags()
    namedFlagSets := opts.Flags()
    for _, f := range namedFlagSets.FlagSets {
        fs.AddFlagSet(f)
    }

    return cmd
}

Run函数

Run函数是kube-scheduler的启动函数,负责调度器的初始化过程。该函数的主要作用是加载配置文件、初始化日志系统、创建客户端、初始化调度器、初始化插件,并最终启动调度器。

func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Option) error {
    config, err := loadConfigFile(opts.ConfigFile)
    if err != nil {
        return err
    }

    initLogs()

    client, informerFactory, err := createClients(opts.ClientConnection)
    if err != nil {
        return err
    }

    scheduler, err := createScheduler(config, client, informerFactory)
    if err != nil {
        return err
    }

    plugins, err := createPlugins(config)
    if err != nil {
        return err
    }

    scheduler.RegisterPlugins(plugins...)

    stopCh := make(chan struct{})
    runScheduler(scheduler, stopCh)

    return nil
}

Setup函数

Setup函数是kube-scheduler的初始化函数,负责调度器的核心组件初始化。该函数的主要作用是创建调度队列、调度算法、调度缓存等核心组件,并最终创建调度器对象。

func Setup(config *kubeschedulerconfig.KubeSchedulerConfiguration, client clientset.Interface, informerFactory informers.SharedInformerFactory) (*scheduler.Scheduler, error) {
    schedulerCache := internalcache.New(30*time.Second, stopCh)
    schedulerQueue := internalqueue.NewSchedulingQueue()

    schedulerAlgorithm, err := scheduler.NewGenericScheduler(
        schedulerCache,
        schedulerQueue,
        config.AlgorithmSource,
        client,
        informerFactory,
    )
    if err != nil {
        return nil, fmt.Errorf("unable to create scheduler algorithm: %v", err)
    }

    scheduler := scheduler.New(
        client,
        informerFactory,
        schedulerAlgorithm,
        schedulerCache,
        schedulerQueue,
    )

    return scheduler, nil
}

createClients函数

createClients函数负责创建与Kubernetes API Server通信的客户端。该函数的主要作用是创建clientset.Interfaceinformers.SharedInformerFactory对象,用于与API Server进行通信和同步集群状态。

func createClients(config *rest.Config) (clientset.Interface, informers.SharedInformerFactory, error) {
    client, err := clientset.NewForConfig(config)
    if err != nil {
        return nil, nil, fmt.Errorf("unable to create kube client: %v", err)
    }

    informerFactory := informers.NewSharedInformerFactory(client, 0)
    return client, informerFactory, nil
}

createScheduler函数

createScheduler函数负责创建调度器对象。该函数的主要作用是初始化调度器的核心组件,包括调度队列、调度算法、调度缓存等,并最终创建调度器对象。

func createScheduler(config *kubeschedulerconfig.KubeSchedulerConfiguration, client clientset.Interface, informerFactory informers.SharedInformerFactory) (*scheduler.Scheduler, error) {
    schedulerCache := internalcache.New(30*time.Second, stopCh)
    schedulerQueue := internalqueue.NewSchedulingQueue()

    schedulerAlgorithm, err := scheduler.NewGenericScheduler(
        schedulerCache,
        schedulerQueue,
        config.AlgorithmSource,
        client,
        informerFactory,
    )
    if err != nil {
        return nil, fmt.Errorf("unable to create scheduler algorithm: %v", err)
    }

    scheduler := scheduler.New(
        client,
        informerFactory,
        schedulerAlgorithm,
        schedulerCache,
        schedulerQueue,
    )

    return scheduler, nil
}

createPlugins函数

createPlugins函数负责创建调度器插件。该函数的主要作用是根据配置文件中的插件配置,创建并初始化调度器插件。

func createPlugins(config *kubeschedulerconfig.KubeSchedulerConfiguration) ([]scheduler.Plugin, error) {
    plugins := []scheduler.Plugin{}

    for _, pluginConfig := range config.Plugins {
        plugin, err := scheduler.NewPlugin(pluginConfig.Name, pluginConfig.Args)
        if err != nil {
            return nil, fmt.Errorf("unable to create plugin %q: %v", pluginConfig.Name, err)
        }

        plugins = append(plugins, plugin)
    }

    return plugins, nil
}

scheduler初始化过程中的关键点

调度器配置

kube-scheduler的配置是通过命令行参数和配置文件共同决定的。命令行参数通常用于指定配置文件的路径、日志级别等基本信息,而配置文件则包含了调度器的详细配置信息,如调度算法、插件配置等。调度器的配置过程涉及到多个组件的初始化,包括调度队列、调度算法、调度缓存等。

插件机制

kube-scheduler支持插件机制,允许用户通过插件扩展调度器的功能。插件可以注册到调度器的各个扩展点,如预选、优选、绑定等。插件的初始化通常在调度器初始化之后进行,插件可以动态加载和卸载,极大地增强了调度器的灵活性和扩展性。

调度器扩展性

kube-scheduler的设计目标是高效、可扩展和可配置,以满足不同场景下的调度需求。调度器的扩展性主要体现在插件机制和调度算法的可配置性上。用户可以通过插件机制扩展调度器的功能,也可以通过配置调度算法来满足不同的调度需求。

总结

kube-scheduler的初始化过程是整个调度器启动的关键步骤,涉及到命令行参数解析、配置文件加载、日志系统初始化、客户端初始化、调度器初始化、插件初始化等多个环节。本文详细分析了kube-scheduler的初始化流程,深入探讨了其源码实现,并总结了其中的关键点。通过本文的分析,读者可以更好地理解kube-scheduler的初始化方法,为深入研究和优化kube-scheduler提供参考。

参考文献

  1. Kubernetes官方文档: https://kubernetes.io/docs/concepts/scheduling/kube-scheduler/
  2. kube-scheduler源码: https://github.com/kubernetes/kubernetes/tree/master/pkg/scheduler
  3. cobra库文档: https://github.com/spf13/cobra
  4. viper库文档: https://github.com/spf13/viper
  5. klog库文档: https://github.com/kubernetes/klog
  6. client-go库文档: https://github.com/kubernetes/client-go
推荐阅读:
  1. 如何利用go语言实现Git重命名远程分支  
  2. Go语言的WaitGroup怎么使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

go语言 scheduler kube-scheduler

上一篇:vue3+element-plus Dialog对话框的使用与setup写法是什么

下一篇:vue3中的Proxy为什么一定要用Reflect

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》