← Kubernetes: планирование
5 мин · просто · Урок 3 из 7

Node Selectors: нацелить Pod на нужную ноду

Как labels на нодах и spec.nodeSelector делят кластер по назначению и почему Pod уходит в Pending при опечатке.

Что вообще такое nodeSelector

node-1 · metadata.labels disk: ssd tier: production Pod · spec.nodeSelector disk: ssd tier: production совпадение строк
Шедулер оставит только те ноды, у которых есть обе строки из 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 кластеров.

Что важно знать

Даже в кластере из одной ноды механизм видно целиком: с нужным label Pod запускается, стоит написать в селекторе несуществующее значение - и он уходит в Pending с FailedScheduling.

Причина видна в kubectl describe pod: FailedScheduling: didn't match Pod's node affinity/selector. Значит label на ноде нет или в ключе опечатка.

nodeSelector vs nodeName vs nodeAffinity

В реальной жизни в проде используют либо 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

Что часто ломается

Домашка

Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-node-selectors     # развернуть стартовое состояние
./run.sh verify k8s-node-selectors    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.