Отладка: почему под не стартует

Рейтинг: 73% · 17 голосов
Kubernetes для разработчиков: поды, деплойменты, сервисы, ingress, конфиги и отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
anton_k8s
Сообщения: 26
Зарегистрирован: 12 май 2026, 03:23

Отладка: почему под не стартует

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 11 из 19
Оглавление курса (19)
  1. Зачем нужен Kubernetes и из чего состоит кластер
  2. Поднимаем локальный кластер: minikube и kind
  3. Поды: базовая единица запуска
  4. Deployment и ReplicaSet: управляем репликами
  5. Service: сетевой доступ к подам
  6. ConfigMap и Secret: выносим конфигурацию
  7. Ingress: пускаем трафик снаружи
  8. Хранилище: Volumes и PersistentVolumeClaim
  9. Namespaces, requests и limits
  10. Health checks: liveness и readiness пробы
  11. Отладка: почему под не стартует (вы здесь)
  12. Helm: пакетный менеджер для Kubernetes
  13. Базовая безопасность: RBAC и доступы
  14. Job и CronJob: разовые и периодические задачи
  15. StatefulSet и DaemonSet: stateful-нагрузки и системные агенты
  16. Стратегии обновления и планирование: rollout и rollback, graceful shutdown, nodeSelector, affinity, taints
  17. Автомасштабирование: HPA по метрикам, обзор VPA и Cluster Autoscaler
  18. Наблюдаемость: логи, метрики, events, обзор Prometheus и Grafana
  19. Безопасность глубже: securityContext, Pod Security Standards, NetworkPolicy, шифрование секретов
Под создан, а приложение не работает. В Kubernetes между "применил манифест" и "контейнер запустился" лежит цепочка шагов, и сломаться может любой из них. В этой главе разберем рабочий алгоритм: как по статусу пода за пару минут понять, где именно все застряло.

С чего начинается отладка:

Первая команда всегда одна и та же:

Код: Выделить всё

kubectl get pods
NAME                      READY   STATUS             RESTARTS   AGE
api-7d4b9c6f5d-x2x8q      0/1     ImagePullBackOff   0          2m
worker-6f9b8d7c4b-k9j2m   0/1     CrashLoopBackOff   4          5m
report-5c8d7f9b6c-p4n7r   0/1     Pending            0          8m
Колонка STATUS сужает поиск до конкретного класса проблем. Вторая команда дает детали:

Код: Выделить всё

kubectl describe pod api-7d4b9c6f5d-x2x8q
Самое ценное в выводе describe находится в конце, в секции Events. Туда кластер пишет, что он пытался сделать с подом и что пошло не так.

Разбор по статусам:

ImagePullBackOff и ErrImagePull. Кластер не смог скачать образ. В Events будет точная причина: not found (опечатка в имени или теге), unauthorized (приватный registry, а imagePullSecrets не указан) или сетевой таймаут. Последнее особенно актуально, если ноды тянут образы с Docker Hub напрямую: надежнее держать копии в своем registry, том же Yandex Container Registry или Harbor на отдельной виртуалке.

Pending. Под даже не назначен на ноду. Шедулеру либо некуда его поставить (Insufficient cpu или Insufficient memory в Events, вспоминаем requests из главы 9), либо мешает условие: nodeSelector, который не совпадает ни с одной нодой, или PVC из главы 8, который сам завис в Pending.

CrashLoopBackOff. Образ скачан, контейнер стартует и падает, kubelet перезапускает его с растущей паузой. Здесь смотрим логи, причем именно упавшего экземпляра:

Код: Выделить всё

kubectl logs worker-6f9b8d7c4b-k9j2m --previous
Без этого флага вы увидите логи свежеперезапущенного контейнера, который мог еще не дойти до места падения. Типичные причины: приложение не достучалось до базы, не хватает переменной окружения, ошибка в command или args.

CreateContainerConfigError. Под ссылается на ConfigMap или Secret, которого нет (или он лежит в другом namespace). describe прямо назовет имя недостающего объекта. Привет главе 6.

OOMKilled. Контейнер убит за превышение лимита памяти. В describe это видно как Last State: Terminated, Reason: OOMKilled, exit code 137. Лечится либо поднятием limits, либо поиском утечки в приложении.

Когда describe молчит:

Иногда полезно посмотреть события всего namespace, отсортированные по времени:

Код: Выделить всё

kubectl get events --sort-by=.lastTimestamp -n production
А если контейнер собран из distroless-образа и внутри нет даже sh, выручает эфемерный контейнер:

Код: Выделить всё

kubectl debug -it worker-6f9b8d7c4b-k9j2m --image=busybox:1.36 --target=worker
Он подключается к живому поду со своим набором утилит и ничего в нем не меняет.

Типичные грабли:

Логи смотрят у нового экземпляра контейнера вместо упавшего и удивляются, что там пусто. Забывают флаг -n и ищут под не в том namespace. Путают "под не стартует" и "под Running, но 0/1 READY": второе почти всегда означает заваленную readiness-пробу из главы 10, и отлаживается она иначе. Тег latest с imagePullPolicy Always внезапно притягивает чужую свежую сборку. И помните, что события живут в кластере по умолчанию около часа: если под сломался ночью, утром секция Events может быть уже пустой, спасают только логи и мониторинг.

Что усвоили:

Алгоритм простой и почти всегда достаточный: get pods для диагноза, describe для деталей, логи упавшего экземпляра при падениях, get events для общей картины по namespace. В следующей главе соберем накопившиеся манифесты в нормальный пакет с помощью Helm, чтобы перестать таскать YAML россыпью.
👍3 ❤️3 🔥2 😄 🤔1
✔ Лучший ответ сформирован автоматически — ivan88
anton_k8s писал(а):Без этого флага вы увидите логи свежеперезапущенного контейнера, который мог еще не дойти до места падения. а если под рестартовал уже раз двадцать? можно как-то достать логи не только последнего падения, а скажем пятого с конца? или kubelet хранит только текущий и предыдущий?
Перейти к ответу →
Аватара пользователя
ivan88
Сообщения: 1
Зарегистрирован: 19 май 2026, 12:47

Re: Отладка: почему под не стартует

Сообщение ivan88 »

✔ Лучший ответ — сформирован автоматически
anton_k8s писал(а):Без этого флага вы увидите логи свежеперезапущенного контейнера, который мог еще не дойти до места падения.
а если под рестартовал уже раз двадцать? можно как-то достать логи не только последнего падения, а скажем пятого с конца? или kubelet хранит только текущий и предыдущий?
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
ScalaMain
Сообщения: 1
Зарегистрирован: 31 май 2026, 23:58

Re: Отладка: почему под не стартует

Сообщение ScalaMain »

спасибо за разбор CreateContainerConfigError, прям в точку. вчера полдня дебажил, оказалось секрет создал в default, а деплой катился в staging. describe реально сразу пишет имя недостающего объекта, я просто в Events не смотрел, сидел в логах которых нет
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
mstiles
Сообщения: 1
Зарегистрирован: 28 май 2026, 18:33

Re: Отладка: почему под не стартует

Сообщение mstiles »

kubectl debug у меня ругнулся что ephemeral containers disabled. потом дошло, что на работе кластер старый, 1.22. так что если у кого тоже не заводится, проверьте версию через kubectl version, на свежих все ок
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
elasticcoder
Сообщения: 1
Зарегистрирован: 10 июн 2026, 22:56

Re: Отладка: почему под не стартует

Сообщение elasticcoder »

небольшое дополнение про 137: это не всегда OOM. контейнер получает SIGKILL и при обычном рестарте, если не успел завершиться за terminationGracePeriodSeconds. так что смотрите именно Reason в describe, а не только код выхода, сэкономите время
👍3 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Health checks: liveness и readiness пробы
Следующая глава →
Helm: пакетный менеджер для Kubernetes

Все главы курса «Kubernetes на практике»

Поделиться темой: ✈ Telegram VK

Вернуться в «Kubernetes на практике»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость