Что такое Node в Kubernetes
Если Control Plane — это «мозг» и администрация кластера, то ноды — это его «рабочие руки». Кластер объединяет вычислительные ресурсы десятков таких нод (процессоры, оперативную...
🟢 Junior Level
30-секундный ответ
Node (Узел) — это отдельный физический сервер или виртуальная машина в кластере Kubernetes, на которой фактически запускаются и выполняются поды с приложениями.
Если Control Plane — это «мозг» и администрация кластера, то ноды — это его «рабочие руки». Кластер объединяет вычислительные ресурсы десятков таких нод (процессоры, оперативную память, диски) в единый общий пул.
Наглядная аналогия из жизни
Представьте международный грузовой порт:
- Control Plane (Диспетчерская): принимает заказы, распределяет грузы по кораблям, следит за расписанием.
- Node (Грузовой корабль): обладает физической грузоподъёмностью (CPU и RAM).
- Pod (Контейнеры с грузом): размещаются на палубе корабля.
- Капитан корабля (
kubelet): следит за креплением грузов, проверяет целостность и непрерывно докладывает в диспетчерскую о свободном месте на палубе.
3 обязательных компонента на каждом Worker Node
kubelet— главный агент узла. Принимает отkube-apiserverзадания на запуск подов, общается с рантаймом контейнеров, выполняет Health Checks и отправляет сигналы жизнеспособности узла (Node Heartbeats).kube-proxy— сетевой агент. Настраивает правила фильтрации пакетов и маршрутизации (iptablesилиIPVS) в ядре операционной системы хоста, отвечая за балансировку трафика сервисов.Container Runtime(CRI) — низкоуровневая среда исполнения контейнеров. Начиная с Kubernetes 1.24 (после удаленияdockershim), стандартом индустрии являютсяcontainerdиCRI-O.
🟡 Middle Level
Бюджет ресурсов ноды: Capacity vs Allocatable
Распространённая ошибка — считать, что вся оперативная память физического сервера доступна подам. Kubernetes рассчитывает доступные ресурсы по строгой формуле:
\[\mathbf{Allocatable} = \mathbf{Capacity} - \mathbf{kube\text{-}reserved} - \mathbf{system\text{-}reserved} - \mathbf{eviction\text{-}threshold}\]+--------------------------------------------------------------------------+
| Node Capacity (Например: 32 GiB RAM) |
| |
| [ kube-reserved ] -> Память для процессов K8s (kubelet, containerd) |
| [ system-reserved ] -> Память для ядра ОС и системных демонов (sshd) |
| [ hard-eviction ] -> Защитный буфер безопасности (порог выселения) |
| ──────────────────────────────────────────────────────────────────────── |
| [ Allocatable ] -> ТОЛЬКО ЭТА ЧАСТЬ доступна для планирования подов!|
+--------------------------------------------------------------------------+
[!IMPORTANT] Планировщик
kube-schedulerоперирует исключительно значениемAllocatable. Если суммаrequestsуже запущенных подов исчерпалаAllocatable, планировщик никогда не посадит новый под на эту ноду, даже если физически память свободна.
Статусы и условия ноды (Node Conditions)
Kubelet непрерывно сообщает состояние здоровья ноды через флаги в объекте Node:
| Condition | Нормальное значение | Описание |
| :— | :—: | :— |
| Ready | True | Нода здорова, kubelet активен и готов принимать поды. |
| MemoryPressure | False | Если True — свободная память упала ниже порога, планирование блокируется. |
| DiskPressure | False | Если True — диск переполнен (не хватает места под образы или логи). |
| PIDPressure | False | Если True — исчерпан лимит доступных идентификаторов процессов Linux PID. |
| NetworkUnavailable| False | Если True — маршрутизация CNI-сети для ноды не настроена. |
Обслуживание нод: Cordon и Drain
Перед проведением технических работ на физическом сервере (обновление ядра Linux, замена RAM):
kubectl cordon <node>(Оцепление):- Помечает ноду как
SchedulingDisabled. - Новые поды на ноду не планируются, но уже запущенные продолжают работать.
- Помечает ноду как
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data(Опустошение):- Блокирует планирование и бережно выселяет (evict) все работающие поды на другие здоровые ноды кластера через механизм Graceful Shutdown.
kubectl uncordon <node>(Снятие оцепления):- Возвращает сервер в строй после перезагрузки.
🔴 Senior Level
Управление размещением: Taints, Tolerations и Node Affinity
Senior-инженер настраивает гибкое распределение нагрузок между специализированными серверами (например, узлы с GPU или узлы под базы данных).
[ Обычный Pod ] [ GPU Pod с Toleration ]
│ │
▼ ▼
❌ Отталкивается! 🟢 Разрешено размещение!
│ │
└─────────────► [ Node с Taint ] ◄───────┘
gpu=true:NoSchedule
1. Taints (Метки отторжения на ноде)
Задаются на узле: kubectl taint nodes worker-gpu dedicated=gpu:NoSchedule.
NoSchedule: новые поды без соответствующей толерантности не будут запланированы на узел.PreferNoSchedule: планировщик попытается избежать размещения, но при дефиците ресурсов посадит под сюда.NoExecute: поды без толерантности немедленно выселяются с узла, даже если они уже работали на нём!
2. Tolerations (Толерантность в манифесте Pod)
Позволяет поду игнорировать метку отторжения:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
3. Node Affinity (Притяжение пода к ноде)
requiredDuringSchedulingIgnoredDuringExecution: жесткое правило (hard rule). Если ноды с меткойtopology.kubernetes.io/zone=eu-west-1aнет, под останется в статусеPending.preferredDuringSchedulingIgnoredDuringExecution: мягкое правило (soft rule) с выставлением весовых коэффициентов приоритета.
Архитектура Node Leases (Оптимизация etcd)
Исторически (до K8s 1.14) каждый kubelet каждые 10 секунд слал полное обновление объекта NodeStatus в kube-apiserver.
- При кластере в 2000 нод это вызывало огромную нагрузку на
etcdи сеть (размер объекта Node с десятками образов и адресов — десятки килобайт). - Современная архитектура: разделение статуса:
- Тяжелый объект
Nodeобновляется редко (только при изменении условий, например раз в минуту). - Быстрый heartbeat передаётся через сверхлегковесный объект
Leaseв пространстве имёнkube-node-leaseкаждые 10 секунд. Если арендаLeaseне продлевается более 40 секунд, Controller Manager переводит ноду в статусNotReady.
- Тяжелый объект
Kubelet Eviction Manager (Вытеснение подов при дефиците памяти)
Когда на ноде срабатывает жесткий порог evictionHard: memory.available < 100Mi:
- Kubelet не ждёт реакции Control Plane, а принимает решение локально прямо на ноде.
- Kubelet ранжирует поды по потреблению ресурсов относительно их
requestsи классу качества обслуживания:- Сначала выселяются поды
BestEffort, потребляющие больше всех памяти. - Затем выселяются поды
Burstable, превысившие свойrequests.memory. - Поды
Guaranteedвыселяются в последнюю очередь, только если на ноде больше нет других подов.
- Сначала выселяются поды
4 Tricky Questions
1. Почему команда kubectl drain <node> по умолчанию завершается ошибкой, если на ноде есть поды с томами emptyDir или поды без контроллера (Bare Pods)?
Ответ:
Команда drain защищает пользователя от случайной безвозвратной потери данных:
- Тома
emptyDir: данные вemptyDirсуществуют исключительно на диске конкретной ноды. Удаление пода уничтожит эти данные навсегда. Поэтомуdrainтребует явного подтверждения флагом--delete-emptydir-data. - Поды без контроллера (Bare Pods): если под создан напрямую (
kind: Pod), а не черезDeploymentилиStatefulSet, то при его удалении его некому пересоздать на другой ноде. Он просто исчезнет. Для их удаления требуется флаг--force. - DaemonSet: поды DaemonSet обязаны работать на каждой ноде. Команда
drainне может их выселить на соседнюю ноду (там уже запущен свой экземпляр), поэтому требует флага--ignore-daemonsets.
2. Что произойдёт с работающими подами на ноде, если процесс kubelet на этом сервере аварийно завершится (упадёт или зависнет)?
Ответ:
- Процессы контейнеров продолжат работать! Запущенные контейнеры управляются рантаймом
containerd, который работает как независимый демон. Трафик черезkube-proxyпродолжит идти к подам. - Нода перестанет обновлять свой объект
Leaseвkube-apiserver. Через 40 секунд Controller Manager присвоит ноде состояниеReady=Unknown. - Запустится таймер
pod-eviction-timeout(по умолчанию 5 минут). - Если
kubeletне восстановится за 5 минут, контроллер начнёт создавать замещающие копии подов на других нодах кластера. - Однако исходные поды на сломанной ноде продолжат выполняться до тех пор, пока
kubeletне оживёт и не получит команду на их удаление.
3. В чём принципиальная разница между эффектами Taints NoSchedule и NoExecute?
Ответ:
NoSchedule: влияет только на будущие поды в момент работы планировщикаkube-scheduler. Поды, которые уже были запущены на этой ноде до добавления taint, продолжат спокойно работать и не будут тронуты.NoExecute: влияет и на новые, и на уже работающие поды! Если на ноду повесить taint с эффектомNoExecute, планировщик мгновенно инициирует удаление (eviction) всех подов на этой ноде, у которых нет явногоtolerationдля этой метки (или выселит их по истечении таймераtolerationSeconds).
4. Чем технология автомасштабирования узлов Karpenter (от AWS) архитектурно превосходит классический Kubernetes Cluster Autoscaler?
Ответ:
- Cluster Autoscaler (Классический подход): привязан к группам автомасштабирования облака (AWS Auto Scaling Groups — ASG). При появлении
Pendingподов он увеличивает размер предопределённой группы узлов фиксированного типа (например, добавляет ещё одинm5.large). Процесс занимает 3–5 минут, а узлы часто расходуются неэффективно. - Karpenter: работает напрямую с API облачного провайдера в обход ASG. Он анализирует совокупные требования всех
Pendingподов (CPU, GPU, архитектура ARM/x86, зоны доступности) и за 30–45 секунд заказывает ровно один идеально подходящий сервер (Right-Sized Instance или Spot-инстанс), экономя до 50% бюджета на облако.
🎯 Шпаргалка для интервью
Главное о Node
- Суть: рабочий сервер кластера (физический или ВМ).
- 3 обязательных демона:
kubelet(агент пода),kube-proxy(L4-сеть),containerd/CRI-O(рантайм). - Ресурсы: $\text{Allocatable} = \text{Capacity} - \text{Зарезервировано под K8s и ОС}$. Планирование идёт только по Allocatable!
- Сервисные команды:
cordon(запрет новых),drain(плавное выселение),uncordon(возврат в строй). - Taints / Tolerations: механизм отталкивания неподходящих подов (
NoSchedule,NoExecute). - Node Affinity: притяжение подов к серверам по меткам (SSD, GPU, Availability Zone).
Сравнение эффектов Taints
| Эффект Taint | Новые поды | Уже работающие поды |
| :— | :— | :— |
| NoSchedule | ❌ Не пускает | 🟢 Не трогает (продолжают работать) |
| PreferNoSchedule | 🟡 Старается не пускать (мягкое правило)| 🟢 Не трогает |
| NoExecute | ❌ Не пускает | 🔴 Немедленно выселяет с ноды! |
Красные флаги на собеседовании (Чего говорить нельзя)
- ❌ «Node и Pod — это одно и то же» — Node это сервер (хост), Pod это контейнерная группа, работающая на сервере.
- ❌ «Вся память сервера доступна подам» — часть памяти жестко зарезервирована под kubelet, containerd и ОС (Allocatable < Capacity).
- ❌ «Падение kubelet сразу убивает запущенные контейнеры» — контейнеры продолжают работать в containerd, но теряется управление нодой.