乐闻世界logo
搜索文章和话题

Kubernetes 亲和性(Affinity)和反亲和性(Anti-Affinity)是什么?如何使用它们控制 Pod 调度?

2月21日 15:53

Kubernetes 亲和性(Affinity)和反亲和性(Anti-Affinity)是用于控制 Pod 调度的机制,它们允许用户定义 Pod 与节点或其他 Pod 之间的关系,从而影响调度决策。

亲和性类型

1. 节点亲和性(Node Affinity)

节点亲和性用于控制 Pod 调度到哪些节点上。

requiredDuringSchedulingIgnoredDuringExecution

硬性要求,Pod 必须调度到满足条件的节点上,否则调度失败。

yaml
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/e2e-az-name operator: In values: - us-west-1a containers: - name: my-container image: nginx

preferredDuringSchedulingIgnoredDuringExecution

软性偏好,调度器优先选择满足条件的节点,但如果没有满足条件的节点,也可以调度到其他节点。

yaml
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disktype operator: In values: - ssd containers: - name: my-container image: nginx

2. Pod 亲和性(Pod Affinity)

Pod 亲和性用于控制 Pod 调度到哪些节点上,基于已经运行在该节点上的 Pod。

requiredDuringSchedulingIgnoredDuringExecution

yaml
apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: topology.kubernetes.io/zone containers: - name: my-container image: nginx

preferredDuringSchedulingIgnoredDuringExecution

yaml
apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: topology.kubernetes.io/zone containers: - name: my-container image: nginx

3. Pod 反亲和性(Pod Anti-Affinity)

Pod 反亲和性用于控制 Pod 不调度到哪些节点上,基于已经运行在该节点上的 Pod。

requiredDuringSchedulingIgnoredDuringExecution

yaml
apiVersion: v1 kind: Pod metadata: name: with-pod-antiaffinity spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - web topologyKey: kubernetes.io/hostname containers: - name: my-container image: nginx

preferredDuringSchedulingIgnoredDuringExecution

yaml
apiVersion: v1 kind: Pod metadata: name: with-pod-antiaffinity spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - web topologyKey: kubernetes.io/hostname containers: - name: my-container image: nginx

操作符类型

  1. In:标签的值在给定的列表中

  2. NotIn:标签的值不在给定的列表中

  3. Exists:标签存在

  4. DoesNotExist:标签不存在

  5. Gt:标签的值大于给定值(仅适用于数值)

  6. Lt:标签的值小于给定值(仅适用于数值)

拓扑域键(Topology Key)

拓扑域键用于定义节点的分组方式,常见的拓扑域键包括:

  1. kubernetes.io/hostname:按主机名分组

  2. topology.kubernetes.io/zone:按可用区分组

  3. topology.kubernetes.io/region:按区域分组

  4. node.kubernetes.io/instance-type:按实例类型分组

亲和性规则的行为

调度阶段(During Scheduling)

  • required:硬性要求,必须满足
  • preferred:软性偏好,优先满足

执行阶段(During Execution)

  • Ignored:Pod 运行后,如果条件不再满足,不影响已运行的 Pod
  • Required:Pod 运行后,如果条件不再满足,需要驱逐 Pod(目前不支持)

亲和性 vs nodeSelector

特性nodeSelector节点亲和性
复杂度简单复杂
灵活性
支持的操作符等值多种操作符
优先级支持权重

使用场景

节点亲和性使用场景

  1. 硬件要求:将 Pod 调度到具有特定硬件的节点(如 GPU、SSD)

  2. 区域要求:将 Pod 调度到特定区域或可用区

  3. 操作系统要求:将 Pod 调度到运行特定操作系统的节点

Pod 亲和性使用场景

  1. 通信优化:将需要频繁通信的 Pod 调度到同一节点,减少网络延迟

  2. 依赖关系:将依赖的 Pod 调度到同一节点,提高性能

  3. 数据局部性:将 Pod 调度到存储数据的节点附近

Pod 反亲和性使用场景

  1. 高可用性:将相同应用的 Pod 分散到不同节点,避免单点故障

  2. 资源竞争:避免资源密集型 Pod 调度到同一节点

  3. 故障隔离:将不同应用的 Pod 分散到不同节点,减少故障影响范围

最佳实践

  1. 合理使用硬性要求:避免过度使用 required 规则,可能导致调度失败

  2. 设置合理的权重:为 preferred 规则设置合适的权重,影响调度决策

  3. 使用标签和注解:为节点和 Pod 添加有意义的标签,便于使用亲和性规则

  4. 监控调度结果:监控 Pod 的调度情况,确保亲和性规则按预期工作

  5. 结合污点和容忍度:结合使用亲和性和污点/容忍度,实现更精细的调度控制

  6. 避免过度复杂:避免创建过于复杂的亲和性规则,影响调度性能

  7. 测试规则:在非生产环境测试亲和性规则,确保正确性

示例:高可用 Web 应用

yaml
apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - web topologyKey: kubernetes.io/hostname nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: disktype operator: In values: - ssd containers: - name: web image: nginx ports: - containerPort: 80

这个示例确保:

  1. 每个 Web Pod 调度到不同的节点(高可用性)
  2. 优先选择具有 SSD 的节点(性能优化)
标签:Kubernetes