Inicio » Cómo solucionar el estado CrashLoopBackOff en Pods de Kubernetes
Sistemas y Servidores

Cómo solucionar el estado CrashLoopBackOff en Pods de Kubernetes

El Diagnóstico Rápido

El estado CrashLoopBackOff en Kubernetes indica que un contenedor dentro de un Pod falla al iniciarse, se interrumpe inmediatamente y entra en un ciclo continuo de reinicios automáticos donde Kubernetes incrementa de forma exponencial el tiempo de espera entre intentos.

🔍 El Diagnóstico Rápido

Síntoma Causa Raíz Solución
Pod en estado CrashLoopBackOff con incremento constante en la cuenta de RESTARTS Error en la aplicación (código), falta de variables de entorno, falta de memoria (OOMKilled) o fallos en livenessProbe Inspeccionar los logs con kubectl logs --previous y revisar eventos del sistema con kubectl describe pod

🚀 Cómo solucionar el error paso a paso

Paso 1: Inspeccionar la razón del fallo con kubectl describe

El primer comando para obtener contexto detallado sobre el ciclo de vida del Pod es kubectl describe:

BASH
# Obtener el estado detallado del Pod afectado
kubectl describe pod <nombre-del-pod> -n <namespace>

En la sección Containers > State y Last State, presta especial atención a los siguientes indicadores:

  • Exit Code 1 o 127: Error de aplicación (código defectuoso, comando CMD no encontrado o archivo faltante).
  • Exit Code 137 (OOMKilled): El contenedor superó el límite estricto de memoria (limits.memory) asignado en el manifiesto YAML.
  • Liveness probe failed: Las pruebas de salud configuradas no responden dentro del tiempo límite establecido.

Paso 2: Extraer los registros del contenedor (Logs)

Para ver la salida estándar (stdout/stderr) del contenedor antes de que fallara en el intento anterior, añade la bandera --previous:

BASH
# Leer los registros de la instancia anterior del contenedor
kubectl logs <nombre-del-pod> --previous -n <namespace>

# Si el Pod contiene múltiples contenedores, especifica el nombre del contenedor:
kubectl logs <nombre-del-pod> -c <nombre-del-contenedor> --previous -n <namespace>

Paso 3: Corregir límites de recursos de memoria (OOMKilled)

Si el contenedor fue terminado por consumir más memoria de la permitida (código 137), edita tu deployment para ajustar los recursos:

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mi-servicio
spec:
  template:
    spec:
      containers:
      - name: mi-app
        image: mi-imagen:latest
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi" # Incrementar si se detecta OOMKilled
            cpu: "500m"

Aplica la actualización con:

BASH
kubectl apply -f deployment.yaml

Paso 4: Ajustar o postergar los Liveness y Readiness Probes

Si el servicio tarda más tiempo en inicializarse (por ejemplo, al ejecutar migraciones de base de datos), el livenessProbe puede matar el Pod prematuramente. Aumenta el parámetro initialDelaySeconds:

YAML
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30 # Dar tiempo a que el servicio complete el arranque
  periodSeconds: 10
  failureThreshold: 3

Consejo de Prevención

Prácticas de seguridad recomendadas:

  • Probar contenedores localmente: Ejecuta la imagen de Docker localmente con docker run -it --rm <imagen> pasando las mismas variables de entorno para confirmar que el comando de inicio (entrypoint) funciona sin problemas.
  • Configurar initialDelaySeconds con margen suficiente: Servicios Java o aplicaciones con cargas pesadas de inicio requieren tiempos de espera iniciales superiores a 30-60 segundos.
  • Usar ConfigMaps y Secrets validados: Verifica que todas las variables requeridas por el software estén declaradas adecuadamente antes de desplegar.