Короткий ответ
podAntiAffinity с правилом по топологическому ключу (topologyKey: kubernetes.io/hostname или topology.kubernetes.io/zone) запрещает или не предпочитает планировать несколько реплик одного приложения на один и тот же узел/зону, снижая риск одновременной потери всех реплик при сбое одного узла или зоны.
Как это работает подробнее
requiredDuringSchedulingIgnoredDuringExecution — жёсткое правило, под которое не удовлетворяющее условие вообще не будет запланировано; preferredDuringSchedulingIgnoredDuringExecution — мягкое предпочтение с весом, которое планировщик учитывает, но может нарушить, если нет другого выбора. "IgnoredDuringExecution" означает, что правило проверяется только при планировании и не приводит к выселению уже запущенного Pod при последующем изменении условий.
Пример кода
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector: { matchLabels: { app: web } }
topologyKey: "kubernetes.io/hostname"Что использовать на практике
- Практика. жёсткая anti-affinity гарантирует распределение, но может привести к тому, что часть реплик останется в
Pending, если подходящих узлов/зон физически не хватает (например, 5 реплик при anti-affinity "один под на узел" и только 3 узлах); мягкая anti-affinity безопаснее с точки зрения доступности размещения, но не даёт строгой гарантии распределения. Для распределения по зонам также можно использоватьtopologySpreadConstraints, который даёт более гибкий контроль над максимальным перекосом (maxSkew).
Подводные камни
- Риски. использовать жёсткую (
required) anti-affinity без учёта реального числа доступных узлов/зон, что приводит к незапланированным Pod в периоды пиковой нагрузки при масштабировании; путатьpodAffinity(стремление к размещению рядом, например с кэшем) иpodAntiAffinity(стремление к размещению порознь, для отказоустойчивости) — у них противоположные цели.