Введение / Зачем это нужно
Поды (Pods) — это базовые и самые часто используемые объекты в Kubernetes. Однако они могут перестать работать по множеству причин: от нехватки ресурсов до ошибок в конфигурации или самом приложении. Системная диагностика с помощью kubectl позволяет быстро локализовать проблему, а не гадать или пересоздавать ресурсы вслепую. После выполнения этого гайда вы сможете самостоятельно выявлять и исправлять большинство типичных проблем с подами.
Требования / Подготовка
Перед началом убедитесь, что у вас есть:
- Доступ к кластеру Kubernetes с правами на просмотр подов (обычно роль
viewили выше). - Установленный и настроенный клиент
kubectl(версия, совместимая с вашим кластером). - Базовое понимание структуры пода и его компонентов (контейнеры, Init Containers, тома).
- Название проблемного пода и его namespace (если не default).
Пошаговая инструкция
Шаг 1: Проверьте общий статус пода и кластера
Первым делом убедитесь, что pod существует и посмотрите на его текущее состояние.
# Показать все поды во всех namespace (или укажите -n <namespace>)
kubectl get pods --all-namespaces
# Если знаете namespace, посмотрите только в нём
kubectl get pods -n <your-namespace>
Обратите внимание на столбец STATUS. Критические состояния:
Pending— pod не был запланирован на ноду.CrashLoopBackOff/Error— контейнер(ы) завершаются с ошибкой.ImagePullBackOff/ErrImagePull— не удалось загрузить образ.Terminating— pod не может быть завершен (часто из-заfinalizers).
Если pod отсутствует в списке, возможно, он был удалён или вы смотрите в не том namespace.
Шаг 2: Изучите подробные события и конфигурацию пода
Команда describe — ваш основной инструмент для диагностики. Она выводит всю метаинформацию о поде и, что самое важное, события (Events), которые часто содержать ключ к разгадке.
kubectl describe pod <pod-name> -n <namespace>
На что смотреть в выводе:
- Events: Последние события (обычно в конце вывода). Ищите сообщения с префиксами
WarningилиFailed. Например:Failed to pull image,Insufficient memory,NodeAffinity. - Containers: Для каждого контейнера проверьте
Ready,State(Waiting/Running/Terminated) иLast State. ВStateбудет указана причина (Reason) и код выхода (Exit Code). - Conditions: Условия, такие как
PodScheduled,Initialized,ContainersReady. ЕслиPodScheduledимеет статусFalse, проблема в планировщике. - Volumes: Убедитесь, что тома успешно подключены (
Mounted).
Шаг 3: Проанализируйте логи контейнеров
Логи приложения — прямой источник информации о внутренних ошибках. Используйте команду logs.
# Логи стандартного (первого) контейнера в поде
kubectl logs <pod-name> -n <namespace>
# Логи конкретного контейнера в мультиконтейнерном поде
kubectl logs <pod-name> -c <container-name> -n <namespace>
# Если pod постоянно перезапускается, посмотрите логи предыдущего экземпляра
kubectl logs <pod-name> --previous -n <namespace>
# Логи за последние 10 минут (если поддерживается)
kubectl logs <pod-name> --since=10m -n <namespace>
Если вывод пустой, возможно, контейнер не запускается до стадии записи в stdout/stderr (например, падает сразу после старта). В таком случае полагайтесь на шаг 2 (события и состояние).
Шаг 4: Проверьте использование ресурсов (CPU/Memory)
Частая причина Pending или OOMKilled — нехватка вычислительных ресурсов. Сначала проверьте запросы (requests) и лимиты (limits) в манифесте пода. Затем сравните с фактическим потреблением и доступными ресурсами на нодах.
# Посмотреть запросы/лимиты ресурсов для пода (если они заданы)
kubectl describe pod <pod-name> -n <namespace> | grep -A5 -B5 "Resources"
# Проверить текущее потребление ресурсов всеми подами в namespace
kubectl top pods -n <namespace>
# Проверить доступные/используемые ресурсы на нодах
kubectl top nodes
Если pod в Pending и событие говорит 0/1 nodes are available: 1 Insufficient memory, значит, ни одна нода не имеет достаточно свободной памяти для удовлетворения requests.memory пода.
Шаг 5: Валидируйте манифест и образ контейнера
Иногда проблема лежит в самом определении пода (YAML/JSON) или в недоступности образа.
# Проверьте синтаксис манифеста перед применением (если редактировали)
kubectl apply --dry-run=client -f your-pod-manifest.yaml
# Проверьте, доступен ли образ и есть ли права на его скачивание
# (если используется приватный реестр)
kubectl get secret <secret-name> -n <namespace> -o yaml | grep -E "username|password"
# Попробуйте вручную запустить pod с другим образом (например, alpine) в том же namespace,
# чтобы проверить общую работоспособность сети и реестра
kubectl run test-pod --image=alpine --restart=Never -n <namespace> --command -- sleep 3600
Если тестовый pod с alpine запускается, а ваш — нет, проблема, скорее всего, в вашем образе или его параметрах (тег, реестр, секрет).
Шаг 6: Проверьте состояние нод и сетевое подключение
Проблемы могут быть не в поде, а в инфраструктуре.
# Проверьте статус нод (Ready, DiskPressure, MemoryPressure и т.д.)
kubectl get nodes
kubectl describe node <node-name>
# Если pod не может быть запланирован из-за толерантностей или селекторов,
# проверьте, соответствуют ли метки ноды (labels) селектору пода (nodeSelector/affinity).
# Проверьте, работают ли сетевые решения (CNI) на ноде.
# Обычно для этого нужно зайти на ноду (ssh) и проверить статус подов kube-system.
kubectl get pods -n kube-system
Проверка результата
После выполнения диагностических шагов и внесения исправлений (например, увеличения лимитов, исправления образа, изменения селектора) обновите состояние пода:
kubectl get pod <pod-name> -n <namespace> --watch
Успешный результат: Под переходит в состояние Running, и в столбце READY отображается 1/1 (или соответствующее количество контейнеров). Логи (kubectl logs) показывают нормальную работу приложения без фатальных ошибок.
Возможные проблемы
kubectlне может подключиться к кластеру: Проверьте конфигурацию (kubectl config view), переменнуюKUBECONFIGи сетевое подключение к мастер-ноде.kubectl describe podне показывает события: События автоматически удаляются через некоторое время. Попробуйте посмотреть события для всего namespace:kubectl get events -n <namespace> --sort-by='.lastTimestamp'.- Pod в
Completed: Это нормальное состояние для заданий (Jobs) или подов с контейнером, который выполнил свою задачу и завершился (например, миграция базы данных). Для долгоживущих сервисов убедитесь, что в контейнере запущен долгий процесс (например, веб-сервер). - Pod в
Terminatingвечно: Чаще всего причина —finalizersв спецификации пода или наличиеpreStopхука, который не завершается. Принудительное удаление:kubectl delete pod <pod-name> --grace-period=0 --force. - Нет доступа к логам (
Error from server: ...): Проверьте, есть ли у вашего пользователя (ServiceAccount) права на получение логов (getна ресурсеpods/log).