K8S的亲和与反亲和概述

330 阅读3分钟

Kubernetes(K8S)中的 亲和性(Affinity) 和 反亲和性(Anti-Affinity) 是用于控制 Pod 在集群中调度位置的机制。它们允许用户定义规则,指定 Pod 应该(或不应该)运行在哪些节点上,或者与其他 Pod 如何共存。这些规则可以优化资源利用率、提高可用性,或满足其他业务需求。


亲和性(Affinity) 亲和性分为两种类型:节点亲和性(Node Affinity) 和 Pod 亲和性(Pod Affinity)。

  1. 节点亲和性(Node Affinity) 定义 Pod 应该调度到哪些节点上。例如:

• 硬亲和性(Required):必须满足的条件,否则 Pod 无法调度。

• 软亲和性(Preferred):尽量满足的条件,不强制要求。

示例场景: • 将 Pod 调度到带有 gpu=true 标签的节点上。

• 优先选择可用区为 us-east-1a 的节点。

配置示例:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: gpu
          operator: In
          values: ["true"]
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values: ["us-east-1a"]
  1. Pod 亲和性(Pod Affinity) 定义 Pod 应该与其他 Pod 运行在同一拓扑域(如节点、可用区等)。例如: • 将多个服务的 Pod 部署在同一节点,减少网络延迟。

• 确保同一服务的多个副本分散在不同拓扑域(如不同节点或可用区)。

配置示例:

affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values: ["cache"]
      topologyKey: kubernetes.io/hostname

反亲和性(Anti-Affinity) 反亲和性与亲和性相反,用于避免 Pod 调度到特定节点或与某些 Pod 共存。同样分为 节点反亲和性 和 Pod 反亲和性。

  1. Pod 反亲和性(Pod Anti-Affinity) 常见场景: • 避免同一服务的多个副本运行在同一节点(提高可用性)。

• 避免竞争资源的 Pod 共存(如 CPU/内存密集型应用)。

配置示例:

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values: ["web"]
      topologyKey: kubernetes.io/hostname

此规则确保同一节点上不会运行多个标签为 app=web 的 Pod。


关键概念

  1. 拓扑域(Topology Domain): • 由 topologyKey 定义,如 kubernetes.io/hostname(节点)、topology.kubernetes.io/zone(可用区)等。

    • 反亲和性规则作用于同一拓扑域内的 Pod。

  2. 调度阶段: • requiredDuringSchedulingIgnoredDuringExecution:调度时必须满足的条件。

    preferredDuringSchedulingIgnoredDuringExecution:尽量满足的条件(权重由 weight 指定,范围 1-100)。

  3. 操作符(Operator): • InNotInExistsDoesNotExist 等,用于匹配标签条件。


使用场景

  1. 高可用部署: • 通过反亲和性将同一服务的 Pod 分散到不同节点或可用区。

    • 例如:数据库主从副本部署在不同节点。

  2. 性能优化: • 通过亲和性将计算密集型 Pod 调度到 GPU 节点。

    • 将紧密通信的微服务部署在同一可用区,减少延迟。

  3. 资源隔离: • 通过反亲和性避免资源竞争的 Pod 共存(如内存密集型应用)。


注意事项 • 资源消耗:Pod 亲和性/反亲和性会增加调度器计算复杂度,可能影响调度性能(尤其是大规模集群)。

• 拓扑域限制:反亲和性规则必须合理设置 topologyKey,否则可能导致 Pod 无法调度(例如集群节点不足时)。

• 与 Taint/Toleration 结合:亲和性规则通常与节点污点(Taint)和容忍(Toleration)配合使用,实现更细粒度的调度。


通过合理使用亲和性与反亲和性,可以显著提升 Kubernetes 集群的稳定性、性能和资源利用率。根据具体业务需求选择硬性规则或柔性建议,结合监控和测试调整策略。