Kubernetes Scheduler Extender浅析

时间:2022-07-22
本文章向大家介绍Kubernetes Scheduler Extender浅析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://kubernetes.io/docs/concepts/extend-kubernetes/extend-cluster/#scheduler-extensions

Scheduler 组件可以视为一种监视 watche 和将 Pod 分配 assign 到 Node 的特殊类型控制器 controller。在 Kubernetes 里,默认的 Scheduler 完全可以被替代,又或者增加多个 Scheduler 来同时或者一起调度 Pod,这在 Kuberntes 里称为 Mulitple Scheduler。

同时 Scheduler 也提供了 webhook 的机制,来让用户通过编写自己定义的 Shedueler Exetension 来为调度 Pod 去过滤 filter 和优化 prioritize 节点。

关于 Scheduler Extender 看下面官方文档就够了,这里补充一些。

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md

Scheduler Extender 实际上是一个额外的调度进程,用来 Filter 和 Prioritize 节点的。所以顺理成章的,用户需要实现自己的 Filter 和 Prioritize 方法。另外 Extender 也可以实现 Bind 方法,来实现将 Pod Bind 到 Node 上的操作。

// Holds the parameters used to communicate with the extender. If a verb is unspecified/empty,
// it is assumed that the extender chose not to provide that extension.
type ExtenderConfig struct {
	// URLPrefix at which the extender is available
	URLPrefix string `json:"urlPrefix"`
	// Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender.
	FilterVerb string `json:"filterVerb,omitempty"`
	// Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender.
	PrioritizeVerb string `json:"prioritizeVerb,omitempty"`
	// Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender.
	// If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver.
	BindVerb string `json:"bindVerb,omitempty"`
	// The numeric multiplier for the node scores that the prioritize call generates.
	// The weight should be a positive integer
	Weight int `json:"weight,omitempty"`
	// EnableHttps specifies whether https should be used to communicate with the extender
	EnableHttps bool `json:"enableHttps,omitempty"`
	// TLSConfig specifies the transport layer security config
	TLSConfig *client.TLSClientConfig `json:"tlsConfig,omitempty"`
	// HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize
	// timeout is ignored, k8s/other extenders priorities are used to select the node.
	HTTPTimeout time.Duration `json:"httpTimeout,omitempty"`
}

可以见到,用户需要提供一个 sheduler policy 的配置文件,其中包括了 Extender 的前缀,Filter 和 Priorize 和 Bind 等信息。

下面是一个配置文件的 json 例子。已知 predicatespriorities 两个字段的值皆为默认值,关注一下 extenders 字段的值,只有在这里配置了,Kubernetes 在调度 Pod 的时候才会过这里这一层。

{
  "predicates": [
    {
      "name": "HostName"
    },
    {
      "name": "MatchNodeSelector"
    },
    {
      "name": "PodFitsResources"
    }
  ],
  "priorities": [
    {
      "name": "LeastRequestedPriority",
      "weight": 1
    }
  ],
  "extenders": [
    {
      "urlPrefix": "http://127.0.0.1:12345/api/scheduler",
      "filterVerb": "filter",
      "enableHttps": false
    }
  ]
}

我们熟知的**开源的 GPU 调度插件也是基于这个机制来实现 GPU 资源的调度 gpu-share-extender 的。 关于 Scheduler Extender 的实现,其实用什么语言都能做。关键是要实现到 filter 和 prioritize 的功能。 这是一个完全用 Bash 脚本完成的 Extender rothgar/bashScheduler。

关于如何编写一个一个 Scheduler Exetender,我建议直接参考 IBM 博客的一篇文章 Create a custom Kubernetes scheduler