La mayoría de los incidentes de Kubernetes no son exóticos. Un puñado de fallos concentra casi todos los tickets de “mi pod no arranca”, y cada uno tiene una firma reconocible y un fix conocido. Esta guía recorre los errores que vas a encontrar de verdad, cómo leerlos con kubectl, y cómo resolverlos.
Para todos los errores de abajo el bucle de diagnóstico es el mismo: mira el estado del pod, luego sus eventos, luego sus logs. Ten estos tres a mano:
kubectl get pods -n <namespace>
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --previous
CrashLoopBackOff
El más famoso. CrashLoopBackOff no significa que Kubernetes esté roto: significa que tu contenedor arranca, sale, y Kubernetes espera cada vez más antes de reiniciarlo (el retardo crece hasta cinco minutos).
Diagnóstico. La razón de salida está en los logs de la ejecución anterior, no en la actual:
kubectl logs <pod> -n <namespace> --previous
kubectl describe pod <pod> -n <namespace> # mira Last State + Exit Code
Causas comunes y fixes.
- Error de la aplicación al arrancar: una variable de entorno ausente, una base de datos inalcanzable, una migración mala. Los logs casi siempre dicen cuál. Corrige la config o la dependencia.
- Liveness probe que falla: si la probe falla, el kubelet mata el contenedor y entra en bucle. Ve la sección de probes más abajo.
- Exit code 137: eso es un OOM kill, lo vemos a continuación.
- command/args mal configurados: el entrypoint sale de inmediato. Verifica
commandyargsen el spec.
ImagePullBackOff y ErrImagePull
El contenedor ni siquiera arranca porque el cluster no puede descargar la imagen.
Diagnóstico.
kubectl describe pod <pod> -n <namespace> # lee los Events al final
El mensaje del evento es específico: not found, unauthorized o manifest unknown.
Causas comunes y fixes.
- Typo en el nombre o el tag de la imagen:
myapp:lateset. Corrige el tag. - Registro privado sin credenciales: crea un
imagePullSecrety referéncialo en el spec del pod (o en el service account). - El tag no existe: el build nunca se publicó, o estás fijando un tag borrado. Publícalo o fija un digest.
- Rate limiting (Docker Hub): autentícate o usa un mirror de la imagen.
OOMKilled
Tu contenedor pidió más memoria de la que permitía su limit, así que el kernel lo mató. Verás OOMKilled y exit code 137.
Diagnóstico.
kubectl describe pod <pod> -n <namespace> # Last State: Terminated, Reason: OOMKilled
kubectl top pod <pod> -n <namespace> # uso en vivo vs limits
Fixes.
- Sube el limit de memoria si el workload de verdad necesita más.
- Arregla la fuga si el uso sube sin parar: un limit solo retrasa lo inevitable.
- Pon los requests cerca del uso real para que el scheduler coloque el pod en un nodo que sí lo aguante.
Una regla útil: pon el request en el working set estable y el limit en el pico que puedas tolerar. Limits muy por encima de los requests invitan a evictions por vecino ruidoso.
Pods atascados en Pending
Un pod en Pending no se ha programado en ningún nodo. El scheduler te dice por qué en los eventos.
Diagnóstico.
kubectl describe pod <pod> -n <namespace> # el evento FailedScheduling lo explica
Causas comunes y fixes.
- CPU/memoria insuficiente: ningún nodo tiene espacio para los requests del pod. Escala el cluster, baja los requests o libera capacidad.
- Affinity / selectors / taints imposibles: el pod exige un nodo que no existe o que no lo tolera. Corrige el
nodeSelector, las reglas de affinity o añade una toleration. - PersistentVolumeClaim sin enlazar: el pod espera por almacenamiento. Revisa el PVC (a continuación).
PVC atascado en Pending
Un PersistentVolumeClaim que nunca se enlaza bloquea a todos los pods que lo montan.
kubectl get pvc -n <namespace>
kubectl describe pvc <claim> -n <namespace>
Normalmente es un StorageClass ausente o que no coincide, o ningún provisioner capaz de satisfacer la petición. Apunta el claim a un StorageClass válido, o provisiona un PersistentVolume que encaje.
CreateContainerConfigError: falta un ConfigMap o Secret
El pod se admite pero el contenedor nunca arranca, porque referencia un ConfigMap o un Secret que no existe. El kubelet reporta CreateContainerConfigError con un mensaje del tipo configmap "app-config" not found.
kubectl describe pod <pod> -n <namespace> # razón Waiting + qué objeto falta
Esto no es un crash loop: el proceso nunca corre. El fix siempre es (re)crear la dependencia que falta, no tocar el workload. Aplica el ConfigMap/Secret y el contenedor arranca en el siguiente reconcile.
Readiness y liveness probes que fallan
Las probes son cómo Kubernetes sabe si tu contenedor está vivo y listo para servir. Fallan de forma distinta:
- Readiness probe que falla: el contenedor corre pero la condición
Readyse queda enFalse, así que el Service lo deja fuera de rotación. Síntoma: “corre pero no sirve tráfico”. Revisa el endpoint, el path y los tiempos. Un arranque lento necesita unstartupProbeo uninitialDelaySecondsmayor. - Liveness probe que falla: el kubelet decide que el contenedor está enfermo y lo reinicia, lo que puede disfrazarse de crash loop. Si la app solo tarda en calentar, tu liveness probe es demasiado agresiva.
kubectl describe pod <pod> -n <namespace> # eventos "Liveness/Readiness probe failed"
Ajusta la probe al comportamiento real de la app: un initialDelaySeconds realista, un startupProbe para arranques lentos, y un endpoint de probe que refleje salud genuina y no un 200 de un handler estático.
Del síntoma al fix, automáticamente
Cada error de arriba tiene una firma determinista: un estado, una razón, un umbral. Eso es justo lo que un verificador automático hace bien. El Insights Engine de KubeBolt trae 24 reglas integradas que vigilan estos patrones de forma continua (CrashLoopBackOff, OOMKilled, ImagePullBackOff, Pending, config ausente, fallos de probes y más) y convierten cada uno en una recomendación en lenguaje claro, sin PromQL ni dashboards que cablear.
Cuando quieras actuar sobre un hallazgo, Kobi propone el fix exacto y puede ejecutarlo con tu aprobación (reiniciar, escalar, hacer rollback, cambiar la imagen) bajo RBAC y con un audit trail completo. Pasas de “CrashLoopBackOff” a un incidente resuelto sin salir del dashboard.
¿Quieres probarlo en tu propio cluster? Se instala en menos de dos minutos.