scheduler调度流程

94 阅读5分钟

Kubernetes 的 Scheduler 负责将 Pod 调度到合适的 Node 上运行。调度的目标是确保 Pod 在集群中的高效运行,并满足资源需求、拓扑要求等各种约束条件。下面是 Kubernetes Scheduler 的详细调度流程:

1. 调度器的工作流程概述

Kubernetes Scheduler 主要包括以下几个步骤:

  1. 监听待调度的 Pod:Scheduler 监视 API 服务器中的 Pod 列表,查找没有被调度的 Pod(状态为 Pending 的 Pod)。
  2. 选择适合的节点:Scheduler 根据 Pod 的资源需求、节点的可用资源、调度策略、亲和性和反亲和性等信息选择一个合适的节点。
  3. 将 Pod 绑定到节点:一旦选择了节点,Scheduler 会将 Pod 绑定到该节点,并将信息更新到 API 服务器。
  4. 执行调度:节点的 kubelet 会接收到更新,并开始启动容器来运行该 Pod。

2. Scheduler 调度流程的详细步骤

步骤 1:监听待调度的 Pod

  • Pod 状态为 Pending:Scheduler 只会调度状态为 Pending 的 Pod,也就是那些还没有被绑定到节点的 Pod。
  • Pod 和调度器:Pod 会首先被创建并发送到 Kubernetes 的 API 服务器,Scheduler 会监控这些 Pod 的状态。
  • Pod 资源需求:每个 Pod 在创建时可以定义其对资源(如 CPU、内存、存储等)的请求和限制(resources.requestsresources.limits)。

步骤 2:调度器选择适合的节点

Scheduler 会根据以下几个因素来选择合适的节点:

  1. Node 可用性

    • Scheduler 会查询所有可用节点,并根据 Node 的资源(CPU、内存、存储等)和 Pod 的资源请求来筛选合适的节点。
    • 如果节点资源不足,Pod 将无法调度到该节点。
  2. Pod 的亲和性和反亲和性(Affinity/Anti-Affinity)

    • NodeAffinity:Pod 可以指定必须调度到具有特定标签的节点上,或者排除特定标签的节点。
    • PodAffinity:Pod 可以指定它应该和其他特定的 Pod 一起调度到同一个节点上。
    • PodAntiAffinity:Pod 可以指定它应该避免和其他特定的 Pod 调度到同一个节点上。 亲和性和反亲和性可以基于标签选择器来指定。
  3. 资源请求和限制

    • Scheduler 会根据 Pod 的资源请求和节点的资源使用情况进行匹配。
    • 例如,如果 Pod 请求 2 CPU 和 4GB 内存,而节点只有 1 CPU 和 2GB 内存,那么该 Pod 无法被调度到这个节点。
  4. Taints 和 Tolerations

    • 节点可以通过 taints 来标记其不适合某些 Pod 的调度,只有具有相应 tolerations 的 Pod 才能被调度到这些节点上。
    • Taints 是一种保护机制,防止 Pod 被调度到不适合的节点。
  5. 资源均衡

    • Scheduler 会尽量保证集群资源的均衡,避免某些节点资源的过度消耗。
    • Kubernetes 会根据各个节点的资源使用情况(例如 CPU、内存的消耗量)来做负载均衡,确保 Pod 被均匀调度。
  6. Priority 和 Preemption

    • Kubernetes 支持 Pod 优先级,调度器会优先调度优先级更高的 Pod。
    • 如果集群中没有足够的资源来调度新 Pod,调度器会选择抢占低优先级的 Pod,释放资源来调度高优先级的 Pod。
  7. 其他约束

    • PodDisruptionBudgets(PDB) :定义了最小的 Pod 副本数量,Scheduler 会确保不会调度导致 PDB 限制的 Pod。
    • 静态调度器插件(例如, VolumeScheduling) :调度时会考虑卷的可用性,避免选择那些无法挂载某个特定卷的节点。

步骤 3:绑定 Pod 到节点

一旦 Scheduler 选择了合适的节点,下一步是将该 Pod 绑定到节点。这个操作实际上是修改 API 服务器中的 Pod 状态,将 Pod 的 nodeName 字段更新为选中的节点名称。

  • Pod Binding:这是调度的最后一步,Scheduler 更新 Pod 资源对象的 nodeName 字段。
  • 更新 API 服务器:Pod 状态会更新为 Scheduled,并指明将该 Pod 调度到的节点。

步骤 4:执行调度

一旦 Pod 被绑定到节点,kubelet 会开始在该节点上执行 Pod 的启动操作,具体步骤如下:

  1. kubelet 启动容器:kubelet 通过容器运行时(如 Docker、containerd 等)启动 Pod 中的容器。
  2. Pod 运行:Pod 在节点上运行,kubelet 会监控容器的状态,并将 Pod 的健康状态报告给 API 服务器。
  3. Pod 健康检查:如果 Pod 配置了探针(liveness、readiness),kubelet 会定期执行探针,确保 Pod 健康。

3. Scheduler 插件体系

Kubernetes Scheduler 是一个高度可扩展的组件,可以通过插件化的方式进行扩展。调度过程中的很多步骤可以通过不同的插件来实现,常见的插件包括:

  • 过滤插件(Filter Plugin) :用于过滤不符合条件的节点。比如,如果节点没有足够的 CPU 或内存资源,Pod 就不能被调度到该节点。
  • 优选插件(Score Plugin) :对节点进行评分,选择最合适的节点。
  • Preemption 插件:当集群资源不足时,Preemption 插件会通过抢占低优先级 Pod 来释放资源供高优先级 Pod 使用。

4. 调度策略

调度器使用不同的策略来优化调度:

  • Round-robin 调度策略:当集群资源分布均匀时,调度器可能使用 round-robin 算法来轮流将 Pod 分配到不同的节点。
  • 资源分配优化:调度器通过均衡集群资源的使用来避免过载,并确保 Pod 调度到合适的节点上,最大限度地提高资源利用率。

5. 总结

Kubernetes Scheduler 是 Kubernetes 中非常重要的组件,负责将 Pod 调度到集群中的合适 Node 上运行。调度过程包括从监听待调度的 Pod、根据节点资源和调度策略选择节点、将 Pod 绑定到节点以及最终通过 kubelet 启动 Pod 的过程。调度器还支持通过插件扩展调度功能,并提供灵活的调度策略来优化集群资源利用。