You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
5.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 调度器总体设计
## 调度器源码分段阅读目录
- [调度器入口](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/Kubernetes%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0-Scheduler-P1-%E8%B0%83%E5%BA%A6%E5%99%A8%E5%85%A5%E5%8F%A3%E7%AF%87.md)
- [调度器框架](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/Kubernetes%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0-Scheduler-P2-%E8%B0%83%E5%BA%A6%E5%99%A8%E6%A1%86%E6%9E%B6.md)
- [Node筛选算法](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/Kubernetes%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0-Scheduler-P3-Node%E7%AD%9B%E9%80%89%E7%AE%97%E6%B3%95.md)
- [Node优先级算法](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/Kubernetes%E6%BA%90%E7%A0%81%E5%AD%A6%E4%B9%A0-Scheduler-P4-Node%E4%BC%98%E5%85%88%E7%BA%A7%E7%AE%97%E6%B3%95.md)
- [Pod优先级抢占调度](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/Kubernetes源码学习-Scheduler-P5-Pod优先级抢占调度.md)
## 概览
首先列出官方md链接,讲解颇为生动:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduler.md
这里用结合自己阅读代码的理解做一下翻译。
### 工作模式
Kubernetes scheduler独立运作与其他主要组件之外(例如API Server),它连接API Server,watch观察,如果有PodSpec.NodeName为空的Pod出现,则开始工作,通过一定得筛选算法,筛选出合适的Node之后,向API Server发起一个绑定指示,申请将Pod与筛选出的Node进行绑定。
### 代码层级
回归到代码本身,scheduler的设计分为3个主要代码层级:
- `cmd/kube-scheduler/scheduler.go`: 这里的main()函数即是scheduler的入口,它会读取指定的命令行参数,初始化调度器框架,开始工作
- `pkg/scheduler/scheduler.go`: 调度器框架的整体代码,框架本身所有的运行、调度逻辑全部在这里
- `pkg/scheduler/core/generic_scheduler.go`: 上面是框架本身的所有调度逻辑,包括算法,而这一层,是调度器实际工作时使用的算法,默认情况下,并不是所有列举出的算法都在被实际使用,参考位于文件中的`Schedule()`函数
### 调度算法逻辑
逻辑图:
```
一个没有指定Spec.NodeName的:
+---------------------------------------------+
| Schedulable nodes: |
| |
| +--------+ +--------+ +--------+ |
| | node 1 | | node 2 | | node 3 | |
| +--------+ +--------+ +--------+ |
| |
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
断言(硬性指标)筛选: node 3 资源不足
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
| 剩余可选nodes: |
| +--------+ +--------+ |
| | node 1 | | node 2 | |
| +--------+ +--------+ |
| |
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
优先级判断: node 1: priority=2
node 2: priority=5
+-------------------+-------------------------+
|
|
v
选择 max{node priority} = node 2
node2则成为成功筛选出的与pod绑定的节点
```
为了给pod挑选出合适的node,调度器做出如下尝试步骤:
- 第一步,通过一系列的predicates(断言)指标,排除不合适的node,例如:pod.resources.requests.memory: 16Gi, node则计算:node.capacity 减去node上现有的所有pod的pod.resources.requests.memory的总和,如果差小于16Gi,那么则此项predicates结果为false,排除此节点
- 第二步,对通过了上一步筛选的node,执行一系列的优先级计算函数,计算的对象是node的负载情况,负载是即是node上现有的所有pod的pod.resources.requests的资源的总和除以node.capacity,值越高则负载越高,优先级越低
- 最终,挑选出了最高优先级的node,若有多个,则随机挑选其中一个
### Predicates and priorities policies
调度算法一共由Predicates和priorities这两部分组成,Predicates(断言)是用来过滤node的一系列策略集合,Priorities是用来优选node的一系列策略集合。默认情况下,kubernetes提供内建predicates/priorities策略,代码集中于`pkg/scheduler/algorithm/predicates/predicates.go` 和 `pkg/scheduler/algorithm/priorities`内.
### 调度策略扩展
管理员可以选择要应用的预定义调度策略中的哪一个,开发者也可以添加自定义的调度策略。
### 修改调度策略
默认调度策略是通过defaultPredicates() 和 defaultPriorities()这两个函数定义的,源码在 `pkg/scheduler/algorithmprovider/defaults/defaults.go`,我们可以通过命令行flag --policy-config-file CONFIG_FILE 来修改默认的调度策略。除此之外,也可以在`pkg/scheduler/algorithm/predicates/predicates.go` `pkg/scheduler/algorithm/priorities`源码中添加自定义的predicate和prioritie策略,然后注册到`defaultPredicates()`/`defaultPriorities()`中来实现自定义调度策略。