Другое ErrImagePullВысокая

Исправляем ErrImagePull в Kubernetes: проверенные способы

Статья объясняет причины сбоя загрузки контейнерных образов в кластере Kubernetes и предлагает проверенные методы их устранения. Вы быстро восстановите работу сервисов без перезапуска нод.

Обновлено 5 апреля 2026 г.
10-15 мин
Средняя
FixPedia Team
Применимо к:Kubernetes v1.24+Containerd 1.6+Docker Container RuntimeUbuntu 22.04 / RHEL 9 ноды

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

Ошибка ErrImagePull (и её производная ImagePullBackOff) появляется, когда kubelet на узле кластера не может скачать указанный контейнерный образ из реестра. В логах вы увидите сообщение вида: Failed to pull image "registry.example.com/app:v1": rpc error: code = Unknown desc = failed to pull and unpack image.

Проблема блокирует запуск пода на этапе инициализации (PendingImagePullBackOff). Сервис остаётся недоступным, а оркестратор продолжает бесконечно ретраить операцию, постепенно увеличивая интервалы между попытками.

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

  • Опечатка в имени образа или указание несуществующего тега (реестр возвращает 404 Not Found).
  • Отсутствие авторизации для приватного реестра (403 Forbidden или 401 Unauthorized).
  • Блокировка исходящих соединений файрволом, отсутствие маршрутизации или некорректная настройка HTTP/HTTPS-прокси на нодах.
  • Сбой локального DNS-резолвера, из-за которого домен реестра не преобразуется в IP-адрес.
  • Нехватка свободного места на разделе /var/lib/containerd или /var/lib/docker. Кэширование обрывается, и загрузка отменяется.

Способы решения

Способ 1: Валидация имени и тега образа

Частая причина — человеческий фактор при редактировании манифеста. Убедитесь, что путь к репозиторию, имя образа и тег совпадают с реально опубликованной версией.

  1. Найдите проблемный под: kubectl get pods -n <namespace> | grep ErrImagePull
  2. Посмотрите текущую конфигурацию: kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[*].image}'
  3. Исправьте деплоймент: kubectl set image deployment/<name> <container-name>=registry.example.com/app:v1.2.3

💡 Совет: Всегда используйте конкретные теги или SHA-дайджесты. Тег latest усложняет отладку и может привести к загрузке нестабильной сборки.

Способ 2: Диагностика сетевых ограничений

Если образ публичный, но не грузится, проблема почти наверняка в сети узла. Kubelet использует системный стек ноды, а не сеть пода.

  1. Подключитесь к ноде по SSH: ssh user@k8s-node-01
  2. Проверьте резолв: nslookup registry.example.com
  3. Попробуйте скачать образ напрямую: crictl pull registry.example.com/app:v1.2.3
  4. Если команда падает, проверьте прокси: systemctl show docker | grep -i proxy или env | grep -i proxy

Для корпоративных сред добавьте домены реестра в noProxy конфигурации systemd для containerd.service или docker.service.

Способ 3: Настройка imagePullSecrets для приватных реестров

Без корректного секрета kubelet не сможет аутентифицироваться в Docker Hub, GitLab Registry или AWS ECR. Секрет должен создаваться в том же неймспейсе, где разворачивается приложение.

kubectl create secret docker-registry regcred \
  --docker-server=https://registry.example.com \
  --docker-username=deploy-bot \
  --docker-password=$CI_TOKEN \
  --namespace=production

Привяжите секрет к деплойменту:

spec:
  template:
    spec:
      containers:
        - name: app
          image: registry.example.com/app:v1.2.3
      imagePullSecrets:
        - name: regcred

Проверьте статус: kubectl get secret regcred -o yaml и убедитесь, что токен не истёк.

Способ 4: Очистка повреждённого кэша рантайма

Иногда частичная загрузка оставляет «битые» слои, которые блокируют повторные попытки. Рантайм не может распознать их и постоянно возвращает ошибку.

# Останавливаем проблемный под, чтобы kubelet перестал его трогать
kubectl scale deployment <name> --replicas=0

# Очищаем локальный кэш на ноде
sudo crictl rmi registry.example.com/app:v1.2.3

# Перезапускаем runtime
sudo systemctl restart containerd

После запуска снова масштабируйте деплоймент до нужного количества реплик. Загрузка начнётся с чистого листа.

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

  • Синхронизация времени: Настройте chrony или systemd-timesyncd на всех нодах. Расхождение системных часов более чем на 5 минут ломает TLS-рукопожатия с реестрами.
  • Мониторинг места на дисках: Поднимите node-exporter и алерты на NodeDiskPressure. Забитый диск — самая тихая причина отказа загрузки.
  • Ротация токенов: Для CI/CD используйте short-lived credentials и автоматизируйте обновление imagePullSecrets через External Secrets Operator или HashiCorp Vault.
  • Локальные зеркала: Для крупных кластеров настройте registry-mirror в конфигурации containerd. Это снизит нагрузку на публичные реестры и уберет сетевые таймауты.

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

Чем отличается ImagePullBackOff от ErrImagePull?
Как вручную проверить доступ к реестру с ноды?
Требуется ли перезапуск кластера после исправления?

Полезное

Диагностика статуса пода
Проверка доступа к реестру
Настройка imagePullSecrets
Очистка кэша и перезапуск

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