LinuxВысокая

CrashLoopBackOff в Kubernetes: причины и способы исправления

Статья объясняет, что означает состояние CrashLoopBackOff в Kubernetes, и предоставляет пошаговые инструкции по диагностике и исправлению проблемы с постоянными перезапусками пода.

Обновлено 17 февраля 2026 г.
10-15 мин
Средняя
FixPedia Team
Применимо к:Kubernetes 1.20+Docker, containerdkubelet

Что означает ошибка CrashLoopBackOff

CrashLoopBackOff — это состояние Kubernetes пода, когда контейнер внутри него постоянно завершается с ошибкой (exit code ≠ 0), а kubelet безуспешно пытается его перезапустить. После каждой неудачной попытки задержка перед следующим запуском экспоненциально увеличивается (10s, 20s, 40s и т.д.), что и отражено в названии состояния.

Ошибка появляется в выводе kubectl get pods:

NAME                     READY   STATUS             RESTARTS   AGE
my-app-5d89d7c8b9-xyz   0/1     CrashLoopBackOff   5          2m

Это не ошибка самого Kubernetes, а индикатор того, что контейнер не может запуститься устойчиво. Проблема всегда в конфигурации пода или в самом приложении.

Причины возникновения

  1. Ошибка в приложении — приложение падает при старте (например, из-за неверных аргументов, отсутствия переменных окружения, ошибок в коде).
  2. Нехватка ресурсов — контейнеру не хватает памяти (OOMKilled) или CPU, что приводит к аварийному завершению.
  3. Неправильная команда запуска — в манифесте пода указаны некорректные command или args, или отсутствует точка входа (ENTRYPOINT) в образе.
  4. Проблемы с образом — несуществующий тег образа, ошибка аутентификации в приватном реестре, повреждённый образ.
  5. Недоступные тома — том (PersistentVolumeClaim) не смounted, недоступен или имеет неправильные права.
  6. Недостаток прав — контейнеру не хватает прав (SecurityContext, ServiceAccount) для доступа к ресурсам (например, к порту <1024).
  7. Конфликт портов — приложение пытается слушать порт, который уже занят другим процессом в контейнере или хосте.
  8. Проблемы с инициализацией — init-контейнеры завершились с ошибкой, не предоставив необходимые ресурсы.

Способ 1: Диагностика через логи и описание пода

Первый и самый важный шаг — собрать информацию об ошибке.

  1. Узнайте имя пода:
    kubectl get pods
    

    Найдите под с статусом CrashLoopBackOff. Запишите его полное имя (например, my-app-5d89d7c8b9-xyz).
  2. Просмотрите логи предыдущего экземпляра контейнера:
    kubectl logs <pod-name> --previous
    

    Ключ --previous показывает логи контейнера, который уже завершился. Если под многоконтейнерный, укажите имя контейнера: -c <container-name>.
  3. Изучите события (Events) пода:
    kubectl describe pod <pod-name>
    

    В выводе найдите раздел Events. Частые ошибки:
    • OOMKilled — нехватка памяти.
    • Failed или ErrImagePull — проблемы с образом.
    • FailedMount — ошибка монтирования тома.
    • Exited с кодом — ошибка приложения.
  4. Если приложение выводит логи в stdout/stderr, они появятся в kubectl logs. Если логи пишутся в файл внутри контейнера, подключитесь к упавшему контейнеру (если возможно):
    kubectl exec -it <pod-name> -- /bin/sh
    

    Но при CrashLoopBackOff контейнер может быть недоступен для exec. В этом случае используйте --previous для логов или временно измените манифест, чтобы контейнер не завершался (например, запустите sleep infinity).

Способ 2: Проверка и увеличение ресурсов (память/CPU)

Частая причина — контейнеру не хватает памяти, и ядро завершает процесс (OOMKilled).

  1. В kubectl describe pod <pod-name> найдите:
    Limits:
      memory:  256Mi
    Requests:
      memory:  128Mi
    

    Если memory в Limits слишком мало (например, 128Mi) для Java-приложения или базы данных, увеличьте.
  2. Измените манифест пода (deployment/statefulset):
    spec:
      containers:
      - name: my-app
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"
          requests:
            memory: "256Mi"
            cpu: "250m"
    

    Примените изменения:
    kubectl apply -f deployment.yaml
    
  3. Если проблема в CPU, увеличьте limits.cpu и requests.cpu. Но учтите, что CPU-лимиты могут вызывать throttling, но не OOMKilled.
  4. Для диагностики можно временно убрать лимиты (не для продакшена!), чтобы проверить, исчезнет ли ошибка:
    resources:
      limits: {}
      requests: {}
    

Способ 3: Проверка команды запуска и аргументов

Если приложение требует конкретных аргументов или переменных окружения, а они не переданы, оно может упасть.

  1. Проверьте, какая команда выполняется в контейнере:
    kubectl describe pod <pod-name> | grep -A5 "Command:"
    kubectl describe pod <pod-name> | grep -A5 "Args:"
    

    Если команда или аргументы неверны, контейнер завершится сразу.
  2. Пример проблемы:
    В Dockerfile указано ENTRYPOINT ["java", "-jar", "app.jar"], а в манифесте пода переопределён command: ["python"] — это вызовет ошибку.
  3. Исправьте манифест:
    spec:
      containers:
      - name: my-app
        image: my-image:latest
        command: ["java"]          # опционально, если хотите переопределить ENTRYPOINT
        args: ["-jar", "app.jar"] # опционально, если хотите переопределить CMD
        env:
        - name: DB_HOST
          value: "postgres"
    

    Убедитесь, что команда существует в образе (проверьте Dockerfile).
  4. Если приложение зависит от переменных окружения, добавьте все необходимые в секции env. Проверьте, что нет опечаток.

Способ 4: Проверка образа и его доступности

Проблемы с образом — одна из самых частых причин CrashLoopBackOff.

  1. Проверьте, что образ существует и доступен:
    kubectl describe pod <pod-name> | grep -i "image"
    

    Ищите события ErrImagePull или ImagePullBackOff.
  2. Убедитесь, что тег образа корректен:
    • Не используйте latest в продакшене (он может меняться).
    • Проверьте, что образ есть в реестре: docker pull <image:tag> (если у вас есть доступ).
  3. Если образ в приватном реестре, убедитесь, что создан imagePullSecret:
    kubectl get secret
    

    Если секрета нет, создайте:
    kubectl create secret docker-registry regcred \
      --docker-server=<registry-server> \
      --docker-username=<username> \
      --docker-password=<password>
    

    И добавьте в под/деплоймент:
    spec:
      imagePullSecrets:
      - name: regcred
    
  4. Проверьте, что образ совместим с архитектурой нод. Например, образ для amd64 не запустится на ноде arm64.

Способ 5: Проверка томов и SecurityContext

Если контейнеру не удаётся смонтировать том или получить доступ к ресурсу из-за прав, он упадёт.

  1. Проверьте события FailedMount:
    kubectl describe pod <pod-name> | grep -A10 "Events"
    

    Ошибки типа MountVolume.SetUp или failed to mount volumes указывают на проблемы с PVC или конфигурацией тома.
  2. Убедитесь, что PVC существует и в статусе Bound:
    kubectl get pvc
    
  3. Проверьте SecurityContext:
    • Если контейнер запускается от root (UID 0), но приложение требует не-привилегированного пользователя, настройте runAsUser.
    • Если нужно слушать порт <1024, требуется CAP_NET_BIND_SERVICE:
      securityContext:
        capabilities:
          add: ["NET_BIND_SERVICE"]
      
    • Проверьте, что fsGroup установлен правильно для доступа к томам.
  4. Пример исправления для тома:
    spec:
      containers:
      - name: my-app
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: my-pvc
    

    Убедитесь, что my-pvc существует и имеет достаточный размер.

Профилактика

  1. Тестируйте образ локально перед деплоем:
    docker run --rm -it <image:tag> <command>
    

    Убедитесь, что контейнер запускается и не падает.
  2. Указывайте явные команды и аргументы в манифесте, даже если они совпадают с Dockerfile. Это исключит неявные зависимости.
  3. Настройвайте разумные лимиты ресурсов на основе мониторинга (например, через kubectl top pod). Начинайте с запасом 20-30%.
  4. Используйте readiness/liveness probes — они не предотвратят CrashLoopBackOff, но помогут отличить проблемы запуска от проблем работоспособности.
  5. Включайте логирование в stdout/stderr и собирайте их через DaemonSet (Fluentd, Filebeat) — это упростит диагностику.
  6. Проверяйте манифесты через kubectl apply --dry-run=client перед применением.
  7. Для критичных приложений рассмотрите использование restartPolicy: OnFailure (для Job) или настройку backoffLimit в Job, чтобы ограничить число перезапусков.

💡 Совет: Если приложение падает только в Kubernetes, но работает локально, сравнивайте окружение: переменные, тома, сеть, архитектуру ноды. Часто проблема в различиях между Docker run и Kubernetes pod.

Часто задаваемые вопросы

Что означает CrashLoopBackOff в Kubernetes?
Как посмотреть логи пода в CrashLoopBackOff?
Можно ли отключить автоматические перезапуски при CrashLoopBackOff?
Частые причины CrashLoopBackOff в Kubernetes?

Полезное

Получите имя пода и проверьте его статус
Просмотрите логи контейнера
Проанализируйте описание пода
Проверьте ресурсы и команды запуска
Увеличьте ресурсы или исправьте конфигурацию

Эта статья помогла вам решить проблему?