← Назад к вопросам

Что такое Affinity в Kubernetes?

2.0 Middle🔥 222 комментариев
#Kubernetes

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Affinity в Kubernetes?

Affinity (Сходство / Сродство) в Kubernetes — это набор правил, которые позволяют администраторам влиять на планирование (scheduling) подов на узлы (nodes) с большей гибкостью, чем простые селекторы. Это механизм декларативного управления тем, где и с кем должен быть размещен под, учитывая не только метки узлов, но и текущее состояние уже запущенных на них рабочих нагрузок.

Концептуально, Affinity расширяет базовые возможности nodeSelector и taints/tolerations, предлагая более выразительный, "мягкий" (soft) и сложный (multi-rule) язык. Она разделяется на два основных типа:

  • Node Affinity (Сродство с узлами): Определяет, на каких узлах может или должен быть запланирован под. Аналогично nodeSelector, но мощнее.
  • Inter-pod Affinity/Anti-affinity (Сродство / анти-сродство между подами): Определяет, должен ли под быть запланирован на том же узле (или в той же зоне), что и другие поды, обладающие определенными метками, или, наоборот, избегать их.

Ключевые компоненты и операторы

Правила Affinity задаются в спецификации пода (или Deployment, StatefulSet и т.д.) в секции .spec.affinity. Основные строительные блоки:

  1. requiredDuringSchedulingIgnoredDuringExecution (Обязательное правило): Жесткое требование, которое должно быть выполнено для успешного планирования пода. Если подходящего узла нет, под останется в состоянии Pending. Аналог жесткого правила (hard).

    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values:
          - ssd
    
  2. preferredDuringSchedulingIgnoredDuringExecution (Предпочтительное правило): "Мягкое" предпочтение. Планировщик попытается его выполнить, но если не сможет — все равно разместит под где-либо. Имеет вес (weight, от 1 до 100) для расстановки приоритетов между несколькими предпочтениями.

    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 80
      preference:
        matchExpressions:
        - key: zone
          operator: In
          values:
          - zone-a
    
  3. operator (Оператор): Определяет логику сопоставления меток. Основные операторы:

    *   `In`, `NotIn` — значение метки в (или не в) указанном списке.
    *   `Exists`, `DoesNotExist` — метка существует (или не существует) на узле/поде.
    *   `Gt`, `Lt` — значение метки больше или меньше указанного числового значения.

Практические примеры использования

1. Node Affinity: Размещение на узлах с SSD

apiVersion: v1
kind: Pod
metadata:
  name: cache-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: hardware
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 70
        preference:
          matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - eu-west-1a
  containers:
  - name: redis
    image: redis:alpine

Что делает манифест: Под ОБЯЗАТЕЛЬНО будет размещен на узле с меткой hardware=ssd. При этом ПРЕДПОЧТИТЕЛЬНО, чтобы этот узел находился в зоне eu-west-1a.

2. Pod Anti-Affinity: Распределение инстансов приложения для высокой доступности

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-store
  template:
    metadata:
      labels:
        app: web-store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-store
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx:latest

Что делает манифест: Каждый под этого Deployment будет избегать узлов, на которых уже работает под с меткой app=web-store. Ключ topologyKey: kubernetes.io/hostname указывает область привязки — отдельный узел. Это гарантирует, что все 3 реплики будут размещены на трех разных физических узлах, повышая отказоустойчивость.

Анти-сродство (Anti-affinity) и топологические домены

Особенно мощным является использование Pod Anti-affinity с topologyKey. Топологический ключ — это метка узла, которая определяет домен логического или физического уровня:

  • kubernetes.io/hostname — отдельный узел.
  • topology.kubernetes.io/zone — зона доступности в облаке (AZ).
  • topology.kubernetes.io/region — регион.

Это позволяет распределять поды не просто по разным узлам, но и по разным зонам или даже регионам, что критично для построения гео-избыточных и отказоустойчивых приложений.

Важные нюансы

  • Производительность: Сложные правила межподового сродства/анти-сродства (особенно requiredDuringScheduling) требуют от планировщика больше вычислений и могут замедлять планирование в больших кластерах. Их следует использовать обдуманно.
  • "IgnoredDuringExecution": Часть названия означает, что правила учитываются только при планировании. Если метки на узле или подах изменятся после запуска пода, он не будет перезапущен или перемещен автоматически. Для этого нужны другие механизмы (например, descheduler).
  • Сочетание с Taints/Tolerations: Правила Affinity работают вместе с taints. Сначала под должен "перенести" taint узла (иметь matching toleration), и только затем применяются правила Affinity для выбора среди допустимых узлов.

Итог: Affinity — это незаменимый инструмент для реализации сложных требований к размещению workload'ов в Kubernetes. Он позволяет перейти от простого "этот под на этом типе узлов" к стратегиям "эти сервисы должны быть вместе для производительности", а "эти инстансы — максимально далеко друг от друга для надежности", что является краеугольным камнем эффективного управления производственным кластером.