Как узнать причину краша (crashloop) пода в Kubernetes?

«Как узнать причину краша (crashloop) пода в Kubernetes?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Когда под попадает в состояние CrashLoopBackOff, это означает, что контейнер внутри него постоянно запускается и падает. Моя последовательность действий для диагностики:

1. Анализ логов — самый важный шаг:

# Смотрю логи последнего запуска контейнера
kubectl logs <pod-name> -n <namespace>
# Если контейнер падает слишком быстро, смотрю логи предыдущей попытки
kubectl logs <pod-name> --previous -n <namespace>
# Для пода с несколькими контейнерами указываю нужный
kubectl logs <pod-name> -c <container-name> -n <namespace>

В логах ищу ошибки инициализации, исключения (Java Exception, Python Traceback), сообщения о невозможности подключиться к БД, отсутствии файлов конфигурации или секретов.

2. Проверка событий и состояния пода:

kubectl describe pod <pod-name> -n <namespace>

В выводе смотрю на:

  • Секцию Events внизу: Часто там есть понятные сообщения — "Failed to pull image", "Secret not found", "Container failed to start".
  • Состояния контейнеров (Containers): Last State и Reason (например, Error, CrashLoopBackOff).
  • Условия пода (Conditions): Проверяю Ready и ContainersReady.

3. Проверка манифестов пода: Смотрю, правильно ли заданы критичные параметры:

kubectl get pod <pod-name> -n <namespace> -o yaml

Проверяю:

  • Команду запуска (command, args): Нет ли опечаток.
  • Точки монтирования (volumeMounts): Существуют ли соответствующие PersistentVolumeClaims или ConfigMaps.
  • Переменные окружения (env, envFrom): Все ли секреты (Secrets) и конфигурации (ConfigMaps) существуют и доступны.
  • Лимиты ресурсов (resources.limits): Не слишком ли они низкие для запуска приложения.

4. Запуск отладочного пода для интерактивного исследования: Если логи не дают ответа, запускаю под с таким же образом, но интерактивно, чтобы проверить окружение.

kubectl run -it debug-pod --image=<problematic-image> --restart=Never --rm -- /bin/sh

Внутри проверяю:

  • Наличие и корректность файлов конфигурации: ls -la /etc/config/
  • Переменные окружения: env | grep DB_
  • Могу ли я подключиться к зависимостям: nc -zv db-host 5432
  • Запускаю команду приложения вручную, чтобы увидеть ошибку.

5. Проверка зависимостей пода: Убеждаюсь, что работают сервисы, от которых зависит под:

  • Базы данных, очереди сообщений (проверяю из другого пода).
  • ConfigMaps и Secrets ( kubectl get configmap,secret -n <namespace>).

6. Анализ дампа памяти (если применимо): Для нативных приложений (C/C++, Go) настраиваю в манифесте пода создание core dump и анализирую его позже с помощью gdb.

Типичные причины, которые я чаще всего нахожу: ошибки в конфигурационных файлах, отсутствующие секреты, неверные права доступа к томам, недостаток памяти (OOMKilled) или ошибки в коде приложения, которые видны только при конкретных условиях инициализации в K8s.