При создании пода в Kubernetes он не появляется на конкретной ноде автоматически.
За выбор подходящего узла отвечает kube-scheduler — компонент control plane, который принимает решение, на какую ноду отправить новый или ожидающий назначения под.
🔭 Что делает kube-scheduler?
Основная задача — найти для каждого пода ноду, которая:
— соответствует всем жёстким требованиям (например, достаточно CPU и памяти, нужные метки, отсутствие запрещающих taint'ов);
— является наилучшей по ряду критериев (например, более свободная, с меньшей загрузкой, предпочитаемая по affinity).
После выбора scheduler сообщает API-серверу о назначении, и kubelet на выбранной ноде запускает под.
✍️ Как происходит планирование:
Процесс планирования логически делится на два этапа:
📌 Фильтрация (Predicates / Filtering)
Отсеиваются все ноды, которые не могут запустить под.
Проверяются:
🔵достаточно ли свободных ресурсов (CPU, память, диски, порты);
🔵соответствуют ли нода меткам, указанным в nodeSelector или nodeAffinity;
🔵не запрещают ли taints запуск пода без соответствующих tolerations;
🔵соблюдены ли правила Pod Affinity/Anti-Affinity;
🔵не конфликтуют ли с уже запущенными подами (например, занятые порты hostPort).
Результат — список подходящих нод.
📌 Оценка (Scoring / Prioritization)
Каждая оставшаяся нода получает баллы по различным критериям. Чем больше баллов, тем предпочтительнее нода.
Критерии могут быть разными:
🔵количество свободных ресурсов после запуска пода,
🔵сбалансированность использования ресурсов,
🔵близость к другим заданным подам (для уменьшения сетевых задержек), 🔵выполнение правил предпочтений (preferred affinity) и т.д.
По итогам выбирается нода с наибольшей суммой баллов.
Если подходящих нод нет — под остаётся в статусе Pending, и scheduler будет периодически повторять попытки.
⚙️ Ключевые механизмы управления планированием
💬 nodeSelector
— Простейший способ указать, что под должен быть размещён на ноде с определённой меткой.
💬 Affinity и Anti-Affinity
— Более выразительные правила, поддерживающие условия и уровни строгости (
requiredDuringSchedulingIgnoredDuringExecution — жёсткое требование, preferredDuringSchedulingIgnoredDuringExecution — предпочтение).— Node affinity: привязка к характеристикам ноды
— Pod affinity/anti-affinity: привязка к расположению других подов (например, требование запускать под на той же ноде, где уже работает под с меткой app=frontend, или, наоборот, избегать одной ноды с подами другого приложения).
💬 Taints и Tolerations — Taints (метка) наносятся на ноды и отталкивают поды, у которых нет соответствующих tolerations (переносимости). Позволяет выделять ноды под специальные задачи (например, только для GPU-нагрузок) или защищать мастер-ноды.
💬 Resource Requests и Limits — Scheduler учитывает запрошенные подом ресурсы (requests) и доступные на ноде. Без указания requests под может быть запланирован на перегруженную ноду, что приведёт к нехватке ресурсов для других.
💬 Приоритеты подов (Pod Priority and Preemption) — Поды можно разделять по приоритетам. Если высокоприоритетный под не может быть запланирован, scheduler может вытеснить (preempt) один или несколько низкоприоритетных подов с ноды, чтобы освободить место.
Kube-scheduler — это мозг Kubernetes по размещению подов. Он не просто выбирает первую попавшуюся ноду, а принимает взвешенное решение на основе множества факторов. Управление его поведением через манифесты позволяет строить эффективные и надёжные системы, максимально использующие мощности кластера.
#заметкиИнженера
