«Под в CrashLoopBackOff, что будешь делать?» это самый частый практический вопрос по Kubernetes. Хороший ответ показывает порядок действий, а не перечисление команд. Порядок почти всегда одинаковый: статус → события → логи → внутрь контейнера → вокруг (узел, сеть, зависимости).
Базовый набор команд
kubectl get pods -n prod -o wide # статус, рестарты, узел
kubectl describe pod api-7c9f -n prod # состояние контейнеров, причины, события
kubectl get events -n prod --sort-by=.lastTimestamp
kubectl logs api-7c9f -n prod # логи текущего контейнера
kubectl logs api-7c9f -n prod --previous # логи упавшего экземпляра
kubectl logs api-7c9f -n prod -c sidecar # конкретный контейнер
kubectl logs deploy/api -n prod --since=10m
kubectl exec -it api-7c9f -n prod -- sh
kubectl debug -it api-7c9f -n prod --image=nicolaka/netshoot --target=api
kubectl debug node/worker-2 -it --image=ubuntu
kubectl top pods -n prod
kubectl debug добавляет в под эфемерный контейнер с нужными утилитами. Это спасает, когда образ distroless и внутри нет даже shell. --target даёт доступ к процессам целевого контейнера.
Статусы и что за ними стоит
Pending
Под не назначен на узел (или ждёт томов). В describe в событиях причина от планировщика:
Insufficient cpu/Insufficient memory: requests не помещаются ни на один узел. Уменьшить requests, добавить узлы, проверить автоскейлер.didn't match Pod's node affinity/selector: nodeSelector или affinity указывают на несуществующие метки.had untolerated taint: узлы с taint, а у пода нет toleration.pod has unbound immediate PersistentVolumeClaims: PVC не привязался (нет StorageClass, нет подходящего PV, конфликт зон).- Превышена ResourceQuota namespace: тогда под даже не создаётся, ошибка видна в событиях ReplicaSet.
ContainerCreating надолго
Проблемы с томами (диск не подключается к узлу, Multi-Attach), с сетью (CNI не выдал IP), с секретом или ConfigMap, на который ссылается под (не существует).
ImagePullBackOff / ErrImagePull
Kubelet не может скачать образ:
- опечатка в имени или теге, тега не существует;
- приватный реестр без
imagePullSecretsили с неверными учётными данными; - лимиты Docker Hub на анонимные скачивания;
- образ под другую архитектуру (тогда скорее
exec format errorпри старте); - узел не видит реестр по сети или DNS.
Точный текст ошибки в событиях describe.
CrashLoopBackOff
Контейнер стартует и падает, kubelet перезапускает его с растущей паузой (10 с, 20 с, 40 с... до 5 минут). Это не причина, а симптом. Где искать:
kubectl describe pod:Last State: Terminated, Reason и Exit Code.kubectl logs --previous: логи именно упавшего экземпляра (текущий может ещё не успеть ничего написать).- Расшифровка кода выхода:
1или другой код приложения: исключение при старте, нет переменной окружения, не подключилась база, ошибка конфига.137(128 + 9, SIGKILL): OOMKilled (видно в Reason) или убит после проваленной liveness probe.143(128 + 15, SIGTERM): остановлен штатно, например при провале liveness, и успел выйти сам.126,127: не найдена или не исполняется команда изcommand/ENTRYPOINT.0приrestartPolicy: Always: процесс просто завершился, а должен работать вечно (например, демон ушёл в фон).
- Если процесс падает мгновенно и логов нет: временно заменить команду на
sleep infinity(илиkubectl debug --copy-toс другой командой) и запустить приложение руками внутри.
OOMKilled
Reason: OOMKilled, Exit Code: 137. Контейнер превысил limits.memory. Разобраться, утечка это или лимит просто мал: графики памяти до падения, kubectl top. Для JVM и Node проверить, что куча меньше лимита. Если OOM приходит от узла (нехватка памяти на узле), поды могут быть вытеснены (статус Evicted), это другой механизм.
Running, но не работает
- READY
0/1: не проходит readiness.describeпокажетReadiness probe failedс ответом. - Всё Ready, но запросы не доходят: путь Service → EndpointSlice → под (модуль про сервисы), NetworkPolicy, DNS.
- Работает, но медленно: троттлинг CPU, соседи по узлу, зависимости.
Terminating навсегда
Под завис в удалении: финализаторы на объекте, недоступный узел, том не отключается. Смотреть metadata.finalizers и состояние узла. --force --grace-period=0 удаляет объект из API, но процесс на недоступном узле может остаться жив: для StatefulSet это риск двух экземпляров.
Проблемы узла
kubectl get nodes, describe node: условия MemoryPressure, DiskPressure, PIDPressure, NetworkUnavailable. DiskPressure часто от образов и логов: kubelet начинает сборку мусора образов и вытеснение подов. На узле: journalctl -u kubelet, crictl ps, crictl logs (аналог docker-команд для CRI).
Методика в одну строку
Что видит Kubernetes (get, describe, events) → что говорит приложение (logs, --previous) → что внутри (exec, debug) → что вокруг (узел, сеть, зависимости, последние изменения: что деплоили?). И всегда спрашивать: что менялось перед началом проблемы.
Частые ошибки
- Смотреть
kubectl logsбез--previousу падающего контейнера. - Удалять под, не прочитав
describe: улика пропадает. - Путать OOMKilled (лимит контейнера) и Evicted (нехватка на узле).
- Лечить CrashLoopBackOff увеличением
initialDelaySeconds, не разобравшись в причине. - Забывать про events: они хранятся ограниченное время (по умолчанию около часа).
Что спросят на собесе
- Под в CrashLoopBackOff: порядок действий.
- Exit code 137 и 143: что значат.
- Под в Pending: какие причины и где их увидеть.
- ImagePullBackOff: что проверить.
- Как отлаживать distroless-контейнер без shell.