Ответ
Для гарантированного разделения подов по разным узлам используется Inter-Pod Anti-Affinity с жестким правилом (requiredDuringSchedulingIgnoredDuringExecution). Это критично для отказоустойчивости StatefulSet'ов (например, мастер-узлы БД) или сервисов, которые не должны простаивать из-за отказа одной ноды.
Пример манифеста Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-app
topologyKey: "kubernetes.io/hostname"
containers:
- name: app
image: nginx:alpine
Как это работает:
labelSelectorопределяет, к каким подам применяется правило (в данном случае ко всем с меткойapp: my-app).topologyKey: "kubernetes.io/hostname"указывает, что "доменом" для разделения является имя узла. Поды с одинаковыми метками не могут быть размещены на узлах с одинаковым значением этого ключа.requiredDuringScheduling...— это жесткое требование. Если в кластере меньше двух узлов, второй под останется в статусеPending.
Альтернатива (мягкое правило): Используйте preferredDuringSchedulingIgnoredDuringExecution, если разделение желательно, но не критично. Планировщик попытается выполнить правило, но разместит поды на одной ноде, если другого выбора нет.