ImagePullBackOff en Kubernetes: causas y soluciones
ImagePullBackOff es otro de los errores clasicos en Kubernetes. Aparece cuando el nodo no puede descargar la imagen del contenedor. A diferencia del CrashLoopBackOff, aqui el problema no es la aplicacion sino la imagen en si — no existe, el nombre esta mal, o el registry requiere autenticacion. En este post te explico todas las causas y como solucionarlas.
Que significa ImagePullBackOff en Kubernetes
Cuando Kubernetes no puede descargar una imagen pasa por dos fases:
- ErrImagePull: primer intento fallido de descargar la imagen
- ImagePullBackOff: Kubernetes sigue reintentando con espera exponencial (igual que CrashLoopBackOff)
# Ver el estado del pod
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# mi-app-xyz 0/1 ImagePullBackOff 0 2m
# Ver el error exacto
kubectl describe pod mi-app-xyz
En la seccion «Events» del describe veras algo como:
Failed to pull image "mi-app:latest": rpc error: ...
- 404 Not Found
- unauthorized: authentication required
- toomanyrequests: You have reached your pull rate limit
Causa 1: El nombre de la imagen o el tag esta mal
La causa mas frecuente. Un typo en el nombre de la imagen, un tag que no existe o un digest incorrecto.
# Error tipico:
# Failed to pull image "ngnix:latest": ... not found
# (ngnix en vez de nginx)
# Verificar la imagen en el deployment
kubectl get deployment mi-app -o yaml | grep image
# Corregir la imagen
kubectl set image deployment/mi-app mi-app=nginx:1.25
# Verificar que la imagen existe en Docker Hub
# https://hub.docker.com/_/nginx/tags
Cuidado con el tag latest en produccion — si alguien sube una nueva version con ese tag, tu pod se actualizara al reiniciarse. Usa siempre tags especificos como nginx:1.25.
Causa 2: Registry privado sin credenciales
Si la imagen esta en un registry privado (Docker Hub privado, GitHub Container Registry, Google Artifact Registry, AWS ECR…) Kubernetes necesita credenciales para descargarla.
# Error tipico:
# unauthorized: authentication required
# Crear el Secret con las credenciales del registry
kubectl create secret docker-registry mi-registry-secret --docker-server=registry.ejemplo.com --docker-username=mi-usuario --docker-password=mi-password --docker-email=email@ejemplo.com
# Para Docker Hub
kubectl create secret docker-registry dockerhub-secret --docker-server=https://index.docker.io/v1/ --docker-username=mi-usuario-dockerhub --docker-password=mi-token-dockerhub
# Para GitHub Container Registry (ghcr.io)
kubectl create secret docker-registry ghcr-secret --docker-server=ghcr.io --docker-username=mi-usuario-github --docker-password=mi-token-github
Luego referencia el secret en el deployment:
spec:
containers:
- name: mi-app
image: registry.ejemplo.com/mi-app:1.0
imagePullSecrets:
- name: mi-registry-secret # el secret que creaste antes
Causa 3: Rate limit de Docker Hub
Docker Hub tiene limites de descargas para usuarios anonimos: 100 pulls cada 6 horas por IP. En un cluster con muchos nodos o muchos reinicios de pods, es facil alcanzar este limite.
# Error tipico:
# toomanyrequests: You have reached your pull rate limit.
# You may increase the limit by authenticating.
# Solucion: autenticar con Docker Hub aunque la imagen sea publica
kubectl create secret docker-registry dockerhub-auth --docker-server=https://index.docker.io/v1/ --docker-username=tu-usuario --docker-password=tu-token-o-password
Con una cuenta gratuita de Docker Hub el limite sube a 200 pulls cada 6 horas. Con una cuenta de pago es ilimitado.
Causa 4: El registry no es accesible desde el nodo
El nodo no puede llegar al registry por problemas de red, firewall o DNS.
# Verificar conectividad desde el nodo
# Acceder al nodo via SSH
ssh usuario@ip-del-nodo
# Probar que el registry es accesible
curl -v https://registry.ejemplo.com/v2/
# Verificar DNS
nslookup registry.ejemplo.com
# Si usas un registry interno, verificar que el nodo
# tiene acceso a la red interna
Causa 5: Imagen en registry con certificado SSL invalido
Si tienes un registry privado con un certificado autofirmado o expirado, el container runtime lo rechazara.
# Error tipico:
# x509: certificate signed by unknown authority
# Opcion 1: añadir el certificado al nodo
# En cada nodo, copiar el certificado CA y actualizar
sudo cp mi-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo systemctl restart containerd
# Opcion 2: configurar containerd para permitir registries inseguros
# En /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."registry.ejemplo.com".tls]
insecure_skip_verify = true
Causa 6: El Secret de imagePullSecrets esta mal configurado
# Verificar que el secret existe
kubectl get secret mi-registry-secret
# Ver el contenido del secret (en base64)
kubectl get secret mi-registry-secret -o yaml
# Decodificar para verificar las credenciales
kubectl get secret mi-registry-secret -o jsonpath='{.data..dockerconfigjson}' | base64 -d
# Verificar que el secret esta en el mismo namespace que el pod
kubectl get secret mi-registry-secret -n mi-namespace
Workflow de diagnostico para ImagePullBackOff
kubectl describe pod mi-pody leer la seccion «Events»- Si el error es not found: verificar nombre y tag de la imagen
- Si el error es unauthorized: crear imagePullSecret con las credenciales
- Si el error es toomanyrequests: autenticar con Docker Hub
- Si el error es x509: problema de certificado SSL en el registry
- Si no hay error claro: verificar conectividad del nodo al registry
Conclusion
ImagePullBackOff siempre tiene una causa concreta que aparece en el kubectl describe pod. El 80% de los casos son un typo en la imagen o credenciales que faltan. Lee el error, identifica la causa y aplica la solucion especifica.
En el proximo post veremos Helm charts: como gestionar aplicaciones en Kubernetes. Si aun tienes dudas sobre como funcionan los pods, repasa el post de Pods, Deployments y Services. Alguna causa de ImagePullBackOff que no este aqui? Dejala en los comentarios.
