图解kubernetes调度器framework核心数据结构

本文探讨了kubernetes调度器Framework的核心实现,包括扩展点、上下文、CycleState、Permit机制以及核心数据结构如插件集合、等待Pod集合等。详细介绍了插件工厂注册、注册实现和插件调用方法,揭示了调度流程中的数据管理和并发控制策略。
摘要由CSDN通过智能技术生成

Framework是kubernetes扩展的第二种实现,相比SchedulerExtender基于远程独立Service的扩展,Framework核心则实现了一种基于扩展点的本地化的规范流程管理机制

1. 扩展实现目标

Framework的设计在官方文档中已经有明确的描述,当前还没有Stable, 本文目前基于1.18版本聊一聊除了官方描述外的实现的上的一些细节

1.1 阶段扩展点

image.png目前官方主要是围绕着之前的预选和优选阶段进行扩展,提供了更多的扩展点,其中每个扩展点都是一类插件,我们可以根据我们的需要在对应的阶段来进行扩展插件的编写,实现调度增强

在当前版本中优先级插件已经抽取到了framework中,后续应该会继续将预选插件来进行抽取,这块应该还得一段时间才能稳定

1.2 context与CycleState

image.png在Framework的实现中,每个插件扩展阶段调用都会传递context和CycleState两个对象,其中context与我们在大多数go编程中的用法类似,这里主要是用于多阶段并行处理的时候的统一退出操作,而CycleState则存储当前这一个调度周期内的所有数据,这是一个并发安全的结构,内部包含一个读写锁

1.3 Bind Permit

image.pngPermit是在进行Bind绑定操作之前进行的一项操作,其主要设计目标是在进行bind之前,进行最后一道决策,即当前pod是否准许进行最终的Bind操作,具有一票否决权,如果里面的插件拒绝,则对应的pod会重新进行调度

2. 核心源码实现

2.1 Framework核心数据结构

image.pngFramework的核心数据结构简单的来说分为三部分:插件集合(针对每个扩展阶段都会有自己的集合)、元数据获取接口(集群和快照数据的获取)、等待Pod集合

2.1.1 插件集合

插件集合中会根据不同的插件类型,来进行分类保存, 其中还有一个插件的优先级存储map,目前只有在优选阶段使用,后续可能会加入预选的优先级

    pluginNameToWeightMap map[string]int
    queueSortPlugins      []QueueSortPlugin
    preFilterPlugins      []PreFilterPlugin
    filterPlugins         []FilterPlugin
    postFilterPlugins     []PostFilterPlugin
    scorePlugins          []ScorePlugin
    reservePlugins        []ReservePlugin
    preBindPlugins        []PreBindPlugin
    bindPlugins           []BindPlugin
    postBindPlugins       []PostBindPlugin
    unreservePlugins      []UnreservePlugin
    permitPlugins         []PermitPlugin

2.1.2 集群数据获取

主要是集群中的一些数据获取接口的实现,主要是为了实现FrameworkHandle, 该接口主要是提供一些数据的获取的接口和集群操作的接口给插件使用

    clientSet       clientset.Interface
    informerFactory informers.SharedInformerFactory
    volumeBinder    *volumebinder.VolumeBinder
    snapshotSharedLister  schedulerlisters.SharedLister

2.1.3 等待pod集合

等待pod集合主要是存储在Permit阶段进行等待的pod,如果在等待周期中pod被删除,则会直接拒绝

    waitingPods           *waitingPodsMap

2.1.4 插件工厂注册表

通过插件工厂来存储所有注册的插件工厂,然后通过插件工厂构建具体的插件

    registry              Registry

2.2 插件工厂注册表

image.png

2.2.1 插件工厂函数

工厂函数即传入对应的参数,构建一个Plugin,其中FrameworkHandle主要是用于获取快照和集群的其他数据

type PluginFactory = func(configuration *runtime.Unknown, f FrameworkHandle) (Plugin, error)

2.2.2 插件工厂的实现

在go里面大多数插件工厂的实现都是通过map来实现这里也是一样,对外暴露Register和UnRegister接口

type Registry map[string]PluginFactory

// Register adds a new plugin to the registry. If a plugin with the same name
// exists, it returns an error.
func (r Registry) Register(name string, factory PluginFactory) error {
    if _, ok := r[name]; ok {
        return fmt.Errorf("a plugin named %v already exists", name)
    }
    r[name] = factory
    return nil
}

// Unregister removes an existing plugin from the registry. If no plugin with
// the provided name exists, it returns an error.
func (r Registry) Unregister(name string) error {
    if _, ok := r[name]; !ok {
        return fmt.Errorf("no plugin named %v exists", name)
    }
    delete(r, name)
    return nil
}

// Merge merges the provided registry to the current one.
func (r Registry) Merge(in Registry) error {
    for name, factory := range in {
        if err := r.Register(name, factory); err != nil {
            return err
        }
    }
    return nil
}

2.3 插件注册实现

image.png这里以preFilterPlugins为例展示整个流程的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值