Ответ
Kubernetes предоставляет несколько механизмов для тонкого контроля над тем, на каких узлах будут запускаться Pod'ы. Мы используем их в комбинации для обеспечения отказоустойчивости, производительности и эффективного использования ресурсов.
1. Node Selector & Node Affinity (Куда размещать):
nodeSelector: Простой выбор узлов по лейблам. Например, для запуска Pod'а только на узлах с SSD:spec: nodeSelector: disktype: ssdnodeAffinity: Более выразительные правила (In,NotIn,Exists,Gt,Lt). Бывает "жестким" (requiredDuringScheduling...) и "мягким" (preferredDuringScheduling...). Мы используем "мягкое" affinity для предпочтительного размещения на узлах в определенной зоне доступности.affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - eu-west-1a
2. Pod Affinity & Anti-Affinity (Размещать вместе или раздельно):
- Pod Affinity: Размещать Pod'ы на тех же узлах/зонах, что и другие Pod'ы (полезно для снижения задержки).
- Pod Anti-Affinity (используем чаще): Критически важно для распределения реплик одного приложения по разным узлам/зонам, чтобы повысить отказоустойчивость.
affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: redis-cache topologyKey: kubernetes.io/hostname # Не размещать две реплики redis на одном узле
3. Taints & Tolerations (Куда НЕ размещать):
- Taint ("пятно") на узле отталкивает все Pod'ы, которые не имеют соответствующего Toleration ("терпимости").
- Мы используем это для выделения специальных узлов (например, с GPU). На них ставится taint
gpu=true:NoSchedule, и только Pod'ы с соответствующим toleration могут там запуститься.tolerations: - key: "gpu" operator: "Equal" value: "true" effect: "NoSchedule"
4. Pod Topology Spread Constraints (Равномерное распределение): Самый современный механизм для гарантированного распределения Pod'ов по доменам сбоя (зонам, узлам). Мы настраиваем его для ключевых Deployment, чтобы максимизировать доступность.
topologySpreadConstraints:
- maxSkew: 1 # Максимальная разница в количестве Pod'ов между зонами
topologyKey: topology.kubernetes.io/zone # Критерий распределения - зона доступности
whenUnsatisfiable: DoNotSchedule # Жесткое требование
labelSelector:
matchLabels:
app: my-critical-app
В нашем продакшене мы комбинируем Pod Anti-Affinity (для распределения по узлам) с Topology Spread Constraints (для распределения по зонам), а для специализированных рабочих нагрузок используем Taints/Tolerations.