图解kubernetes调度器SchedulerExtender扩展

在kubernetes的scheduler调度器的设计中为用户预留了两种扩展机制SchdulerExtender与Framework,本文主要浅谈一下SchdulerExtender的实现, 因为还有一篇Framework, 所以本文的k8s代码切到1.18版本

1. 设计思路

图解kubernetes调度器SchedulerExtender扩展_第1张图片

1.1 实现机制

SchdulerExtender是kubernets外部扩展方式,用户可以根据需求独立构建调度服务,实现对应的远程调用接口(目前是http), scheduler在调度的对应阶段会根据用户定义的资源和接口来进行远程调用,对应的service根据自己的资源数据和scheduler传递过来的中间调度结果来进行决策

1.2 服务插拔

extender只需要实现对应插件的接口,并编写yaml文件来进行注册对应的服务接口,就可以实现scheduler的扩展,不需要修改任何调度器的代码,即可实现调度插件的插拔

1.3 资源存储

因为是独立的服务,extender可以实现自定义资源的存储与获取,甚至可以不依赖于etcd使用第三方的存储来进行资源的存储,主要是用于kubernetes中不支持的那些资源的调度扩展

2. SchedulerExtender

2.1 接口与实现

2.1.1 接口声明

Scheduler主要用于扩展


type SchedulerExtender interface {
    // Name returns a unique name that identifies the extender.
    Name() string

    //预选阶段, 进行筛选
    Filter(pod *v1.Pod, nodes []*v1.Node) (filteredNodes []*v1.Node, failedNodesMap extenderv1.FailedNodesMap, err error)

    // 优选阶段,参与优选评分
    Prioritize(pod *v1.Pod, nodes []*v1.Node) (hostPriorities *extenderv1.HostPriorityList, weight int64, err error)

    // extender对pod指向绑定操作
    Bind(binding *v1.Binding) error

    // 扩展是否支持bind
    IsBinder() bool

    // 是否对对应的pod的资源感兴趣
    IsInterested(pod *v1.Pod) bool
    // 抢占阶段
    ProcessPreemption(
        pod *v1.Pod,
        nodeToVictims map[*v1.Node]*extenderv1.Victims,
        nodeInfos listers.NodeInfoLister) (map[*v1.Node]*extenderv1.Victims, error)

    // 是否支持抢占
    SupportsPreemption() bool

    // IsIgnorable returns true indicates scheduling should not fail when this extender
    // is unavailable. This gives scheduler ability to fail fast and tolerate non-critical extenders as well.
    IsIgnorable() bool
}

2.1.2 默认实现

// HTTPExtender implements the algorithm.SchedulerExtender interface.
type HTTPExtender struct {
    extenderURL      string
    preemptVerb      string
    filterVerb       string
    prioritizeVerb   string
    bindVerb         string
    weight           int64          // 对应的权重
    client           *http.Client // 负责http接口通过
    nodeCacheCapable bool          // 是否传递node元数据
    managedResources sets.String  // 当前extender管理的资源
    ignorable        bool
}

extender的默认是海鲜是同过 HTTPExtender实现,即基于http协议通过json来进行数据传递,其核心数据结构如下

2.2 关键实现机制

2.2.1 远程通信接口

图解kubernetes调度器SchedulerExtender扩展_第2张图片其实通信很简单,通过http协议json序列化方式来进行远程post的提交,并序列化返回的结果

// Helper function to send messages to the extender
func (h *HTTPExtender) send(action string, args interface{}, result interface{}) error {
    // 序列化
    out, err := json.Marshal(args)
    if err != nil {

你可能感兴趣的:(go,源码,编程,并发)