Как ищешь причину зависания кода в состоянии Pending в Kubernetes
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Поиск причин зависания Pod'ов в состоянии Pending в Kubernetes
Pending — это состояние, указывающее, что Kubernetes принял запрос на создание Pod'а, но не смог его запланировать на какой-либо узел. Это одна из наиболее частых проблем в кластере, и её диагностика требует системного подхода. Я следую многоуровневой стратегии, начиная с самой очевидной информации и постепенно углубляясь.
1. Первичный сбор информации и анализ Pod'а
Первым делом я проверяю расширенную информацию о Pod'е, используя флаг -o wide и ключевое поле status. Команда kubectl describe pod — основной инструмент.
# Получаем общую информацию о подах в Pending
kubectl get pods --all-namespaces | grep Pending
# Детальное описание проблемного пода
kubectl describe pod <pod-name> -n <namespace>
В выводе describe критически важны два раздела:
- Events: События в нижней части вывода показывают хронологию попыток планировщика. Это главный источник истины. Частые сообщения:
FailedScheduling,0/X nodes are available. - Conditions: Состояния Pod'а, например,
PodScheduledсо статусомFalseи сообщением.
Пример предупреждения в Events, на которое я сразу обращаю внимание:
Warning FailedScheduling 3s (x5 over 18s) default-scheduler 0/3 nodes are available: 1 Insufficient cpu, 2 node(s) didn't match Pod's node affinity/selector.
2. Анализ наиболее частых причин на основе событий
Я систематизирую поиск по основным категориям проблем:
A. Нехватка ресурсов на узлах (Insufficient resources)
Это самая распространённая причина. Кластеру не хватает запрашиваемых CPU или Memory (реже ephemeral-storage).
- Проверка: В событиях будет явное указание.
- Действия:
# Проверяем запросы (requests) и лимиты (limits) пода kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].resources}' # Смотрим доступные ресурсы на всех узлах kubectl describe nodes | grep -A 5 -i "allocatable" # Или используем утилиту kubectl-top kubectl top nodes
**Решение:** Увеличить `requests`/`limits` у других Pod'ов, добавить новые узлы в кластер (масштабирование) или оптимизировать потребление ресурсов приложениями.
B. Несоблюдение селекторов и правил размещения (Affinity/Node Selectors/Taints)
- Node Selector / Node Affinity: Pod запрашивает узлы с определёнными метками (
disktype=ssd,gpu=true), которых нет.# Проверяем селекторы узла у пода kubectl get pod <pod-name> -o jsonpath='{.spec.nodeSelector}' # Смотрим метки всех узлов kubectl get nodes --show-labels - Taints and Tolerations: Узлы могут иметь "пятна" (taints), которые отталкивают Pod'ы, если у тех нет соответствующих "допусков" (tolerations).
# Смотрим taints на узлах kubectl describe node <node-name> | grep Taint # Проверяем tolerations у пода kubectl get pod <pod-name> -o jsonpath='{.spec.tolerations}'
C. Отсутствие доступного узла, удовлетворяющего всем условиям
Комбинация причин: Pod требует 8Gi памяти, а также метку zone=west, при этом узел с меткой имеет только 4Gi свободно. События обычно перечисляют несколько причин.
D. Проблемы с PersistentVolumeClaims (PVC)
Если Pod использует постоянное хранилище, он будет оставаться в Pending, пока связанный PVC не перейдёт в статус Bound.
# Проверяем статус PVC
kubectl get pvc -n <namespace>
# Детализируем проблемный PVC
kubectl describe pvc <pvc-name> -n <namespace>
Возможные причины: Нет доступного PersistentVolume (PV), удовлетворяющего storageClassName, accessModes или size. Либо проблемы с динамическим провижионингом (CSI-драйвер, квоты в облаке).
E. Достигнуты лимиты (Quotas) и лимиты пространства имён (ResourceQuotas, LimitRanges)
Администратор мог установить ResourceQuotas для пространства имён.
# Проверяем квоты в namespace
kubectl describe resourcequota -n <namespace>
Если сумма requests всех Pod'ов в namespace превышает квоту, новые Pod'ы будут зависать в Pending.
3. Углублённая диагностика и работа с планировщиком (Scheduler)
Если очевидных причин не найдено, я перехожу к анализу логики планировщика.
- Просмотр логов планировщика: Включаю детальный логгинг или смотрю существующие логи.
# Получаем логи пода планировщика (зависит от установки) kubectl logs -n kube-system -l component=kube-scheduler --tail=50
В логах ищу конкретный ID Pod'а (например, `default/myapp-pod-12345`). Современный планировщик (kube-scheduler) часто подробно логирует этапы фильтрации и оценки.
-
Ручная проверка планирования: С помощью
kubectlможно симулировать работу планировщика для проверки его логики (в отладочных целях). -
Проверка состояния узлов: Узел может быть в состоянии
NotReady, что делает его недоступным для планирования.kubectl get nodes kubectl describe node <node-name> # Ищу условия Ready, MemoryPressure, DiskPressure, PIDPressure.
4. Прочие специфические причины
- Низкий приоритет Pod'а (PriorityClass): В кластере с приоритетами Pod'ы с высоким
priorityClassNameмогут вытеснять менее приоритетные или занимать все ресурсы. - Проблемы с Container Runtime: В редких случаях сбойная работа CRI (например, containerd или docker) на узле может приводить к тому, что kubelet не отчитывается о доступных ресурсах корректно.
- Баг или кастомизация планировщика: При использовании кастомных scheduler profiles или сторонних планировщиков проблема может быть в их конфигурации.
Моя общая стратегия резюмируется в чек-лист:
kubectl describe pod→ Анализ Events и Conditions.- Проверка ресурсов:
kubectl top nodes, сравнениеrequestsсallocatable. - Проверка меток, taints и tolerations:
kubectl describe node. - Проверка хранилища:
kubectl get pvc,pv. - Проверка квот namespace:
kubectl describe resourcequota. - Анализ состояния узлов:
kubectl get nodes,kubectl describe node. - Логи планировщика:
kubectl logs -n kube-system -l component=kube-scheduler.
Такой иерархический подход позволяет в 95% случаев быстро локализовать причину зависания Pod'а в состоянии Pending, будь то банальная нехватка памяти или сложная комбинация affinity и taints.