Что такое Affinity и Anti-Affinity в Kubernetes?

«Что такое Affinity и Anti-Affinity в Kubernetes?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Affinity и Anti-Affinity в Kubernetes — это набор правил, которые позволяют тонко управлять тем, на каких узлах (Node) будут размещены Pod'ы, учитывая их взаимное расположение.

Основные типы:

  • Node Affinity: Позволяет привязать Pod к узлам с определенными характеристиками (метками). Это эволюция простого nodeSelector, но с более гибкими операторами (In, NotIn, Exists, DoesNotExist, Gt, Lt).

    • requiredDuringSchedulingIgnoredDuringExecution: Жесткое правило. Пода будет размещен только на узле, соответствующем условию.
    • preferredDuringSchedulingIgnoredDuringExecution: Предпочтение. Планировщик попытается выполнить правило, но если не сможет — разместит Pod где есть место.
  • Pod Affinity / Anti-Affinity: Позволяет управлять совместным или раздельным размещением Pod'ов относительно друг друга, основываясь на их метках и пространстве домена (topologyKey, например, kubernetes.io/hostname, topology.kubernetes.io/zone).

    • Pod Affinity: "Размести этот Pod рядом с Pod'ами, имеющими такие-то метки". Полезно для снижения задержки между микросервисами.
    • Pod Anti-Affinity: "Размести этот Pod подальше от Pod'ов с такими-то метками". Критически важно для обеспечения отказоустойчивости, чтобы реплики одного приложения не оказались на одном физическом узле или в одной зоне доступности (AZ).

Пример Node Affinity для размещения на узлах с GPU:

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: accelerator
            operator: In
            values:
            - nvidia-tesla-p100

Пример Pod Anti-Affinity для распределения реплик по разным узлам:

spec:
  replicas: 3
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - my-web-app
            topologyKey: kubernetes.io/hostname # Разные физические узлы