Задача
Под висит в состоянии Pending. При этом kubectl top nodes показывает, что ноды загружены на 40–50% — места, казалось бы, полно.
Вопрос: какие причины могут держать под в Pending и как быстро найти настоящую?
Что кажется очевидным
«Не хватает ресурсов». Иногда так и есть, но «свободно по top» и «доступно для планирования» — разные величины, и это только одна из шести типичных причин.
Как это работает на самом деле
Планировщик работает в две фазы:
- Фильтрация — отсеиваются ноды, на которых под размещать нельзя: не хватает ресурсов, не подходит
nodeSelector, есть непереносимый taint, нет нужного тома. - Оценка — оставшиеся ноды ранжируются, выбирается лучшая.
Если после фильтрации не осталось ни одной ноды — под остаётся Pending, а причина пишется в события.
Ключевой момент про ресурсы: планировщик считает сумму requests всех подов на ноде, а не фактическое потребление. Нода может использовать 40% памяти по факту, но если сумма requests уже покрывает всю ёмкость — новых подов туда не поставят. Это ровно тот случай, когда top вводит в заблуждение.
Шесть типичных причин
1. Недостаточно выделяемых ресурсов. Сумма requests не влезает. Помните, что часть ресурсов ноды зарезервирована под системные компоненты (kube-reserved, system-reserved) и не доступна подам — смотрите Allocatable, а не Capacity.
2. Taints без toleration. Нода помечена, под не имеет разрешения:
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, taints: .spec.taints}'Классика — мастер-ноды с node-role.kubernetes.io/control-plane:NoSchedule и ноды с GPU.
3. Не выполняются nodeSelector / nodeAffinity. Под требует метку, которой ни на одной ноде нет — например, disktype: ssd при переезде в новый пул нод.
4. Не выполняются podAntiAffinity / topologySpread. Правило «не более одного пода на ноду» при 3 нодах не даст запустить четвёртую реплику. При whenUnsatisfiable: DoNotSchedule под честно останется Pending (см. задачу 8).
5. Проблема с томом. PVC не привязан: нет подходящего PV, StorageClass отсутствует, или том находится в другой зоне доступности, чем свободные ноды. Для volumeBindingMode: WaitForFirstConsumer порядок обратный — том создаётся после выбора ноды, и тут свои сюрпризы.
6. Превышена квота namespace. ResourceQuota исчерпана — под не создастся вовсе или зависнет (см. задачу 4).
Ответ
Причин много, но узнавать их наизусть не нужно — планировщик сам пишет причину в события пода. Это первое, что нужно смотреть:
kubectl describe pod my-pod | tail -20Типичный вывод:
Events:
Type Reason Message
---- ------ -------
Warning FailedScheduling 0/12 nodes are available:
3 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: },
5 Insufficient memory,
4 node(s) didn't match Pod's node affinity/selector.Здесь сразу видна вся арифметика: 3 + 5 + 4 = 12 нод, и по каждой группе названа причина. Это самый информативный вывод во всём Kubernetes — он практически всегда даёт ответ.
Что с этим делать
Диагностика по шагам
# 1. Причина — почти всегда здесь
kubectl describe pod my-pod | grep -A10 Events
# 2. Реально доступные ресурсы ноды (Allocatable, не Capacity)
kubectl describe node node-1 | grep -A6 "Allocated resources"
# 3. Taints на нодах
kubectl describe node node-1 | grep -i taint
# 4. Состояние PVC, если под с томом
kubectl get pvcОсобенно полезен пункт 2: он показывает суммы Requests и Limits по ноде в процентах от Allocatable. Если Requests по памяти близки к 100%, вопрос закрыт независимо от показаний top.
Лечение по причинам
| Причина в событиях | Что делать |
|---|---|
Insufficient cpu/memory | Уменьшить requests, добавить ноды, включить autoscaler |
untolerated taint | Добавить tolerations или убрать taint |
didn't match node affinity/selector | Проверить метки нод, поправить селектор |
didn't match pod anti-affinity | Смягчить правило или добавить ноды |
had volume node affinity conflict | Том в другой зоне — проверить StorageClass и зоны |
exceeded quota | Поднять квоту или освободить ресурсы |
Профилактика
- Cluster Autoscaler / Karpenter — чтобы
Pendingиз-за нехватки ресурсов разрешался автоматически добавлением ноды. Но помните: если под не помещается ни на одну возможную ноду (просит больше, чем есть у самого крупного типа), автоскейлер не поможет. - PriorityClass — критичные поды могут вытеснять менее важные вместо ожидания.
- Реалистичные
requests. Завышенныеrequests— самая частая причина «в кластере есть место, но поды не встают». - Мониторинг
Pending. Под, висящий дольше нескольких минут, должен порождать алерт: это либо нехватка ёмкости, либо ошибка в манифесте.
Дальше: Задача 17. StatefulSet, PVC и данные, которые пережили под.