Taints, Tolerations и Affinity

Обзор

Управление планированием подов на узлы в Kubernetes включает:

  • Taints и Tolerations — ограничение, какие поды могут планироваться на какие узлы (выделение узлов под GPU, Ingress, БД);
  • Node Affinity — предпочтение узлов по лейблам;
  • Pod Affinity / Anti-Affinity — размещение подов рядом с другими подами или рассредоточение по узлам.

Taint — «метка» на узле, запрещающая планирование подов без Toleration.
Toleration — «разрешение» в поде планироваться на узлы с указанным Taint.


Управление Taints в GUI

Добавление Taint на узел

  1. АдминистрированиеУправление узлами → клик по нужному узлу.
  2. На странице узла перейдите на вкладку Taints.
  3. Нажмите +.
  4. Задайте Ключ (key) и при необходимости Значение (value).
  5. Выберите Эффект: NoSchedule, PreferNoSchedule или NoExecute.
  6. Нажмите Добавить.
  7. Нажмите Сохранить.
Скриншот: страница узла, вкладка Taints

Taints на узле

Скриншот: добавление Taint

Добавление Taint

Скриншот: список Taints

Список Taints

Удаление Taint

На вкладке Taints удалите нужный Taint (значок корзины) и нажмите Сохранить.


Управление Tolerations в GUI

Tolerations задаются в шаблоне пода при создании или редактировании нагрузки (Deployment, StatefulSet, DaemonSet, Pod и др.).

  1. Выберите неймспейс → Нагрузки → нужный тип (Deployment и т.д.) → Добавить или откройте существующую нагрузку для редактирования.
  2. В блоке Шаблон пода найдите Tolerations.
  3. Нажмите +.
  4. Задайте Ключ и при необходимости Значение taint, которому должен соответствовать Toleration.
  5. Выберите Оператор: Exists (по ключу) или Equal (ключ и значение).
  6. Выберите Эффект: NoSchedule, PreferNoSchedule, NoExecute или Любой.
  7. Для NoExecute при необходимости укажите Toleration Seconds — время в секундах до вытеснения пода с узла (по умолчанию 300).
  8. Сохраните нагрузку.
Скриншот: добавление Toleration при создании

Toleration при создании Toleration при создании

Скриншот: добавление Toleration в существующий Deployment

Toleration в Deployment Добавление Toleration

При создании любого вида нагрузки (Deployment, StatefulSet, DaemonSet, Job, CronJob, Pod) есть возможность добавить Tolerations.


Taints: параметры и эффекты

На один узел можно добавить несколько Taints. Для размещения пода на таком узле нужны Tolerations для каждого Taint.

Параметры Taint:

  • Ключ (key) и Значение (value) — пара для идентификации ограничения.
  • Эффект (effect) — правило применения.
Эффект Описание
NoSchedule Новые поды не планируются на узел. Существующие поды не затрагиваются.
PreferNoSchedule Предпочтительно не планировать, но возможны исключения при нехватке ресурсов.
NoExecute Новые поды не планируются. Существующие поды без Toleration выселяются (с учётом tolerationSeconds, по умолчанию 5 мин).

Автоматические Taints

Kubernetes автоматически добавляет Taints при определённых условиях:

Taint Описание Эффект
node.kubernetes.io/not-ready Узел не готов (Ready=False) NoExecute
node.kubernetes.io/unreachable Узел недоступен (Ready=Unknown) NoExecute
node.kubernetes.io/memory-pressure Нехватка памяти NoSchedule
node.kubernetes.io/disk-pressure Нехватка диска NoSchedule
node.kubernetes.io/pid-pressure Лимит процессов (PID) NoSchedule
node.kubernetes.io/network-unavailable Сеть недоступна NoSchedule
node.kubernetes.io/unschedulable Узел не подлежит планированию NoSchedule

Несколько Taints на узле

  • Если у пода есть Tolerations ко всем Taints, кроме NoSchedule — под не будет запланирован.
  • Если нет Toleration только для PreferNoSchedule — под может быть размещён.
  • Если нет Toleration для NoExecute — под будет вытеснен (если уже запущен) и не будет запланирован.

Примеры: Taints и Tolerations

Добавление Taint через kubectl

# Узел только для GPU-нагрузок
kubectl taint nodes node-1 gpu=true:NoSchedule

# Узел только для Ingress
kubectl taint nodes node-2 node-role.kubernetes.io/ingress:NoSchedule

# Удаление Taint
kubectl taint nodes node-1 gpu=true:NoSchedule-

Toleration в Pod / Deployment

tolerations:
- key: "gpu"
  operator: "Equal"
  value: "true"
  effect: "NoSchedule"

Toleration для любого Taint с ключом (Exists)

tolerations:
- key: "gpu"
  operator: "Exists"
  effect: "NoSchedule"

Toleration для NoExecute с задержкой выселения

tolerations:
- key: "node.kubernetes.io/not-ready"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 300

Полный пример: Deployment для Ingress

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-controller
  namespace: ingress
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ingress
  template:
    metadata:
      labels:
        app: ingress
    spec:
      tolerations:
      - key: "node-role.kubernetes.io/ingress"
        operator: "Exists"
        effect: "NoSchedule"
      containers:
      - name: nginx
        image: nginx:latest

Node Affinity

Node Affinity — правила планирования подов на узлы по лейблам узлов. Работает «на притяжение»: под предпочитает или требует узлы с определёнными лейблами.

Типы Node Affinity

Тип Описание
requiredDuringSchedulingIgnoredDuringExecution Обязательное правило. Под будет запланирован только на подходящий узел.
preferredDuringSchedulingIgnoredDuringExecution Предпочтительное правило. Scheduler старается разместить на подходящем узле, но может выбрать другой.

Пример: обязательное размещение на GPU-узлах

apiVersion: v1
kind: Pod
metadata:
  name: gpu-app
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: gpu
            operator: In
            values:
            - "true"
  containers:
  - name: app
    image: my-gpu-app:latest

Пример: предпочтение узлов с большей памятью

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      preference:
        matchExpressions:
        - key: node.kubernetes.io/instance-type
          operator: In
          values:
          - high-memory

Операторы в matchExpressions

Оператор Описание
In Лейбл узла в списке values
NotIn Лейбл узла не в списке values
Exists Ключ лейбла существует (values не нужен)
DoesNotExist Ключ лейбла не существует
Gt, Lt Для числовых значений (например, CPU)

Pod Affinity

Pod Affinity — под планируется рядом с подами, соответствующими селектору (в той же зоне, на том же узле и т.д.).

Пример: разместить под рядом с cache

affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: redis-cache
      topologyKey: kubernetes.io/hostname  # на том же узле

topologyKey

  • kubernetes.io/hostname — на том же узле;
  • topology.kubernetes.io/zone — в той же зоне доступности;
  • topology.kubernetes.io/region — в том же регионе.

Pod Anti-Affinity

Pod Anti-Affinity — поды рассредоточиваются (не на одном узле, не в одной зоне). Используется для отказоустойчивости.

Пример: реплики на разных узлах

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: my-app
            topologyKey: kubernetes.io/hostname
      containers:
      - name: app
        image: my-app:latest

Поды с app: my-app не будут на одном узле.

Пример: предпочтительное рассредоточение (soft)

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: my-app
        topologyKey: kubernetes.io/hostname

Scheduler постарается разместить поды на разных узлах, но не гарантирует.

Пример: рассредоточение по зонам

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: my-app
      topologyKey: topology.kubernetes.io/zone

Реплики будут в разных зонах доступности.


Сравнение: когда что использовать

Задача Инструмент
Выделить узлы под конкретную нагрузку (GPU, Ingress) Taints + Tolerations
Предпочитать узлы с определёнными лейблами Node Affinity (preferred)
Требовать узлы с лейблами Node Affinity (required) или nodeSelector
Разместить поды на разных узлах Pod Anti-Affinity
Разместить поды рядом (на одном узле) Pod Affinity
Разместить поды в разных зонах Pod Anti-Affinity с topologyKey: zone

Связь с группами узлов

В платформе «Штурвал» группы узлов (Worker Groups) могут иметь Taints при создании кластера. Узлы с Taint используются для изоляции нагрузок (например, группа «infra» для Ingress и мониторинга). Подробнее — Группы узлов.

Управление Taints на странице узла — Страница узла, вкладка «Taints».