3.2.8 Scheduler 调度
调度器通过 Kubernetes 的监测(Watch)机制来发现集群中新创建但是未被调度到节点上的 Pod。 对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler 会选择一个最优的节点去运行这个 Pod。 然而,Pod 内的每一个容器对资源都有不同的需求, 而且 Pod 本身也有不同的需求。因此,Pod 在被调度到节点上之前根据这些特定的调度需求,需要对集群中的节点进行一次过滤。
在一个集群中,满足一个 Pod 调度请求的所有节点称之为 可调度节点。 如果没有任何一个节点能满足 Pod 的资源请求, 那么这个 Pod 将一直停留在未调度状态直到调度器能够找到合适的 Node。
调度器先在集群中找到一个 Pod 的所有可调度节点,然后根据一系列函数对这些可调度节点打分, 选出其中得分最高的节点来运行 Pod。之后,调度器将这个调度决定通知给 kube-apiserver,这个过程叫做 绑定。
kube-scheduler 给一个 Pod 做调度选择时包含两个步骤:过滤和打分。过滤阶段会将所有满足 Pod 调度需求的节点选出来。 例如,PodFitsResources 过滤函数会检查候选节点的可用资源能否满足 Pod 的资源请求。 在过滤之后,得出一个节点列表,里面包含了所有可调度节点;通常情况下, 这个节点列表包含不止一个节点。如果这个列表是空的,代表这个 Pod 不可调度。
在打分阶段,调度器会为 Pod 从所有可调度节点中选取一个最合适的节点。 根据当前启用的打分规则,调度器会给每一个可调度节点进行打分。最后,kube-scheduler 会将 Pod 调度到得分最高的节点上。 如果存在多个得分最高的节点,kube-scheduler 会从中随机选取一个。
所以综上可以看到,调度时候其实是涉及多个因素考虑的, 不仅仅是节点资源等因素,在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、 亲和以及反亲和要求、数据局部性、负载间的干扰等等 。
那就产生了一个疑问,我们如何查看kube-scheduler的打分情况呢?默认情况下kube-scheduler采集的日志是不会显示pod调度过程中的打分情况的。
修改scheduler运行args参,将 --v=5 修改为--v=7, 修改完毕后会重启scheduler pod,在pod重启过程中,如果遇到pod调度,会被hung住,这个需要结合实际业务判断影响
图:Scheduler Pod日志等级设定
下面是个典型的pod调度打分过程。我们可以看到针对每一个调度影响方面,scheduler都会对所有适合的node进行打分,最后打分高的node是优先被调度器选择的节点。
图:Scheduler Pod调度日志示例