Что такое Taints и Tolerations?

Что такое taints и tolerations (в общих чертах)

Taints — метки/марки на нодах, которые «отталкивают» Pod’ы от размещения на этих нодах. Tolerations — декларация в Pod’е, которая позволяет этому Pod'у игнорировать (то есть «терпеть») соответствующий taint и быть запланированным/оставаться на ноде. Вместе они дают обратимый механизм: ноды говорят «не принимай такие Pod’ы», а Pod’ы говорят «я могу сидеть на такой ноде».

Формат и эффекты taint

Taint имеет форму key=value:effect, где effect — один из трёх:

  • NoSchedule — новые Pod’ы, которые не имеют соответствующей toleration, не будут запланированы на эту ноду. Уже работающие Pod’ы не эвакуируются из-за данного taint.

  • PreferNoSchedule — кластер постарается избежать размещения неподходящих Pod’ов на ноде, но не гарантирует этого (мягкое приглашение).

  • NoExecute — блокирует и новые, и существующие Pod’ы без toleration: новые Pod’ы не будут запланированы, существующие — будут эвакуированы (если toleration не позволяет оставаться).

Как задаётся taint (пример команды)

kubectl taint nodes node1 dedicated=group1:NoSchedule
\# убрать taint
kubectl taint nodes node1 dedicated:NoSchedule-

Поле toleration в Pod: структура и логика сопоставления

Toleration имеет поля: key, operator (Equal или Exists), value, effect, tolerationSeconds. Правила сопоставления:

  • operator: Exists — матч по ключу (значение игнорируется).

  • operator: Equal — ключ и значение должны совпасть. Если operator не указан, по умолчанию считается Equal (если указано значение).

  • effect в toleration (опционально): если указан — должна совпадать и effect; если не указан — toleration будет соответствовать taint с любым effect (при совпадении key/value/operator).

  • tolerationSeconds применим только к NoExecute и определяет, сколько секунд Pod может терпеть taint; по истечении — Pod будет эвакуирован.

Примеры в манифесте Pod:

spec:
tolerations:
\- key: "dedicated"
operator: "Equal"
value: "group1"
effect: "NoSchedule"
\- key: "example"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 3600

Поведение при добавлении/удалении taint

  • Если на ноде появился NoSchedule taint — новые неподходящие Pod’ы не попадут на ноду. Существующие не тронут.

  • Если появился NoExecute taint — неподдерживающие Pod’ы будут удалены (evicted) немедленно, либо после tolerationSeconds, если у Pod’а оно задано.

  • PreferNoSchedule — попытка не назначать, но не жёсткое правило.

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

  • Изолировать ноды для специальных рабочих нагрузок (GPU, latency-sensitive, billing-sensitive): пометить ноды taint’ом dedicated=gpu:NoSchedule, а нужные Pod’ы снабдить toleration + nodeSelector/nodeAffinity.

  • Защитить контроль-плейн: мастер-нодам часто ставят taint node-role.kubernetes.io/control-plane:NoSchedule, чтобы на них не попадали обычные Pod’ы.

  • Маркировать спотовые/прерываемые ноды (taint spot=true:PreferNoSchedule или NoExecute) и разрешать на них только устойчивым/временнЫм Pod’ам.

  • Выполнять maintenance: временно добавить node.kubernetes.io/unreachable:NoExecute/пользовательский taint для эвакуации Pod’ов.

Важные замечания и best practices

  • Taints отталкивают; labels/affinity притягивают — часто используют оба: taint на ноде + toleration в Pod + nodeSelector/nodeAffinity, чтобы только нужные Pod’ы могли попасть на ноду.

  • Не злоупотребляйте NoExecute, если не хотите сразу эвакуировать все Pod’ы. Для миграции лучше сначала PreferNoSchedule, затем NoSchedule, затем NoExecute (если нужно).

  • Tolerations не дают права автоматически попасть на ноду — pod всё ещё должен соответствовать affinity/selector или просто иметь допустимость планировщиком.