S_lion's Studio

k8s-scheduler原理

字数统计: 913阅读时长: 3 min
2021/10/03 Share

scheduler作用

负责整个集群资源的调度功能,根据特定的调度算法和策略,将 Pod 调度到最优的工作节点上面去,从而更加合理、更加充分的利用集群的资源。

工作机制

根据特定的调度算法和调度策略将 Pod 调度到合适的 Node 节点上去,是一个独立的二进制程序,启动之后会一直监听 API Server,获取到 PodSpec.NodeName 为空的 Pod,对每个 Pod 都会创建一个 binding。

Scheduler 提供的调度流程分为预选 (Predicates) 和优选 (Priorities) 两个步骤:

  • 预选,K8S会遍历当前集群中的所有 Node,筛选出其中符合要求的 Node 作为候选
  • 优选,K8S将对候选的 Node 进行打分

预选阶段首先遍历全部节点,过滤掉不满足条件的节点,属于强制性规则,这一阶段输出的所有满足要求的 Node 将被记录并作为第二阶段的输入,如果所有的节点都不满足条件,那么 Pod 将会一直处于 Pending 状态,直到有节点满足条件,在这期间调度器会不断的重试。

优选阶段即再次对节点进行筛选,如果有多个节点都满足条件的话,那么系统会按照节点的优先级(priorites)大小对节点进行排序,最后选择优先级最高的节点来部署 Pod 应用。

Queue

Kubernetes Scheduler 在多任务情况下,他是如何工作的? Queue,队列方式工作的,也就是说,即便有多个调度任务同时在 etcd 中等待调度, Scheduler 每次只会调度一个任务(和 Master 的数量无关)。内部逻辑:

  1. Scheduler 内部维护一个调度的pods队列podQueue, 并监听APIServer。

  2. 当我们创建Pod时,首先通过 API Server 往 etcd 写入 pod 元数据。

  3. 调度器通过 Informer 监听 pods 状态,当有新增 pod 时,将 pod 加入到 PodQueue中。

  4. 调度器中的主进程,会不断的从podQueue取出的pod,并将pod进入调度分配节点环节

  5. 调度环节分为两个步奏, Filter过滤满足条件的节点 、 Prioritize根据pod配置,例如资源使用率,亲和性等指标,给这些节点打分,最终选出分数最高的节点。

  6. 分配节点成功, 调用apiServer的binding pod 接口, 将pod.Spec.NodeName设置为所分配的那个节点。

  7. 节点上的kubelet同样监听ApiServer,如果发现有新的pod被调度到所在节点,调用本地的dockerDaemon 运行容器。

    假如调度器尝试调度 Pod 不成功,如果开启了优先级和抢占功能,会尝试做一次抢占,将节点中优先级较低的pod删掉,并将待调度的pod调度到节点上。 如果未开启,或者抢占失败,会记录日志,并将pod加入 PodQueue 队尾(这意味着,如果调度队列很长,你只有多等待了)。

  8. 经过预选筛选和优选打分之后,K8S选择分数最高的 Node 来运行 Pod,如果最终有多个 Node 的分数最高,那么 Scheduler 将从当中随机选择一个 Node 来运行 Pod。

预选策略

如果开启了 TaintNodesByCondition(从 1.12 开始为 beta级别,默认开启) 特性,则 CheckNodeCondition、CheckNodeMemoryPressure、CheckNodeDiskPressure、CheckNodePIDPressure 预选策略则会被禁用,PodToleratesNodeNoExecuteTaints、CheckNodeUnschedulable 则会启用。

优选策略

如果开启了 ResourceLimitsPriorityFunction(默认不开启) 特性,则 ResourceLimitsPriority 会被启用。

高可用

查看etcd篇的leader选举,没有额外设置都是走的默认配置(endpoint),可以在scheduler.conf中设置。

CATALOG
  1. 1. scheduler作用
  2. 2. 工作机制
    1. 2.1. Queue
    2. 2.2. 预选策略
    3. 2.3. 优选策略
  3. 3. 高可用