一、什么是亲和力

亲和力(Affinity)是 Kubernetes 中的一种机制,用于指定 Pod 与其他资源(如节点、Pod 或标签)之间的关联性和偏好。

亲和力定义了 Pod 对其他资源的偏好和互动方式,以便在调度过程中进行合适的匹配。通过使用亲和力规则,可以将 Pod 调度到满足特定条件的节点上,或者将 Pod 与其他相关的 Pod 进行关联,以实现特定的调度需求和业务需求。

nodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:

  • 亲和性、反亲和性语言的表达能力更强。nodeSelector 只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。
  • 你可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时仍然调度该 Pod。
  • 你可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束, 而不是只能使用节点本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。

亲和性功能由两种类型的亲和性组成:

  • 节点亲和性功能类似于 nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。
  • Pod 间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod。

二、亲和力出现背景

我们可以使用Taint让节点不能随便部署Pod,也通过NodeSelector+Toleration实现了将Pod部署到指定的节点上。但是NodeSelector对节点的选择是强制性的,假如配置了NodeSelector为ssd=true,那么如果集群中没有匹配的节点,这个Pod将一直处于Pending状态。而在生产环境中可能会有这样的需求:

  • 某些Pod优先选择有ssd=true标签的节点,如果没有再考虑部署到其他节点。
  • 某些Pod需要部署在ssd=true和type=physical的节点上,但是优先部署在ssd=true的节点上。
  • 同一类应用的Pod尽量不要部署或不允许部署在同一个节点或者符合某个标签的一类节点上。
  • 相互依赖的两个Pod尽量或必须部署在同一个节点上。

诸如此类的需求单单使用NodeSelector、NodeName、Taint和Toleration是无法实现的,所以Kubernetes引用了Affinity(亲和力)的概念,用于满足生产环境中更复杂的需求。

三、亲和力分类

Affinity根据功能的不同分为节点亲和力(Node Affinity)和Pod亲和力(Pod Affinity),每种亲和力还有两种不同的“实现方法”,即必须和尽量,所以亲和力又分为软亲和力(非强制性)和硬亲和力(强制性)。还可以看出Pod之间可以相互排斥,也可以相互吸引,所以Pod亲和力又分为PodAffinity(Pod亲和力)和PodAntiAffinity(Pod反亲和力),每种亲和力均可以使用软亲和力和硬亲和力。

亲和力分类

图中参数说明:

  • Affinity:亲和力
  • Node Affinity:节点亲和力
  • Pod Affinity:Pod亲和力
  • PodAntiAffinity:Pod反亲和力
  • 硬亲和力:requiredDuringSchedulinglgnoredDuringExecution

  • 软亲和力:preferredDuringSchedulinglgnoredDuringExecution