Introducción
Hace unas semanas me he visto en la necesidad de empezar a trabajar con Kubernetes. Hasta ahora estaba cómodo en Docker, pero poco a poco he ido migrando servicios y probando cosas nuevas en mi servidor principal, al que cariñosamente llamo raam.
Lo curioso es que una de las primeras piezas que desplegué no fue un servicio crítico, sino un bot personal que uso para interactuar con Telegram y con algunos proyectos que tengo montados. Ese bot me sirvió como puerta de entrada al mundo Kubernetes: configurar despliegues, pods, namespaces y empezar a jugar con manifestos YAML.
Pronto me di cuenta de que si quería tomármelo en serio tenía que montar un sistema de monitorización real. Ahí entró en juego Grafana.
¿Por qué Grafana?
Grafana es, básicamente, la interfaz que da sentido a todos esos datos que Kubernetes y sus servicios generan: métricas, logs, errores de CronJobs, consumo de nodos…
Lo que me interesaba era:
- Saber si mis CronJobs se ejecutaban bien o alguno se quedaba en estado BackoffLimitExceeded.
- Detectar si algún nodo empezaba a tener problemas de CPU, RAM o disco.
- Explorar herramientas como Node Problem Detector (NPD) para anticipar fallos en el clúster.
En resumen: ver todo de un vistazo en dashboards claros.
Instalación de Grafana en Kubernetes
En Kubernetes hay varias formas de desplegar Grafana. Yo opté por el camino rápido con Helm:
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install grafana grafana/grafana --namespace monitoring --create-namespace --set adminPassword='MiPasswordSuperSecreta'
Esto me levantó un pod con Grafana accesible dentro del clúster. A partir de ahí ya podía entrar con kubectl port-forward
o exponerlo con un servicio tipo LoadBalancer
o un túnel de Cloudflare.
Conectando Grafana a Prometheus y Elasticsearch
Lo siguiente era darle fuentes de datos a Grafana:
-
Prometheus, que ya tenía desplegado como parte del stack de monitorización.
- Esto me permitió ver métricas del propio clúster (CPU, memoria, jobs, etc.).
-
Elasticsearch, que uso para centralizar logs de Wazuh y otros servicios.
- Aquí podía cruzar información de seguridad con lo que estaba ocurriendo en Kubernetes.
Con estas dos integraciones, Grafana se convierte en un auténtico centro de control.
Primer dashboard: CronJobs
Uno de mis dolores de cabeza eran los CronJobs: tareas que se lanzan automáticamente según un cron definido.
Problema: si fallaban o se quedaban en bucle, no me enteraba.
Así que monté un panel en Grafana con una consulta a Prometheus:
sum by (namespace, job) (
increase(kube_job_failed{namespace=~".*"}[1h])
)
Esto me muestra los jobs fallidos por namespace en la última hora.
También añadí un panel para los completados:
sum by (namespace, job) (
increase(kube_job_complete{namespace=~".*"}[1h])
)
De esta forma puedo ver:
- Cuántos jobs se ejecutan.
- Cuáles fallan.
- Si algún CronJob empieza a dar guerra recurrentemente.
Segundo dashboard: estado de los nodos
Los nodos son el corazón de Kubernetes. Si un nodo falla, los pods que corren en él también.
En Grafana añadí paneles para:
- Uso de CPU y memoria por nodo:
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes
- Uso de disco:
1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})
- Reinicios de kubelet o kernel oops (eventos críticos).
Esto me da una visión clara: si un nodo empieza a saturarse, lo veo al instante.
Node Problem Detector (NPD)
Investigando, encontré Node Problem Detector:
un demonset que corre en cada nodo y detecta problemas comunes:
- Kernel Oops.
- FileSystem Corruption.
- OOMKilled.
- Ficheros en read-only.
Lo mejor es que NPD expone métricas que Grafana puede recoger directamente.
Ejemplo de consulta Prometheus para errores detectados por NPD:
rate(problem_counter[5m])
Esto permite ver si, por ejemplo, un nodo está entrando en CrashLoopBackOff o si hay procesos matados por falta de memoria.
Con un panel de “Problemas recientes en nodos” puedo anticiparme a caídas serias.
Buenas prácticas que voy descubriendo
En este proceso he aprendido algunos trucos útiles:
- Variables de dashboards: para cambiar entre namespaces o jobs sin duplicar paneles.
- Alertas en Grafana: configurar alertas que avisen por Telegram/Discord cuando algo falla.
- Anotaciones: marcar en el tiempo cuándo hice un despliegue, para correlacionar errores.
- Uso de carpetas: organizar dashboards en Seguridad, Kubernetes, Logs, etc.
Un ejemplo de panel de fallos
Un panel interesante que estoy probando ahora mismo:
- Panel principal: lista de jobs fallidos con detalles de
reason
(CrashLoopBackOff, OOMKilled, etc.). - Panel lateral: nodos con mayor número de problemas detectados por NPD.
- Panel de contexto: evolución de errores en las últimas 24h.
La consulta para ver errores críticos por nodo puede ser algo así:
count by (reason, instance) (
increase(problem_counter{reason=~"KernelOops|KubeletIsDown|FilesystemCorruptionDetected|OOMKilling"}[1h])
)
Esto me muestra exactamente qué tipo de fallo ocurrió y en qué nodo.
Conclusión
Mi conclusión de estas semanas es clara: Grafana es esencial para cualquier despliegue en Kubernetes, aunque sea pequeño o personal.
- Me ayuda a detectar fallos en CronJobs que de otra forma se me escaparían.
- Puedo vigilar nodos y anticiparme a problemas de memoria, CPU o disco.
- Con Node Problem Detector llevo la observabilidad a otro nivel, identificando problemas del kernel o del sistema de archivos.
Y lo más importante: estoy aprendiendo Kubernetes a base de pegarme con casos reales. No hay mejor manera.
¿Qué viene después?
Para la próxima semana quiero escribir sobre Kubernetes en sí:
cómo empecé a organizar mis pods, namespaces, services y cómo estoy planteando la seguridad y la red.
Grafana ha sido la puerta de entrada, pero Kubernetes es un mundo entero que merece su propio post.
Stay tuned 😉