Новые поды не размещаются на узле Kubernetes, хотя ресурсов достаточно. Как механизм пометки узла отфильтро...

Новые поды не размещаются на узле Kubernetes, хотя ресурсов достаточно. Как механизм пометки узла отфильтровывает этот узел?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Taint отсекает поды, у которых нет соответствующего toleration. Планировщик не размещает такой под на узле с эффектом NoSchedule, даже если на узле достаточно CPU и памяти. При этом toleration лишь разрешает размещение, но сама по себе не заставляет планировщик выбрать этот узел.

Исторический контекст

В кластере часто есть узлы с особыми свойствами: GPU, локальными дисками, повышенными требованиями безопасности или ограниченной надёжностью. Одних меток узла недостаточно, потому что метки позволяют поду выбрать подходящий узел, но не запрещают другим подам попасть туда.

Механизм taints and tolerations появился как форма отрицательного ограничения: узел объявляет, какие поды он не принимает, а под явно подтверждает совместимость через toleration. Это помогает отделить специализированные узлы и управлять вытеснением подов.

Постановка проблемы

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

Обратная ошибка тоже опасна: слишком широкая toleration разрешает подам размещаться на узлах, для которых они не предназначены. Тогда taint перестаёт быть эффективной границей, хотя внешне конфигурация выглядит корректной.

Подробное решение

Узел получает taint, состоящий из ключа, необязательного значения и эффекта. Планировщик проверяет все taints узла и tolerations пода. Если хотя бы один taint не покрыт toleration, под не считается допустимым кандидатом для этого узла.

Основные эффекты различаются по последствиям:

  • NoSchedule запрещает размещение новых подов без подходящей toleration, но сам по себе не удаляет уже работающие поды.
  • PreferNoSchedule задаёт мягкое предпочтение: планировщик старается не использовать узел, но может сделать это при отсутствии лучших вариантов.
  • NoExecute запрещает новые поды и может удалить уже работающие поды, если у них нет toleration с подходящей длительностью действия.

Toleration сопоставляется с taint по ключу, эффекту и, в зависимости от оператора, значению. Оператор Equal требует совпадения значения, а Exists допускает любое значение для указанного ключа. Toleration с отсутствующим эффектом может соответствовать taint с любым эффектом того же ключа, поэтому такие разрешения нужно задавать осторожно.

Важно различать допустимость и предпочтение. Taint с toleration делает узел допустимым для пода, но не выбирает его; для привлечения подов обычно дополнительно используют nodeSelector, nodeAffinity или другие правила размещения.

При NoExecute toleration может иметь tolerationSeconds. В этом случае под получает временное разрешение оставаться на узле после появления taint, например во время кратковременной деградации узла. Если время истекло, контроллер удаляет под, а затем он может быть создан заново на другом подходящем узле.

Минимальный пример механизма:

spec: tolerations: - key: workload operator: Equal value: batch effect: NoSchedule

Этот фрагмент разрешает поду находиться на узле с taint workload=batch:NoSchedule. Он не гарантирует размещение именно на таком узле и не покрывает taint с другим ключом, значением или эффектом.

Ситуация из практики

В кластере выделили узлы с локальными SSD для пакетных задач. После установки taint обычные сервисы перестали туда попадать, но пакетные поды тоже начали оставаться в общей очереди: у них не было toleration.

Рассматривались два варианта. Полностью убрать taint было проще, но это возвращало риск конкуренции за локальные диски. Добавить широкую toleration для всех подов решало проблему запуска, но разрушало изоляцию. Выбранный вариант — точечная toleration с ключом, значением и эффектом NoSchedule, дополненная node affinity для явного предпочтения SSD-узлов.

В результате только пакетные поды получили доступ к специализированным узлам, а остальные нагрузки продолжили планироваться в общем пуле. При этом affinity обеспечила не просто разрешение, а ожидаемое направление размещения.

Что кандидаты часто упускают

1. Вопрос: Достаточно ли toleration, чтобы под гарантированно оказался на узле с соответствующим taint?

Ответ: Нет. Toleration только снимает запрет, создаваемый taint. После этого узел конкурирует с другими допустимыми узлами по ресурсам, affinity, topology-ограничениям и другим фильтрам планировщика. Чтобы направить под на нужный класс узлов, применяют toleration вместе с label и node affinity.

2. Вопрос: Чем NoSchedule отличается от NoExecute для уже работающего пода?

Ответ: NoSchedule влияет прежде всего на новые решения планировщика и не требует немедленного удаления уже работающих подов. NoExecute дополнительно определяет, может ли существующий под оставаться на узле. Без подходящей toleration такой под будет вытеснен; при наличии tolerationSeconds он останется только на заданный срок.

3. Вопрос: Что произойдёт, если на узле есть несколько taints, а под покрывает toleration только одного из них?

Ответ: Под всё равно не будет допущен к узлу, если оставшийся taint несовместим с его tolerations. Ограничения применяются совместно: каждый непокрытый taint продолжает исключать узел для NoSchedule или влияет на пребывание пода при NoExecute. Поэтому при диагностике нужно проверять весь набор taints, а не только тот, который первым появился в описании узла.