Durante meses my “sistema de logs” era SSH al servidor, docker logs nombre-del-container y rezar para encontrar el error antes de perder la paciencia. Cuando algo fallaba a las 3 de la mañana y me despertaba una alerta, el proceso era: conectarme, buscar en logs, no encontrar nada relevante porque el container había reiniciado y los logs anteriores habían desaparecido, rendirse.
Loki lo cambió. No es el sistema de logs más potente del mercado, pero para un homelab es perfecto: consume poco, se integra directamente con Grafana y funciona bien con Kubernetes desde el primer día.
Por qué Loki y no Elasticsearch#
La respuesta corta es la memoria RAM. Un stack ELK (Elasticsearch, Logstash, Kibana) mínimamente funcional necesita 4-8 GB de RAM solo para Elasticsearch. En un homelab donde los recursos son finitos, eso es demasiado.
Loki funciona diferente. En lugar de indexar el contenido completo de cada línea de log, solo indexa los metadatos (a qué pod pertenece, en qué namespace está, qué nodo lo generó). El contenido de los logs se almacena comprimido y se busca con grep cuando consultas. Esto lo hace mucho más ligero: mi instalación completa de Loki + Promtail consume menos de 500MB de RAM en el cluster.
La contrapartida es que las búsquedas son más lentas cuando tienes que buscar en el contenido del log, y que no puedes hacer las queries complejas de Elasticsearch. Para un homelab no me parece un problema: la mayoría de veces busco logs de un servicio concreto en una ventana de tiempo razonable.
Si ya tienes Grafana corriendo (como vimos en el post de monitorización con Prometheus), añadir Loki es relativamente sencillo porque Grafana lo soporta como datasource nativo.
Arquitectura del stack#
El stack tiene tres componentes:
Loki es el servidor central. Recibe los logs, los almacena y responde a las queries. Lo despliego en K3s con almacenamiento en un PVC de Longhorn.
Promtail es el agente de recolección. Corre en cada nodo del cluster como DaemonSet y lee los logs de todos los containers, añadiendo las etiquetas de Kubernetes (namespace, pod, container, nodo). Los envía a Loki.
Grafana ya lo tenía. Solo añado Loki como datasource y ya puedo hacer queries con LogQL desde los dashboards existentes.
Instalar Loki#
Uso el chart de Helm de Grafana. Primero añade el repo:
| |
Crea el namespace:
| |
Prepara el values.yaml para Loki. Esta es una configuración básica pero funcional:
| |
Instala con Helm:
| |
Verifica que el pod está corriendo:
| |
Puede tardar 2-3 minutos en arrancar la primera vez mientras Longhorn provisiona el PVC.
Instalar Promtail#
Promtail es el agente que recoge los logs de cada nodo. Va como DaemonSet, o sea que correrá automáticamente en cada nodo del cluster.
| |
Instala:
| |
Promtail desplegará un pod en cada nodo. Verifica:
| |
Añadir Loki como datasource en Grafana#
En Grafana, ve a Connections > Data sources > Add data source > Loki.
La URL del datasource es el servicio de Loki dentro del cluster:
| |
Guarda y verifica la conexión. Si aparece “Data source connected and labels found”, todo está funcionando.
Si tienes Grafana fuera del cluster, necesitas exponer el servicio de Loki o usar un port-forward temporal para configurarlo.
Primeras queries con LogQL#
LogQL es el lenguaje de queries de Loki. Se parece a PromQL pero para logs. La sintaxis básica es:
# Todos los logs de un namespace
{namespace="produccion"}
# Logs de un container específico
{namespace="monitoring", container="loki"}
# Filtrar por contenido (grep en logs)
{namespace="default"} |= "error"
# Filtrar por contenido excluyendo
{namespace="default"} != "health check"
# Parsear JSON y filtrar por campo
{namespace="api"} | json | level="error"
# Contar errores por pod en los últimos 5 minutos
count_over_time({namespace="default"} |= "error" [5m])En Grafana, la forma más fácil de explorar los logs es usando Explore (el icono de la brújula en el menú lateral). Selecciona Loki como datasource y empieza a construir queries.
Los labels disponibles dependen de lo que etiquete Promtail. Por defecto tienes namespace, pod, container, node y stream (stdout o stderr). Con estos labels puedes filtrar cualquier combinación de servicios.
Dashboard de logs del cluster#
No hay un dashboard de “logs del cluster” como tal, porque los logs son muy específicos de cada setup. Lo que yo hice fue crear paneles en mi dashboard de homelab existente para los servicios que más me importan.
Por ejemplo, un panel que muestra los últimos 50 errores de cualquier namespace en las últimas 6 horas:
{namespace=~".+"} |= "error" | json | line_format "{{.namespace}}/{{.pod}}: {{.message}}"Y otro que muestra los reinicios de containers (cuando un container crashea, Kubernetes lo reinicia y el log incluye un mensaje específico):
{namespace=~".+"} |= "Back-off restarting failed container"Estos dos paneles me dan visibilidad inmediata cuando algo está mal en el cluster sin tener que buscar manualmente.
Alertas basadas en logs#
La integración más útil de Loki con Grafana es las alertas. Puedes crear alertas que se disparan cuando aparece un patrón específico en los logs.
Para configurar alertas en Grafana basadas en Loki, necesitas Grafana Alerting activado (viene por defecto en versiones recientes).
Ejemplo: alerta cuando hay más de 10 errores en un namespace en 5 minutos:
count_over_time({namespace="produccion"} |= "error" [5m]) > 10En Grafana, crea la alerta desde Alerting > Alert rules > New alert rule. Selecciona Loki como datasource, introduce la query y configura el umbral y el tiempo de evaluación.
Las alertas pueden enviarse a cualquier canal que Grafana soporte: Telegram, Email, Slack, PagerDuty… Yo las tengo configuradas para Telegram, que es donde ya recibo el resto de notificaciones del homelab.
Retención de logs#
Por defecto Loki guarda los logs indefinidamente hasta que te quedas sin espacio. Para un homelab con espacio limitado, configura la retención.
En el values.yaml de Loki, añade:
| |
Haz un upgrade del release de Helm con los nuevos valores:
| |
Con 31 días de retención y los logs comprimidos, el PVC de 20GB me dura con holgura en mi cluster. Si tienes servicios muy verbosos, puede que necesites aumentar el tamaño o reducir la retención.
Consumo real de recursos#
Después de dos meses con Loki en producción en mi cluster:
- Loki consume ~300-400MB de RAM y menos del 2% de CPU en idle
- Promtail en cada nodo consume ~50-80MB de RAM
- Con 14 nodos, el total de Promtail es ~700MB-1GB de RAM entre todos los nodos
- El PVC crece a razón de ~1-2GB por semana con los logs comprimidos
- Las queries habituales responden en menos de 2 segundos
No es el stack de observabilidad de una empresa grande, pero para un homelab es más que suficiente. La diferencia entre tener logs centralizados y no tenerlos es enorme cuando algo falla.
Casos de uso reales#
Desde que tengo Loki, he resuelto problemas que antes me llevaban horas:
Un día Mealie dejó de responder. Con el sistema anterior, habría tenido que SSH al nodo donde estaba corriendo y buscar en los logs del container. Con Loki, en 30 segundos tenía la query {namespace="mealie"} y veía claramente que había un error de conexión a la base de datos a las 3:42 AM, que coincidía con el momento en que Watchtower actualizó el container de MariaDB. El container nuevo tardó más en arrancar de lo esperado, y el de Mealie intentó conectarse antes de que la base de datos estuviera lista.
Otro caso: noté que uno de los nodos de Longhorn estaba generando errores periódicos. Con {namespace="longhorn-system"} |= "error" encontré que había un problema de conectividad entre dos réplicas. Sin logs centralizados, probablemente no me habría enterado hasta que fallara algo más grande.
El tiempo que me ahorra Loki cuando tengo que debuggear ya justificó la hora que me llevó instalarlo.