Что означает ошибка CrashLoopBackOff
Ошибка CrashLoopBackOff означает, что контейнер в поде запускается, завершается с ненулевым кодом, а Kubernetes пытается перезапустить его с нарастающей задержкой. Полный текст в статусе пода выглядит как CrashLoopBackOff (или Error), а в событиях — Back-off restarting failed container. Эта ситуация возникает в Linux-кластерах при сбоях инициализации, нехватке ресурсов или проблемах с CNI и kubelet.
Причины возникновения
- Некорректный или отсутствующий образ контейнера (ошибка
ImagePullBackOffилиErrImagePull). - Ограничения безопасности (SELinux/AppArmor), блокирующие выполнение бинарей или доступ к томам.
- Нехватка лимитов CPU/памяти на узле, из-за чего контейнер убивается (OOMKilled).
- Сбой в
livenessProbeилиstartupProbe, приводящий к принудительному завершению пода. - Проблемы с сетевым плагином (CNI), из-за которых под не может получить IP или связаться с API-сервером.
- Ошибки монтирования томов (PVC не bound, права доступа, несоответствие
fsGroup). - Неправильные переменные окружения, аргументы командной строки или точки входа (ENTRYPOINT) в Dockerfile.
Способы решения
Способ 1: Диагностика через kubectl и логи
Узнайте имя пода и пространства имён, затем проверьте его статус и события:
kubectl get pods -A | grep -E 'CrashLoopBackOff|Error'
kubectl describe pod <имя-пода> -n <namespace>
Посмотрите логи текущего и предыдущего запуска контейнера:
kubectl logs <имя-пода> -c <контейнер> -n <namespace>
kubectl logs <имя-пода> -c <контейнер> --previous -n <namespace>
Если логи пусты, возможно, контейнер не успел стартовать — обратите внимание на события (Events) в выводе describe.
Способ 2: Проверка узлов, kubelet и сети
Убедитесь, что узлы работают и kubelet активен:
kubectl get nodes
systemctl status kubelet
journalctl -u kubelet -n 50 --no-pager
Перезапустите kubelet, если в логах есть ошибки сертификатов или подключения к API:
sudo systemctl restart kubelet
Проверьте, что CNI-плагин (например, Calico или Flannel) запущен на всех узлах и пода CNI находятся в статусе Running:
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium'
Способ 3: Исправление проблем с образами и правами
Если в событиях указано Failed to pull image, убедитесь, что образ доступен и у узла есть доступ к реестру. Для приватных образов добавьте imagePullSecrets:
spec:
imagePullSecrets:
- name: regcred
Примените обновление:
kubectl apply -f <файл-манифеста>
Если контейнер падает из-за прав доступа, добавьте securityContext в манифест пода:
securityContext:
runAsUser: 1000
fsGroup: 1000
allowPrivilegeEscalation: false
Для отладки временно запустите интерактивный под с тем же образом:
kubectl run debug --image=<ваш-образ> -it --rm -- /bin/sh
Это поможет проверить, стартует ли процесс вручную и доступны ли нужные файлы.
Способ 4: Корректировка ресурсов и проб
Если под убивается по OOMKilled, увеличьте лимиты памяти:
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
Если проблема в livenessProbe, временно отключите её или увеличьте initialDelaySeconds и timeoutSeconds:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
Примените изменения и убедитесь, что под перешёл в статус Running.
Профилактика
Чтобы минимизировать появление ошибок CrashLoopBackOff и связанных с ними сбоев, соблюдайте базовые правила:
- Используйте
readinessProbeиlivenessProbeс адекватными тайм-аутами для каждого контейнера. - Устанавливайте лимиты ресурсов (CPU/память) для всех подов, чтобы избежать вытеснения и OOMKilled.
- Регулярно обновляйте CNI-плагины и kubelet до стабильных версий, совместимых с вашей версией Kubernetes.
- Проверяйте доступность образов и секретов для вытягивания (imagePullSecrets) до деплоя в production.
- Отключайте или настраивайте SELinux/AppArmor на узлах, если они блокируют выполнение приложений в контейнерах.
- Включайте структурированные логи и метрики в приложениях, чтобы быстрее локализовать причины падений через Prometheus и Grafana.