Neysi Patricia Alvarado Linares
Resumen
Cuando despliegas aplicaciones en Kubernetes, los errores son parte del día a día.
Cuando despliegas aplicaciones en Kubernetes, los errores son parte del día a día. La buena noticia es que con un puñado de comandos como kubectl describe, kubectl logs y kubectl exec puedes resolver la mayoría de fallas en clusters productivos sin volverte loco. Esta guía está pensada para personas DevOps, SRE y desarrolladores que despliegan microservicios en EKS y necesitan un flujo claro de troubleshooting Kubernetes.
A lo largo del recorrido vas a ver cuatro errores reales que aparecen una y otra vez: ImagePullBackOff, errores de configuración por secretos mal nombrados, OOMKilled por límites de recursos mal calculados y problemas de conectividad de red hacia una base de datos RDS.
¿Cómo se diagnostica un error ImagePullBackOff en Kubernetes?
El primer pod del namespace backend aparece con el estado ImagePullBackOff, una señal clásica de que el kubelet no pudo descargar la imagen del contenedor [02:10].
Para confirmarlo usas kubectl describe pod <nombre> -n backend y revisas la sección de Events. Ahí el kubelet te dice exactamente qué pasó: la imagen k8s-backend:v2 no existe en el registry, porque la única versión publicada es v1.
¿Qué significa ImagePullBackOff? Es el error que aparece cuando Kubernetes intenta descargar una imagen del registry y falla repetidamente. Suele deberse a un tag inexistente, un registry privado sin credenciales o un nombre de imagen mal escrito.
La solución es directa: editar el manifiesto YAML del backend, corregir el tag a v1 y volver a aplicar con kubectl apply -f k8s/backend.yaml -n backend.
¿Por qué siempre debo especificar el namespace al aplicar un YAML?
Un detalle fácil de pasar por alto: si no incluyes -n backend en el apply, los recursos caen en el namespace default y parece que nada cambió [05:30]. Por eso conviene ser explícito en el comando o configurar un contexto por defecto que apunte al namespace correcto.
¿Cómo soluciono un error de configuración por un secret mal referenciado?
Después de corregir la imagen, el pod cambia de estado y ahora muestra CreateContainerConfigError. Vuelves a ejecutar kubectl describe pod y los eventos te dicen que el contenedor descargó la imagen, pero al iniciar no encontró el secret mysql-secret [07:45].
Al listar los secretos con kubectl get secrets -n backend descubres que el secret existe, pero se llama mysql, sin el sufijo -secret. Es un typo en el manifiesto.
Editas el YAML, reemplazas las cuatro ocurrencias de mysql-secret por mysql, aplicas de nuevo y el pod por fin entra en estado Running. Errores así son comunes en clusters productivos y por eso muchos equipos automatizan la generación de manifiestos con herramientas como Helm o Kustomize.
¿Por qué un pod entra en CrashLoopBackOff con OOMKilled?
La aplicación responde, pero el endpoint /getmyinfo devuelve vacío y al rato el pod cae en CrashLoopBackOff. El describe revela un nuevo culpable: OOMKilled, es decir, Out of Memory Killed.
En la sección de Limits y Requests del manifiesto ves valores ridículamente bajos: 5000m de CPU y 16 MB de memoria, y además los límites son iguales a los requests, sin margen para crecer.
¿Qué es OOMKilled en Kubernetes? Es la señal que envía el sistema operativo cuando un contenedor consume más memoria de la asignada en sus limits. Kubernetes lo mata y lo reinicia, generando ciclos de CrashLoopBackOff.
La corrección consiste en darle aire al pod:
Con esos valores el pod arranca limpio y deja de reiniciarse [13:20].
¿Cómo verifico la conectividad desde un pod hacia una base de datos RDS?
El pod ya corre, pero la API sigue respondiendo vacía y los logs no muestran errores. Toca entrar al contenedor con kubectl exec -it <pod> -n backend -- sh. Como la imagen está basada en Alpine, no trae bash, así que usas sh directamente.
Dentro del pod instalas el cliente de MySQL y revisas las variables de entorno con env | grep DB para extraer DB_USER, DB_HOST y DB_NAME. Al intentar conectarte con mysql -u $DB_USER -h $DB_HOST $DB_NAME -p, la conexión se queda colgada [17:50].
¿Qué tengo que revisar en los security groups de AWS?
El problema no está en Kubernetes sino en la red de AWS. El security group de la instancia RDS solo permitía tráfico desde una IP específica, no desde el security group de los nodos del cluster EKS.
La solución pasa por editar las reglas de entrada de la base de datos:
La propagación tarda unos segundos. Al reintentar la conexión y ejecutar SELECT * FROM user_info;, los datos aparecen y la API empieza a responder con información real.
Comandos clave para hacer troubleshooting en Kubernetes
De todo el recorrido salen los comandos que conviene tener a la mano cuando algo se rompe en producción.
kubectl describe pod <nombre> -n <namespace> para leer eventos y configuración.kubectl logs <pod> -n <namespace> para ver la salida de la aplicación.kubectl exec -it <pod> -n <namespace> -- sh para entrar al contenedor y depurar desde dentro.kubectl get events -n <namespace> para ver el historial de eventos del cluster.kubectl apply -f <archivo>.yaml -n <namespace> para aplicar cambios sin olvidar el namespace.Cada error que viste tiene un patrón claro: lee los eventos, valida el manifiesto, revisa los recursos asignados y cuando todo lo demás falla, entra al pod y prueba la conectividad manualmente. ¿Cuál de estos errores te ha tocado resolver últimamente? Cuéntalo en los comentarios.
Troubleshooting en Kubernetes
Resolver problemas en Kubernetes requiere una metodología estructurada para diagnosticar fallas en aplicaciones, nodos, Pods, o configuraciones del clúster.
1. Diagnóstico Inicial
**Verifica los componentes básicos del clúster:**kubectl get nodes kubectl get pods -A kubectl get services -A
Identifica errores: Busca estados como CrashLoopBackOff, Pending, o Error en Pods:kubectl get pods -n <namespace>
2. Problemas Comunes y Soluciones
A. Pods en estado Pending
Esto ocurre cuando Kubernetes no puede programar el Pod en un nodo.
Insufficient CPU o Insufficient memory).Aumenta los recursos del clúster: Escala los nodos.kubectl scale nodepool <nodepool-name> --replicas=3
Revisa los límites del Pod: Ajusta las solicitudes de recursos (requests y limits) en el manifiesto YAML.
B. Pods en CrashLoopBackOff
Esto indica que el contenedor del Pod falla repetidamente.
**Verifica los logs del Pod:**kubectl logs <pod-name> -n <namespace>
Investiga las causas comunes:
Soluciones:
C. Servicios no accesibles
El servicio no responde o no expone correctamente el tráfico.
LoadBalancer, verifica que se haya creado en el proveedor de la nube.D. Problemas con ConfigMaps o Secrets
Errores en la configuración de aplicaciones debido a ConfigMaps o Secrets incorrectos.
**Verifica los datos:**kubectl describe configmap <configmap-name> -n <namespace> kubectl describe secret <secret-name> -n <namespace>
Soluciones:
E. Fallas en Nodos
Un nodo puede no estar listo o tener problemas de rendimiento.
**Verifica el estado de los nodos:**kubectl get nodes kubectl describe node <node-name>
Soluciones:
Si un nodo está en NotReady, revisa los logs de kubelet:journalctl -u kubelet
Escala el clúster si hay nodos saturados.
3. Herramientas Útiles
Logs
Ver logs de Pods:kubectl logs <pod-name> -n <namespace>
Ver logs de un contenedor específico:kubectl logs <pod-name> -c <container-name> -n <namespace>
Describe
Eventos del clúster
Top (Uso de recursos)
4. Soluciones Proactivas
A. Liveness y Readiness Probes
Configura pruebas de vida y disponibilidad para garantizar que los contenedores se comporten como se espera:
livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10
readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10
B. Escalabilidad
Habilita el HPA para garantizar que la aplicación escale automáticamente en función de la demanda.
C. Monitoreo
5. Comandos de Limpieza
Elimina Pods en mal estado:kubectl delete pod <pod-name> -n <namespace>
Reinstala un Deployment:kubectl rollout restart deployment <deployment-name> -n <namespace>
Limpia todos los eventos:kubectl delete events -n <namespace>
6. Flujograma de Troubleshooting
Pending, CrashLoopBackOff, etc.).Neysi Patricia Alvarado Linares
Resumen
Cuando despliegas aplicaciones en Kubernetes, los errores son parte del día a día.
José Gabriel González Pérez
Una manera de hacer que no tengas que especificar el namespace cuando creas un resource en tu cluster es definir el namespace predeterminado en la configuración de tu kubectl context:
kubectl config set-context \<context-name> --namespace=\<namespace-name>
Por defecto el namespace será default.
José Gabriel González Pérez
kubectl config set-context <context-name> --namespace=<namespace-name>
Adolfo Armas
Profe, cuales son las herramientas que permiten automatizar el proceso de creación del deployments para no generar errores?
Gracias
Yor Jaggy Castaño Pino
ProfesorHola Adolfo, que buena pregunta! Lo ideal es que tengas versionados los archivos con los que creas tus objetos dentro del cluster. De esta forma, puedes usar alguna herramienta de CI/CD para crear estos Deployments y para las siguientes ocasiones que necesites actualizarlo solo debes usar el mismo CI/CD para ejecutar un comando cambiando el imageName de tus deployment. En cuanto a que CI/CD depende de tu caso de uso. en mi actual empresa usamos Jenkins o Github Actions, pero con AzureDevOps o AWS CodeBuild, etc puede funcionar perectamente.
Guillermo Camarena Miramontes
En la clase anterior tuve problemas para conectar los nodos con los pods. El tema relacionado al agregar el sg, lo habia resuelto. Esto me tomo tiempo descubrirlo. Sugiero que antes de ver la clase anterior, se salte a este. O mencionarlo, algo.... Hay cosas que ya estan dados por hecho desde tu ambiente, que no se mencionan en los videos... Creo que por eso se nota que la gente abandono este curso....