Taints и tolerations в 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
В общих чертах алгоритм такой:
- Планировщик получает список доступных Node.
- Для каждой Node собираются её taint-ы.
- Pod фильтрует Node, если для какой-то taint нет соответствующей toleration.
- Оставшиеся 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.
Модель зрелости и чеклист внедрения (мини-методология)
- Идентификация целей: зачем нужен taint — резервация, защита, HW-ограничение?
- Пометка целевых Node: document why, кто владелец узла.
- Подготовка Pod-манифестов: добавить соответствующие toleration-ы.
- Тестирование в staging: применять taint, пробовать раскат тестовых Pod-ов.
- Наблюдение: следить за событиями, метриками Node (CPU, RAM, Disk).
- Развертывание в 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-ы утверждены.
Примеры сценариев и тест-кейсы
Сценарий: резервирование production Node. Шаги теста:
- taint nodes prod-node env=production:NoSchedule
- Создать Pod без toleration — он не должен быть запланирован на prod-node
- Создать Pod с toleration env=production:NoSchedule — он должен быть запланирован
Сценарий: временная эвакуация со степенью терпимости. Шаги теста:
- Применить NoExecute к узлу с уже запущенным Pod-ом, у которого ограниченный tolerationSeconds = 120
- Убедиться, что Pod остаётся до 120 секунд, затем эвакуируется
Сценарий: 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)
Шаги:
- Подготовка: уведомить команду, проверить текущее состояние Node.
- Применение taint:
kubectl taint nodes key=value:NoSchedule - Обновление манифестов приложений: добавить tolerations и задеплоить их в контролируемой среде.
- Мониторинг: наблюдать за метриками и логами в течение windows наблюдения (например, 1 час).
- Откат: если проблемы — удалить 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, напишите, и я подготовлю их отдельно.
Похожие материалы
Сменить город для погодной компликации на Apple Watch
Коллекции в Apple Maps: создание и обмен
Мобильный интернет на ноутбуке через эмулятор
Установка шрифтов в Linux: Google, Microsoft и любые другие
Отключить Game DVR в Windows 10