Гид по технологиям

Taints и tolerations в Kubernetes — полное руководство

9 min read Kubernetes Обновлено 15 Dec 2025
Taints и tolerations в Kubernetes — руководство
Taints и tolerations в Kubernetes — руководство

Логотип Kubernetes

Быстрые ссылки

  • Как работает планирование

  • Случаи использования taint

  • Эффекты taint

  • Как taint-ить Node

  • Как добавить tolerations в Pod

  • Правила сопоставления taint и toleration

  • Автоматические taints от Kubernetes

  • Сводка

Что такое taints и tolerations

Taint — это метаинформация на уровне Node, которая «отталкивает» новые Pod-ы, если у тех нет соответствующего toleration. Toleration — это часть Pod-манифеста, которая объявляет, что Pod может терпеть (tolerate) определённый taint и, значит, потенциально быть запланирован на такой узел.

Короткое определение терминов:

  • Taint: пометка на Node (ключ, значение и эффект). Она не заставляет Pods уезжать сама по себе (зависит от эффекта), но мешает новым.
  • Toleration: строка в spec.tolerations Pod-манифеста, говорящая, какие taint-ы Pod допускает.

Важно: toleration не гарантирует отправку Pod на конкретный Node — она только снимает «запрет». Чтобы заставить Pod предпочитать или попадать на нужный узел, комбинируйте tolerations с affinity/anti-affinity и nodeSelector/nodeAffinity.

Как работает планирование

Когда создаётся Pod, контроллер планирования (kube-scheduler) выбирает Node по набору критериев: ресурсы (CPU, RAM), ограничения (taints), affinity и другие правила. Процесс можно представить как фильтрацию кандидатов по исключающим условиям (включая taints), затем ранжирование оставшихся по предпочтениям.

Простой mental model: сначала «кто запрещает» (taints фильтруют кандидатов), затем «кого мы предпочитаем» (affinity и scoring).

Случаи использования taint

Taints полезны в ситуациях:

  • Разграничение сред (staging vs production): пометить production-нод как резерв и допустить на них только production Pod-ы.
  • Специальное оборудование: GPU-нод следует taint-ить, чтобы на них не попадали обычные Pod-ы без необходимости.
  • Временная переподготовка узла: при изменении роли узла можно применить NoExecute, чтобы выселить неподходящие Pod-ы.
  • Защита от ресурсного истощения: kubelet/control plane может автоматически ставить taint при давлении по памяти/диску.

Когда использовать taint: когда нужно активно ограничить прием новых Pod-ов на уровне Node. В сочетании с affinity даёт более строгий контроль.

Эффекты taint

У taint есть три эффекта, влияющие на планировщик и поведение уже запущенных Pod-ов:

  • NoSchedule — Pod-ы без соответствующей toleration не будут запланированы на узел. Уже запущенные Pod-ы не трогаются.
  • PreferNoSchedule — планировщик попытается избегать таких узлов, но может использовать их как запасной вариант. Не влияет на существующие Pod-ы.
  • NoExecute — влияет и на новые, и на существующие Pod-ы: Pod-ы без toleration будут немедленно эвакуированы (evicted) с узла.

Краткая подсказка: NoSchedule — запрет новых, NoExecute — запрет новых и текущих, PreferNoSchedule — только рекомендация.

Как taint-ить Node

Taints применяются через kubectl taint. Примеры:

# taint с ключом env и значением production, эффект NoSchedule
kubectl taint nodes demo-node env=production:NoSchedule

Ожидаемый ответ:

node/demo-node tainted

Двоичный taint (без значения):

kubectl taint nodes demo-node has-gpu:NoSchedule

Удаление taint-а — добавьте дефис к эффекту:

kubectl taint nodes demo-node has-gpu:NoSchedule-

Ожидаемый ответ:

node/demo-node untainted

Посмотреть текущие taint-ы Node можно через describe:

kubectl describe node demo-node

В выводе будет строка Taints: env=production:NoSchedule

Советы по практическому использованию:

  • Всегда комментируйте в версии контроля (например, в Git) причины taint-а и кому он нужен.
  • Проводите taint/untaint в maintenance-периоды с оповещением команды.

Добавление tolerations в Pod

Tolerations записываются в поле spec.tolerations Pod-манифеста. Пример корректного Pod-манифеста с toleration (валидный YAML):

apiVersion: v1
kind: Pod
metadata:
  name: api
spec:
  containers:
  - name: api
    image: example.com/api:latest
  tolerations:
  - key: "env"
    operator: "Equal"
    value: "production"
    effect: "NoSchedule"

Если taint был без значения (Exists), используйте оператор Exists:

apiVersion: v1
kind: Pod
metadata:
  name: api-gpu-aware
spec:
  containers:
  - name: api
    image: example.com/api:latest
  tolerations:
  - key: "has-gpu"
    operator: "Exists"
    effect: "NoSchedule"

Пояснение полей:

  • key — имя taint-а на Node.
  • operator — “Equal” или “Exists”.
  • value — значение (требуется при Equal).
  • effect — NoSchedule | PreferNoSchedule | NoExecute.
  • tolerationSeconds (только для NoExecute) — сколько секунд Pod может остаться после применения taint.

Важно: toleration не означает автоматическое размещение на нужном узле. Она лишь убирает запрет. Чтобы привязать Pod к конкретным узлам, используйте nodeSelector, nodeAffinity или PodAffinity.

Правила сопоставления taint и toleration

В общих чертах алгоритм такой:

  1. Планировщик получает список доступных Node.
  2. Для каждой Node собираются её taint-ы.
  3. Pod фильтрует Node, если для какой-то taint нет соответствующей toleration.
  4. Оставшиеся taint-ы (непокрытые toleration) применяют свои эффекты к решению о планировании.

Особенность NoExecute: tolerationSeconds даёт возможность «пожить ещё N секунд» — Pod может оставаться после применения NoExecute в течение указанного времени, затем будет эвакуирован.

Пример toleration с задержкой эвакуации:

apiVersion: v1
kind: Pod
metadata:
  name: api
spec:
  containers:
  - name: api
    image: example.com/api:latest
  tolerations:
  - key: "env"
    operator: "Equal"
    value: "production"
    effect: "NoExecute"
    tolerationSeconds: 900

В этом примере Pod останется на Node до 900 секунд (15 минут) после применения taint env=production:NoExecute, затем будет эвакуирован.

Автоматические taints от Kubernetes

Kubernetes и kubelet автоматически ставят taint-ы в определённых ситуациях, например при давлении по памяти или диску. Общие системные taint-ы:

  • node.kubernetes.io/memory-pressure
  • node.kubernetes.io/disk-pressure
  • node.kubernetes.io/not-ready
  • node.kubernetes.io/unreachable
  • node.kubernetes.io/unschedulable

Эти taint-ы помогают системе эвакуировать Pod-ы и предотвратить дальнейшее назначение на проблемные Node-ы. Обычно с ними не нужно вмешиваться вручную — создание toleration для таких taint-ов может привести к нежелательным последствиям (ресурсное истощение).

Совет: если вы всё же добавляете toleration для системного taint-а, делайте это только для специализированных компонентов, где вы понимаете риски.

Когда taints и tolerations не работают как ожидалось

Распространённые ошибки и причины неожиданных результатов:

  • Неправильный оператор (использовали Equal вместо Exists или наоборот).
  • Опечатка в ключе или значении — точное совпадение обязательно.
  • Ожидали, что toleration принудительно поместит Pod на Node (но toleration лишь снимает запрет).
  • Конфликт с nodeAffinity/nodeSelector или другими контроллерами (например, scheduler extender).
  • Наличие PreferNoSchedule даёт только рекомендацию; планировщик может всё равно назначить Pod.
  • Создан toleration для системного taint-а и в итоге Pod потребляет всю память/диск — будьте осторожны.

Проверка проблем:

  • kubectl describe node — посмотреть taint-ы.
  • kubectl describe pod — посмотреть события и причины, почему Pod не запланирован.
  • kubectl get events –all-namespaces — системные события.

Альтернативные подходы и когда использовать другие механизмы

Taints хорошо решают задачу «запретить размещение», но есть альтернативы:

  • nodeSelector — простой ключ/значение для жёсткой привязки к Node по label.
  • nodeAffinity — более гибкая привязка (preferred/required), даёт приоритеты.
  • PodAffinity / PodAntiAffinity — привязка на основе соседних Pod-ов на узле.
  • ResourceQuota и LimitRange — для ограничения потребления ресурсов на уровне namespace.

Когда выбирать:

  • Для строгого запрета на Node используйте taints + tolerations.
  • Для «хочу, но не обязательно» — nodeAffinity preferred или PreferNoSchedule.
  • Для ограничения по типу ресурса (например, GPU) — taint + toleration совместно с nodeSelector на label GPU.

Модель зрелости и чеклист внедрения (мини-методология)

  1. Идентификация целей: зачем нужен taint — резервация, защита, HW-ограничение?
  2. Пометка целевых Node: document why, кто владелец узла.
  3. Подготовка Pod-манифестов: добавить соответствующие toleration-ы.
  4. Тестирование в staging: применять taint, пробовать раскат тестовых Pod-ов.
  5. Наблюдение: следить за событиями, метриками Node (CPU, RAM, Disk).
  6. Развертывание в production: оповещение, план отката.

Мини-чеклист ролей:

  • DevOps/Platform team:
    • Добавляет taint на Node и документирует причины.
    • Настраивает мониторинг и оповещения.
  • Разработчики/Owners приложений:
    • Добавляют tolerations в Pod-манифесты (только для контролируемых рабочек).
    • Тестируют поведение при применении taint.
  • QA/Release manager:
    • Подтверждает, что staging не затронут production-ресурсами.

Критерии приёмки

  • Подготовленные Pod-ы с toleration-ами успешно планируются на tainted Nodes.
  • Staging Pod-ы без toleration-ов не попадают на production Node.
  • Мониторинг фиксирует ожидаемое поведение (нет неожиданных OOMKill, нет дефицита диска).
  • Документация и owner-ы утверждены.

Примеры сценариев и тест-кейсы

  1. Сценарий: резервирование production Node. Шаги теста:

    • taint nodes prod-node env=production:NoSchedule
    • Создать Pod без toleration — он не должен быть запланирован на prod-node
    • Создать Pod с toleration env=production:NoSchedule — он должен быть запланирован
  2. Сценарий: временная эвакуация со степенью терпимости. Шаги теста:

    • Применить NoExecute к узлу с уже запущенным Pod-ом, у которого ограниченный tolerationSeconds = 120
    • Убедиться, что Pod остаётся до 120 секунд, затем эвакуируется
  3. Сценарий: GPU-узлы защищены от обычных Pod-ов. Шаги теста:

    • taint nodes gpu-node has-gpu:NoSchedule
    • Обычный Pod без toleration не должен попасть на gpu-node
    • Pod с Exists toleration допускается

Безопасность, риски и рекомендации

  • Не создавайте toleration-ы для системных taint-ов без явной причины.
  • Внимательно тестируйте Pod-ы с toleration-ами на предмет потребления ресурсов.
  • Мониторьте метрики Node и ставьте алерты на узлы с pressure taint-ами.
  • Ограничьте права на изменение taint-ов — это административная операция.

Совместимость и миграция

  • Taints/tolerations поддерживаются во всех современных версиях Kubernetes (1.x и выше). При миграции кластера проверяйте:
    • наличие кастомных scheduler extender-ов, которые могут влиять на поведение.
    • контролируемые taint-ы в инфраструктурных автоматизациях (terraform, ansible).

Миграция шаги:

  • Выявить все taint-ы в текущем кластере: kubectl get nodes -o json | jq ‘.items[].spec.taints’
  • Обновить манифесты приложений: добавить toleration-ы там, где это необходимо.
  • Запустить canary-развёртывание и мониторинг.

Частые ошибки и как их исправить

  • Pod «Pending» после добавления toleration: проверьте nodeSelector/affinity и ресурсы.
  • Тaint не применяется: убедитесь, что у вас есть права RBAC для taint/untaint Node.
  • Подозрение на неправильное поведение scheduler-а: проверьте конфигурацию kube-scheduler и расширения.

Пример playbook для операций (SOP)

Шаги:

  1. Подготовка: уведомить команду, проверить текущее состояние Node.
  2. Применение taint:
kubectl taint nodes  key=value:NoSchedule
  1. Обновление манифестов приложений: добавить tolerations и задеплоить их в контролируемой среде.
  2. Мониторинг: наблюдать за метриками и логами в течение windows наблюдения (например, 1 час).
  3. Откат: если проблемы — удалить taint:
kubectl taint nodes  key=value:NoSchedule-

Короткая галерея пограничных случаев

  • Taint с PreferNoSchedule на маленьком кластере: планировщик может игнорировать предпочтение и назначить Pod-ы на такой узел.
  • TolerationExists с NoExecute и без tolerationSeconds: Pod будет оставлен и не эвакуирован, если у него есть допуск; чтобы заставить эвакуацию, нужно явно указать tolerationSeconds.
  • Несовпадающие регистры в ключах/значениях: совпадение строк чувствительно к регистру — будьте внимательны.

One-line glossary

  • Taint: метка на Node, ограничивающая назначение Pod-ов.
  • Toleration: декларация в Pod, разрешающая терпеть конкретный taint.
  • NoSchedule / PreferNoSchedule / NoExecute: базовые эффекты поведения.

Краткая сводка

Taints и tolerations — мощный инструмент для управления размещением Pod-ов на Node-ах. Они полезны для резервирования узлов, разграничения ресурсов и управления сложными сценариями размещения. Помните, что toleration снимает запрет, но не заставляет Pod быть размещённым; комбинируйте с affinity и nodeSelector для полного контроля.

Важное: всегда тестируйте изменения в staging, документируйте причины taint-ов и контролируйте доступ к их изменению.


Если нужна выдержка для соцсетей или short announcement, напишите, и я подготовлю их отдельно.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Сменить город для погодной компликации на Apple Watch
Инструкции

Сменить город для погодной компликации на Apple Watch

Коллекции в Apple Maps: создание и обмен
Руководство

Коллекции в Apple Maps: создание и обмен

Мобильный интернет на ноутбуке через эмулятор
Инструкции

Мобильный интернет на ноутбуке через эмулятор

Установка шрифтов в Linux: Google, Microsoft и любые другие
Linux

Установка шрифтов в Linux: Google, Microsoft и любые другие

Отключить Game DVR в Windows 10
Windows

Отключить Game DVR в Windows 10

Настройка Alt + Tab в Windows 10
Windows

Настройка Alt + Tab в Windows 10