K8s 基础调度原理:如何将 Pod 分配到节点

好嘞,各位观众老爷们,大家好!我是你们的老朋友,程序界的“段子手”——K8s 小能。今天呢,咱们不聊高大上的架构,也不谈深奥的源码,就来聊聊 Kubernetes (简称 K8s) 里最基础,也是最重要的一环——Pod 的调度!

想象一下,K8s 集群就像一个庞大的蜂巢,里面住着成千上万只“蜜蜂” (Pod)。而我们的任务,就是要把这些“蜜蜂”分配到合适的“蜂巢格子” (Node) 里,让它们辛勤工作,酿出美味的“蜂蜜” (应用服务)。

那么问题来了,K8s 是怎么决定把哪个 Pod 分配到哪个 Node 上的呢?难道是随机抓阄,还是靠“猜猜猜”?当然不是!K8s 的调度器可是一位精明的“管家”,它会综合考虑各种因素,做出最合理的安排。

接下来,就让咱们一起深入了解 K8s 的调度原理,看看这位“管家”是如何工作的!

一、调度器:K8s 的“大脑”

首先,我们要认识一下这位“管家”——kube-scheduler。它是 K8s 控制平面 (Control Plane) 的核心组件之一,负责监听 API Server,当发现有新的 Pod 需要调度时,它就会开始“思考”:

  • 这个 Pod 需要什么? (资源需求、亲和性、反亲和性等等)
  • 集群里有哪些 Node 可以满足它的需求? (资源充足、标签匹配等等)
  • 哪个 Node 是最佳选择? (综合考虑资源利用率、节点健康状况等等)

kube-scheduler 的工作流程可以概括为以下几个步骤:

  1. 预选 (Filtering): 筛选出所有满足 Pod 基本需求的 Node。这就像“海选”,先把不合格的选手淘汰掉。
  2. 优选 (Scoring): 对通过预选的 Node 进行打分,根据各种策略 (例如资源利用率、亲和性等) 给出不同的权重。这就像“决赛”,评委们会根据选手的表现打分。
  3. 选择 (Binding): 选择得分最高的 Node,并将 Pod 绑定到该 Node 上。这就像“颁奖”,最终选出冠军!

二、预选 (Filtering):排除“不合适”的节点

预选,顾名思义,就是初步筛选。它会根据 Pod 的一些硬性条件,排除掉那些明显不符合要求的 Node。常见的预选条件包括:

  • PodFitsResources: 检查 Node 的资源 (CPU、内存等) 是否足够满足 Pod 的需求。如果 Node 的资源不够,Pod 肯定无法运行,直接淘汰!
  • PodFitsHostPorts: 检查 Node 上是否已经占用了 Pod 需要的 HostPort。如果端口冲突,Pod 也会运行失败。
  • MatchNodeSelector: 检查 Node 的标签 (Labels) 是否与 Pod 的 nodeSelector 匹配。如果 Pod 指定了特定的 Node 标签,只有拥有这些标签的 Node 才能通过预选。
  • NoExecuteTaints: 检查 Node 是否存在污点 (Taints),以及 Pod 是否有相应的容忍 (Tolerations)。如果 Node 有污点,且 Pod 没有容忍,Pod 就无法调度到该 Node 上。

为了方便理解,咱们用一个表格来总结一下:

预选条件 描述
PodFitsResources 检查 Node 资源是否满足 Pod 需求
PodFitsHostPorts 检查 Node 上是否已占用 Pod 需要的 HostPort
MatchNodeSelector 检查 Node 标签是否与 Pod 的 nodeSelector 匹配
NoExecuteTaints 检查 Node 是否存在污点,以及 Pod 是否有相应的容忍。没有容忍的 Pod 无法调度到有污点的 Node 上。

三、优选 (Scoring):选出“最优秀”的节点

经过预选,我们得到了一批“候选人” (Node)。接下来,就要进行优选,对这些 Node 进行打分,选出“最优秀”的那一个。

优选的策略有很多,每种策略都有自己的权重。K8s 会根据这些策略,综合计算每个 Node 的得分,然后选择得分最高的 Node。

常见的优选策略包括:

  • LeastRequestedPriority: 优先选择资源利用率较低的 Node。这可以避免资源过度集中在少数 Node 上,提高整体的资源利用率。
  • BalancedResourceAllocation: 优先选择 CPU 和内存利用率相对均衡的 Node。这可以避免某些 Node 的 CPU 负载过高,而内存却闲置的情况。
  • NodeAffinityPriority: 根据 Node 的亲和性 (NodeAffinity) 规则,优先选择与 Pod 亲和的 Node。这可以确保相关的 Pod 尽可能地调度到一起,提高性能。
  • TaintTolerationPriority: 优先选择可以容忍 Node 污点的 Node。这可以确保 Pod 可以调度到那些带有污点的 Node 上,例如专门用于运行特定类型应用的 Node。
  • SelectorSpreadPriority: 尽量将属于同一个 Service 或 ReplicationController 的 Pod 分散到不同的 Node 上。这可以提高应用的可用性,避免单点故障。
  • InterPodAffinityPriority: 根据 Pod 间的亲和性(PodAffinity)规则,优先选择与当前Pod亲和的Pod所在的Node。

同样,咱们也用一个表格来总结一下:

优选策略 描述
LeastRequestedPriority 优先选择资源利用率较低的 Node
BalancedResourceAllocation 优先选择 CPU 和内存利用率相对均衡的 Node
NodeAffinityPriority 根据 Node 的亲和性 (NodeAffinity) 规则,优先选择与 Pod 亲和的 Node
TaintTolerationPriority 优先选择可以容忍 Node 污点的 Node
SelectorSpreadPriority 尽量将属于同一个 Service 或 ReplicationController 的 Pod 分散到不同的 Node 上
InterPodAffinityPriority 根据 Pod 间的亲和性(PodAffinity)规则,优先选择与当前Pod亲和的Pod所在的Node。

四、亲和性 (Affinity) 和反亲和性 (Anti-Affinity):让 Pod “抱团” 或 “分散”

亲和性和反亲和性是 K8s 中非常重要的概念,它们可以用来控制 Pod 的调度行为,让 Pod 尽可能地调度到一起 (亲和性) 或分散开来 (反亲和性)。

  • NodeAffinity: 定义 Pod 与 Node 之间的亲和性。例如,我们可以指定 Pod 只能调度到拥有特定标签的 Node 上。
  • PodAffinity: 定义 Pod 与 Pod 之间的亲和性。例如,我们可以指定两个 Pod 必须调度到同一个 Node 上。
  • PodAntiAffinity: 定义 Pod 与 Pod 之间的反亲和性。例如,我们可以指定两个 Pod 不能调度到同一个 Node 上。

亲和性和反亲和性可以用来实现很多高级的调度策略,例如:

  • 提高性能: 将相关的 Pod 调度到一起,减少网络延迟。
  • 提高可用性: 将 Pod 分散到不同的 Node 上,避免单点故障。
  • 实现隔离: 将不同的应用部署到不同的 Node 上,避免互相干扰。

五、污点 (Taints) 和容忍 (Tolerations):给 Node “贴标签”

污点和容忍是 K8s 中另一种重要的调度机制。它们可以用来给 Node “贴标签”,只有拥有相应容忍的 Pod 才能调度到这些 Node 上。

  • Taint: 给 Node 添加一个污点,表示该 Node 不适合运行某些类型的 Pod。
  • Toleration: Pod 声明自己可以容忍某些类型的污点。

污点和容忍可以用来实现一些特殊的调度需求,例如:

  • 专用节点: 给一些 Node 添加污点,只有特定的 Pod 才能调度到这些 Node 上。
  • 节点维护: 给需要维护的 Node 添加污点,阻止新的 Pod 调度到这些 Node 上。

六、自定义调度器 (Custom Scheduler):打造专属的“管家”

K8s 默认的调度器已经足够强大,可以满足大部分的调度需求。但是,在某些特殊的场景下,我们可能需要自定义调度器,以实现更精细的调度控制。

自定义调度器可以完全控制 Pod 的调度过程,可以根据自己的需求,实现各种复杂的调度策略。

例如,我们可以自定义一个调度器,根据 Pod 的优先级、资源需求、业务特性等因素,进行更智能的调度。

七、总结:K8s 调度的“葵花宝典”

好了,各位观众老爷们,今天的 K8s 调度之旅就到这里了。咱们一起了解了 K8s 调度的基本原理,包括预选、优选、亲和性、反亲和性、污点、容忍等概念。

记住,K8s 的调度器就像一位精明的“管家”,它会综合考虑各种因素,做出最合理的安排,让你的应用在集群里跑得飞起!🚀

希望今天的讲解对你有所帮助。如果你还有什么疑问,欢迎在评论区留言,我会尽力解答。咱们下期再见! 👋

最后,送给大家一句 K8s 界的至理名言:

“调度一时爽,一直调度一直爽!” 😎

希望大家在 K8s 的世界里玩得开心,学有所成! 🍻

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注