概述
Scheduler 组件可以视为一种监视 watch 和将 Pod 分配 assign 到 Node 的特殊类型控制器 controller。在 Kubernetes 里,默认的 Scheduler 完全可以被替代,又或者增加多个 Scheduler 来同时或者一起调度 Pod,这在 Kubernetes 里称为 Multiple Scheduler。
同时 Scheduler 也提供了 webhook 的机制,来让用户通过编写自己定义的 Scheduler Extension 来为调度 Pod 去过滤 filter 和优化 prioritize 节点。
关于 Scheduler Extender 看下面官方文档就够了,这里补充一些。
代码实现
Scheduler Extender 实际上是一个额外的调度进程,用来 Filter 和 Prioritize 节点的。所以顺理成章的,用户需要实现自己的 Filter 和 Prioritize 方法。另外 Extender 也可以实现 Bind 方法,来实现将 Pod Bind 到 Node 上的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 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"`
}
|
可以见到,用户需要提供一个 scheduler policy 的配置文件,其中包括了 Extender 的前缀,Filter 和 Prioritize 和 Bind 等信息。
下面是一个配置文件的 json 例子。已知 predicates
和 priorities
两个字段的值皆为默认值,关注一下 extenders
字段的值,只有在这里配置了,Kubernetes 在调度 Pod 的时候才会过这里这一层。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
{
"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 Extender,我建议直接参考 IBM 博客的一篇文章 Create a custom Kubernetes scheduler。
参考资料
- scheduler-extensions
警告
本文最后更新于 2017年2月1日,文中内容可能已过时,请谨慎参考。