主要讲三部分的内容:
- Kubernetes 的调度过程
- Kubernetes 的基础调度能力(资源调度、关系调度)
- Kubernetes 高级调度能力(优先级、抢占)
Kubernetes 调度过程
首先来看第一部分 - Kubernetes 的调度过程。如下图所示,画了一个很简单的 Kubernetes 集群架构,它包括了一个 kube-ApiServer,一组 webhooks 的 Controller,以及一个默认的调度器 kube-Scheduler,还有两台物理机节点 Node1 和 Node2,分别在上面部署了两个 kubelet。
我们来看一下,假如要向这个 Kubernetes 集群提交一个 pod,它的调度过程是什么样的一个流程?
假设我们已经写好了一个 yaml 文件,就是下图中的橙色圆圈 pod1,然后我们往 kube-ApiServer 里面提交这个 yaml 文件。
此时 ApiServer 会先把这个待创建的请求路由给我们的 webhooks 的 Controlles 进行校验。
在通过校验之后,ApiServer 会在集群里面生成一个 pod,但此时生成的 pod,它的 nodeName 是空的,并且它的 phase 是 Pending 状态。在生成了这个 pod 之后,kube-Scheduler 以及 kubelet 都能 watch 到这个 pod 的生成事件,kube-Scheduler 发现这个 pod 的 nodeName 是空的之后,会认为这个 pod 是处于未调度状态。
接下来,它会把这个 pod 拿到自己里面进行调度,通过一系列的调度算法,包括一系列的过滤和打分的算法后,Schedule 会选出一台最合适的节点,并且把这一台节点的名称绑定在这个 pod 的 spec 上,完成一次调度的过程。
此时我们发现,pod 的 spec 上,nodeName 已经更新成了 Node1 这个 node,更新完 nodeName 之后,在 Node1 上的这台 kubelet 会 watch 到这个 pod 是属于自己节点上的一个 pod。
然后它会把这个 pod 拿到节点上进行操作,包括创建一些容器 storage 以及 network,最后等所有的资源都准备完成,kubelet 会把状态更新为 Running,这样一个完整的调度过程就结束了。
通过刚刚一个调度过程的演示,我们用一句话来概括一下调度过程:它其实就是在做一件事情,就是把 pod 放到合适的 node 上。
这里有个关键字“合适”,什么是合适呢?这里给出了几点合适定义的特点:
1、首先要满足 pod 的资源要求;
2、其次要满足 pod 的一些特殊关系的要求;
3、再次要满足 node 的一些限制条件的要求;
4、最后还要做到整个集群资源的合理利用。
做到这些要求之后,可以认为我们把 pod 放到了一个合适的节点上了。