Node Selectors: нацелить Pod на нужную ноду
Как labels на нодах и spec.nodeSelector делят кластер по назначению и почему Pod уходит в Pending при опечатке.
Что вообще такое nodeSelector
nodeSelector - простейший механизм размещения Pod. В spec пишут
карту labels, и Pod может попасть только на ноды, у которых эти labels
проставлены. Принцип тот же, что у label selector в Service, но
направлен на ноды.
Зачем: разделить ноды по назначению. GPU-ноды для ML, SSD-ноды для БД, spot-инстансы для batch. Ставишь на ноды labels, в каждом Pod прописываешь nodeSelector, шедулер сам разруливает.
В отличие от nodeName, который жёстко привязывает к конкретной
ноде по имени, nodeSelector декларативен: «хочу любую ноду с
такими-то свойствами». Нод подходящих три, шедулер выберет любую с
учётом ресурсов. Подходящих нет, Pod висит в Pending и ждёт.
Минимальный YAML
apiVersion: v1
kind: Pod
metadata:
name: db
spec:
nodeSelector:
disk: ssd
tier: production
containers:
- name: db
image: postgres:16
Все ключи в nodeSelector объединены через AND. Ноде нужны и
disk=ssd, и tier=production одновременно.
labels на нодах
labels ставят через kubectl label nodes:
kubectl label nodes node-1 disk=ssd
kubectl label nodes node-1 tier=production
kubectl get nodes --show-labels
kubectl get nodes -L disk -L tier
У всех нод по дефолту есть встроенные labels:
kubernetes.io/hostname, kubernetes.io/os, kubernetes.io/arch,
node.kubernetes.io/instance-type и так далее. На них тоже можно
селектить, удобно для multi-arch кластеров.
Что важно знать
nodeSelectorумеет только строгое равенство ключа со значением. Для «OR», «NOT» и «один из списка» нуженnodeAffinity.- Selector не передвигает работающие Pod. Поставил label, новый Pod сядет куда надо, старые останутся где были.
- Шедулер не падает, если кандидатов нет. Pod висит в Pending. На лету поставишь нужный label на ноду, Pod оживёт.
- На labels у нод есть лимиты длины ключа и значения (63 символа), как у обычных kubernetes labels.
Даже в кластере из одной ноды механизм видно целиком: с нужным label
Pod запускается, стоит написать в селекторе несуществующее значение -
и он уходит в Pending с FailedScheduling.
Причина видна в kubectl describe pod: FailedScheduling: didn't match Pod's node affinity/selector. Значит label на ноде нет или в ключе
опечатка.
nodeSelector vs nodeName vs nodeAffinity
nodeName. Хардкод одной ноды по имени. Шедулер вне игры.nodeSelector. Простой матч по labels, AND, строгое равенство.nodeAffinity. То же самое плюс OR, веса предпочтений, численные сравнения, soft/hard правила.
В реальной жизни в проде используют либо nodeSelector (когда
хватает простого равенства), либо nodeAffinity (когда нужны
preferred-правила или сложная логика).
Связанные команды
kubectl label nodes <name> disk=ssd
kubectl label nodes <name> disk- # снять label
kubectl get nodes --show-labels
kubectl get nodes -l disk=ssd
kubectl get nodes -L disk
kubectl describe pod <name> # секция Events если Pending
kubectl explain pod.spec.nodeSelector
Что часто ломается
- Поставил
disk: SSD(большие буквы), а на нодеdisk=ssd. Равенство строгое, не сматчится. - Указал label, который есть у другой группы нод. Pod сел не туда. labels должны быть точные и осмысленные.
- Шедулер вроде должен видеть свободную ноду, но не ставит. Проверь taints на ноде: nodeSelector не пробивает taint, нужны tolerations.
Домашка
Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-node-selectors # развернуть стартовое состояние
./run.sh verify k8s-node-selectors # проверить текущий шаг
Коротко
nodeSelector- карта labels в spec Pod, все ключи через AND и только строгое равенство.- labels на ноды ставят через
kubectl label nodes, встроенные (kubernetes.io/archи другие) есть у всех нод сразу. - Нет подходящей ноды - Pod остаётся в
Pending, причина видна в событияхkubectl describe pod. - Новый label не переносит уже работающие Pod, он влияет только на следующее размещение.
nodeSelectorне пробивает taints. Для OR-логики и предпочтений нуженnodeAffinity.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс