一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
一、kube-scheduler
职责及调度流程
Master
节点上的核心服务之一 Scheduler
服务(也就是 kube-scheduler
进程)负责实现 Pod
的调度,整个调度的过程通过执行一系列复杂的算法,最终为每个 Pod
都计算出一个最佳的目标节点。
kube-scheduler
通过监听kube-apiserver
,获取未调度的Pod
列表,通过调度算法计算出分配给Pod
的Node
,并将Node
信息与Pod
进行绑定(Bind
),结果存储在etcd
中。而根据调度结果执行Pod
的创建操作是由Node
上的kubelet
执行的。
**kube-scheduler
职责及调度流程 **主要分为:
- 集群高可用
- 调度资源监听
- 调度节点分配
1. 集群高可用
kube-scheduler
可以设置leader-elect
启动参数,这样会通过etcd
进行节点选主。kube-scheduler
和kube-controller-manager
都使用了一主多从的高可用方案。简单理解的话是这样的:
kube-scheduler
启动时,会在etcd
中创建endpoint
,endpoint
的信息中记录了当前的leader
节点信息,以及上次更新时间。leader
节点会定期更新endpoint
的信息,维护自己的leader
身份,每个从节点的服务都会定期检查endpoint
的信息,如果endpoint
的信息在规定的时间范围内没有更新,从节点将会尝试更新自己的leader
节点。
2. 调度资源监听
通过 Watch
机制监听 kube-apiserver
上资源(pod
和 node
)的变化。
kube-apiserver
给其他组件(kubectl
、kube-controller-manager
、kube-scheduler
等)提供了一套Watch
机制用于监控各种资源的变化。
类似于消息中间件的 发布-订阅模式(push
)。
步骤:
kube-apiserver
初始化时,建立对etcd
的连接并watch etcd
- 当
kube-scheduler
客户端调用watch api
时,kube-apiserver
内部会建立一个watchserver
watchserver
会从etcd
中获取资源的watch event
,watch event
经过加工过滤后就会发送给客户端,watch api
本质上是一个GET
请求。
通常有两种实现模式:
- 通过
websocket
协议发送- 通过
Transfer-Encoding=chunked
方式建立长连接
3. 调度节点分配
调度节点分配分为两个环节:预选(Predicates
)与优选 (Priorites
)。调度资源监听也是为了这个环节提供数据输入。
- 预选:遍历所有目标
Node
,根据配置的预选策略Predicates Policies
过滤掉不符合策略的Node
,剩下符合要求的候选节点。
预选的输出将会作为优选的输入。预选策略默认使用的是 DefaultProvider 中定义的 default predicates policies 集合。
- 优选:根据配置的优选策略
Priorites Policies
,为前一步过滤后的Node
进行打分排名,得分最高的Node
将作为最适合的Node
,该Pod
将绑定(Bind
)到最适合的 Node 上。
如果打分排名后,有多个
Node
并列得分最高,kube-scheduler
会从中随机选取一个Node
作为目标Node
。优选策略默认使用的是DefaultProvider
中定义的default priorites policies
集合。
kube-scheduler
调度节点分配需要考虑的问题较多,有:
- 公平:如何保证每个
Node
都能够分配资源 - 资源高效利用:集群所有资源能够被最大化使用
- 效率:调度性能高,能够尽快对大批量的
Pod
完成调度工作 - 灵活:允许用户自定义调度逻辑
二、常用参数
kube-scheduler
在启动的时候也可以指定一些参数,列表如下:
参数 | 含义 | 默认值 |
---|---|---|
--adress | 监听地址 | "0.0.0.0" |
--port | 调度器监听的端口 | 10251 |
--algorithm-provider | 提供调度算法的对象 | "DefaultProvider" |
--master | API Server 的 HTTP 地址 | / |
--profiling | 是否开启 profiling,开启后可以在 host:port/debug/pprof 访问 profile 信息 | true |
--scheduler-name | 调度器名称,用来唯一确定该调度器 | "default-shcheduler" |
--kube-api-burst | 和 API Server 通信时的最大 burst 值 | 100 |
--kube-api-qps | 和 API Server 通信时的 QPS 值 | 50 |
--log_dir | 日志保存的目录 | / |
--policy-config-file | json 配置文件,用来指定调度器的 Predicates 和 Priorites 策略 | / |
关于自定义策略的 JSON
文件的格式示例如下:
{
"kind": "Policy",
"apiVersion": "v1",
"predicates":
[
{ "name": "PodFitsHostPorts" },
{ "name": "PodFitsResources" },
{ "name": "NoDiskConflict" },
{ "name": "NoVolumeZoneConflict" },
{ "name": "MatchNodeSelector" },
{ "name": "HostName" },
],
"priorities":
[
{ "name": "LeastRequestedPriority", "weight": 1 },
{ "name": "BalancedResourceAllocation", "weight": 1 },
{ "name": "ServiceSpreadingPriority", "weight": 1 },
{ "name": "EqualPriority", "weight": 1 },
],
"hardPodAffinitySymmetricWeight": 10,
"alwaysCheckAllPredicates": false,
}