Lab 04: Prometheus + Grafana – El Stack Open Source Esencial

Objetivo del Lab

Montar un stack completo de monitoreo open source usando Docker Compose para aprender los conceptos fundamentales de observabilidad: recolección de métricas, visualización y alertas.

Tiempo estimado: 30-45 minutos
Dificultad: Intermedia
Infraestructura: Ubuntu Server en VirtualBox


¿Qué vas a aprender?

Al finalizar este lab sabrás:

  • ✅ Configurar Prometheus para recolectar métricas del sistema
  • ✅ Crear dashboards profesionales en Grafana
  • ✅ Configurar alertas basadas en métricas (CPU, RAM, disco)
  • ✅ Entender la arquitectura del stack de monitoreo moderno
  • ✅ Generar y visualizar alertas en tiempo real

Arquitectura del Stack

Componentes:

  1. Prometheus: Motor de métricas que recolecta y almacena datos
  2. Grafana: Interfaz de visualización para crear dashboards
  3. Node Exporter: Exporta métricas del sistema (CPU, RAM, disco, red)
  4. Alertmanager: Gestiona y enruta las alertas

📋 Requisitos Previos

Hardware Mínimo

  • RAM: 2GB (4GB recomendado)
  • CPU: 2 cores
  • Disco: 10GB libres

Software Necesario

  • Ubuntu Server 22.04 o 24.04 en VirtualBox
  • Docker y Docker Compose instalados
  • Acceso SSH a la VM

🌐 Configuración de Red en VirtualBox

Para acceder a Grafana desde tu navegador, configura la red de tu VM:

Opción 1 – Adaptador Puente (Recomendado si funciona en tu red):

  1. VirtualBox → Configuración de tu VM → Red → Adaptador 1
  2. «Conectado a:» → Selecciona Adaptador puente
  3. Inicia la VM
  4. Dentro de la VM, obtén la IP: hostname -I
  5. Desde tu navegador: http://IP_DE_LA_VM:3000

Opción 2 – NAT con Port Forwarding (Siempre funciona):

  1. VirtualBox → Configuración de tu VM → Red → Adaptador 1 → NAT
  2. Clic en AvanzadasReenvío de puertos
  3. Añade esta regla (botón +):
  • Nombre: Grafana
  • Protocolo: TCP
  • Puerto anfitrión: 3000
  • Puerto invitado: 3000
  1. Desde tu navegador: http://localhost:3000

💡 Nota: Solo necesitas el puerto 3000 (Grafana). Los demás servicios (Prometheus, Alertmanager) se acceden desde Grafana.

Opcional: Si quieres acceder directamente a Prometheus (9090) o Alertmanager (9093), añade esos puertos también.

Verificar instalación de Docker:

# Verificar Docker
docker --version

# Verificar Docker Compose
docker-compose --version

Si no tienes Docker instalado:

# Instalar Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

# Instalar Docker Compose (si no está incluido)
sudo apt update
sudo apt install docker-compose -y

# Verificar instalación
docker --version
docker-compose --version

# Reiniciar sesión para aplicar permisos de grupo
exit

🚀 Paso a Paso

Paso 1: Preparar el Entorno

Crear estructura de directorios:

# Crear directorio del proyecto
mkdir -p ~/prometheus-stack
cd ~/prometheus-stack

# Crear subdirectorios para configuraciones
mkdir -p prometheus grafana alertmanager

Paso 2: Configurar Prometheus

Crear archivo de configuración de Prometheus:

nano prometheus/prometheus.yml

Copiar este contenido:

# Configuración global de Prometheus
global:
  scrape_interval: 15s      # Frecuencia de recolección de métricas
  evaluation_interval: 15s  # Frecuencia de evaluación de reglas

# Configuración de Alertmanager
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

# Archivos de reglas de alertas
rule_files:
  - /etc/prometheus/alert.rules.yml

# Configuración de scrape (qué métricas recolectar)
scrape_configs:
  # Métricas del propio Prometheus
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Métricas del sistema (Node Exporter)
  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']

Paso 3: Crear Reglas de Alertas

Crear archivo de reglas:

nano prometheus/alert.rules.yml

Copiar este contenido:

groups:
  - name: system_alerts
    interval: 10s
    rules:
      # Alerta: CPU alta
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[2m])) * 100) > 70
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "CPU usage is above 70%"
          description: "CPU usage on {{ $labels.instance }} is {{ $value }}%"

      # Alerta: Memoria alta
      - alert: HighMemoryUsage
        expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 80
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Memory usage is above 80%"
          description: "Memory usage on {{ $labels.instance }} is {{ $value }}%"

      # Alerta: Disco alto
      - alert: HighDiskUsage
        expr: (node_filesystem_size_bytes{fstype!="tmpfs"} - node_filesystem_free_bytes{fstype!="tmpfs"}) / node_filesystem_size_bytes{fstype!="tmpfs"} * 100 > 85
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Disk usage is above 85%"
          description: "Disk usage on {{ $labels.instance }} mountpoint {{ $labels.mountpoint }} is {{ $value }}%"

      # Alerta: Servicio caído
      - alert: ServiceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Service is down"
          description: "Service {{ $labels.job }} on {{ $labels.instance }} is down"

Paso 4: Configurar Alertmanager

Crear configuración de Alertmanager:

nano alertmanager/alertmanager.yml

Copiar este contenido:

# Configuración global
global:
  resolve_timeout: 5m

# Rutas de alertas
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 12h
  receiver: 'default'

# Receptores (dónde enviar las alertas)
receivers:
  - name: 'default'
    # Por ahora solo log, puedes añadir webhook, email, Slack, etc.

# Inhibición de alertas (evitar spam)
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'cluster', 'service']

Paso 5: Crear Docker Compose

Crear el archivo principal:

nano docker-compose.yml

Copiar este contenido:

version: '3.8'

services:
  # Prometheus - Motor de métricas
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus/alert.rules.yml:/etc/prometheus/alert.rules.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
    networks:
      - monitoring

  # Node Exporter - Métricas del sistema
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    command:
      - '--path.rootfs=/host'
    volumes:
      - /:/host:ro,rslave
    networks:
      - monitoring

  # Grafana - Visualización
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana-data:/var/lib/grafana
    networks:
      - monitoring
    depends_on:
      - prometheus

  # Alertmanager - Gestión de alertas
  alertmanager:
    image: prom/alertmanager:latest
    container_name: alertmanager
    restart: unless-stopped
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
      - alertmanager-data:/alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

volumes:
  prometheus-data:
  grafana-data:
  alertmanager-data:

Paso 6: Levantar el Stack

# Verificar que los archivos están correctos
ls -la prometheus/
ls -la alertmanager/
cat docker-compose.yml

# Levantar los contenedores
docker-compose up -d

# Verificar que todo está corriendo
docker-compose ps

# Ver logs en tiempo real (Ctrl+C para salir)
docker-compose logs -f

Salida esperada:

NAME            IMAGE                           STATUS
prometheus      prom/prometheus:latest          Up
node-exporter   prom/node-exporter:latest       Up
grafana         grafana/grafana:latest          Up
alertmanager    prom/alertmanager:latest        Up

Paso 7: Verificar Acceso Web

Acceder a Grafana desde tu navegador:

  • Si usas Adaptador Puente: http://IP_DE_LA_VM:3000
  • (Para saber tu IP, ejecuta en la VM: hostname -I)
  • Si usas NAT: http://localhost:3000

Credenciales por defecto:

  • Usuario: admin
  • Password: admin

💡 Todo el lab se hace desde Grafana. Los demás servicios (Prometheus, Alertmanager) se acceden internamente.

Para curiosos: Si quieres ver las UIs de otros servicios:

  • Prometheus: puerto 9090
  • Alertmanager: puerto 9093
  • Node Exporter (métricas raw): puerto 9100

Paso 8: Configurar Grafana

8.1 Primer login

  • URL: http://TU_IP:3000
  • Usuario: admin
  • Password: admin
  • Te pedirá cambiar la contraseña (puedes usar admin123 para el lab)

8.2 Añadir Prometheus como Data Source

  1. Click en (menú) → ConnectionsData sources
  2. Click Add data source
  3. Seleccionar Prometheus
  4. Configurar:
  • Name: Prometheus
  • URL: http://prometheus:9090
  • Dejar el resto por defecto
  1. Click Save & test → Debe salir «Data source is working»

8.3 Importar Dashboard pre-hecho

  1. Click en DashboardsImport
  2. En Import via grafana.com: escribir 1860
  3. Click Load
  4. Configurar:
  • Name: Node Exporter Full
  • Prometheus: Seleccionar «Prometheus» (el que acabas de crear)
  1. Click Import

¡BOOM! 💥 Ya tienes un dashboard profesional con métricas en tiempo real


Paso 9: Probar las Alertas

9.1 Verificar que las reglas están cargadas

Desde Grafana (recomendado):

  1. Ir a Grafana → 🔔 AlertingAlert rules
  2. Deberías ver las 4 reglas configuradas

Alternativamente desde Prometheus:

  1. Si configuraste el puerto 9090, ir a http://TU_IP:9090 (o localhost:9090)
  2. Click en StatusRules

9.2 Generar carga de CPU para disparar alerta

# Instalar stress (si no lo tienes)
sudo apt update && sudo apt install -y stress

# Generar carga de CPU al 100% durante 3 minutos
stress --cpu 4 --timeout 180s

# Alternativa sin instalar nada:
dd if=/dev/zero of=/dev/null &
dd if=/dev/zero of=/dev/null &
dd if=/dev/zero of=/dev/null &
# Esperar 2-3 minutos y luego matar los procesos:
# killall dd

9.3 Ver la alerta activarse

En Grafana (principal):

  1. Ir al dashboard Node Exporter Full
  2. Ver el gráfico de CPU subir en tiempo real
  3. Click en 🔔 AlertingAlert rules
  4. Esperar 2 minutos (el for: 2m de la regla)
  5. Ver HighCPUUsage cambiar: InactivePendingFiring 🔥

Opcional – En Prometheus:

  • Si configuraste el puerto, ir a http://TU_IP:9090/alerts (o localhost:9090/alerts)
  • Ver la alerta cambiar de estado

Opcional – En Alertmanager:

  • Si configuraste el puerto, ir a http://TU_IP:9093 (o localhost:9093)
  • Ver la alerta listada

Paso 10: Crear tu Propio Dashboard Simple

  1. En Grafana: DashboardsNewNew Dashboard
  2. Click Add visualization
  3. Seleccionar Prometheus como data source
  4. En la query escribir:
   100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
  1. En el panel de la derecha:
  • Title: CPU Usage %
  • Unit: Percent (0-100)
  1. Click Apply
  2. Save dashboard (icono 💾) → Nombre: «Mi Dashboard»

¡Felicidades! Acabas de crear tu primer panel personalizado


🧪 Pruebas Funcionales

✅ Checklist de Validación

Ejecuta estas pruebas para confirmar que todo funciona:

# 1. Verificar que todos los contenedores están corriendo
docker-compose ps
# Todos deben estar "Up"

# 2. Verificar que Prometheus recolecta métricas
curl -s http://localhost:9090/api/v1/targets | grep -o '"health":"[^"]*"'
# Debe mostrar: "health":"up"

# 3. Verificar que Node Exporter expone métricas
curl -s http://localhost:9100/metrics | grep node_cpu
# Debe mostrar líneas con métricas de CPU

# 4. Verificar reglas de alertas
curl -s http://localhost:9090/api/v1/rules | grep -o '"name":"[^"]*"'
# Debe mostrar los nombres de tus alertas

# 5. Verificar conectividad Grafana → Prometheus
# Desde el navegador: Grafana → Data sources → Prometheus → Test
# Debe decir "Data source is working"

🎯 Escenarios de Prueba

Escenario 1: Alerta de CPU Alta

# Generar carga
stress --cpu 4 --timeout 180s

# Esperar 2 minutos
# Verificar en http://TU_IP:9090/alerts
# Debe activarse HighCPUUsage

Escenario 2: Alerta de Memoria Alta

# Generar consumo de RAM
stress --vm 2 --vm-bytes 1G --timeout 180s

# Verificar en Prometheus/alerts
# Debe activarse HighMemoryUsage

Escenario 3: Simular Servicio Caído

# Detener Node Exporter
docker-compose stop node-exporter

# Esperar 1 minuto
# Verificar alerta ServiceDown

# Volver a levantar
docker-compose start node-exporter

🐛 Troubleshooting

Problema: No puedo acceder a Grafana desde mi navegador

1. Verificar que el contenedor está corriendo:

docker-compose ps
# Debe mostrar "Up" en grafana

2. Verificar que el puerto está expuesto:

docker-compose ps grafana
# Debe mostrar: 0.0.0.0:3000->3000/tcp

3. Verificar firewall (si está activo):

sudo ufw status
# Si está activo:
sudo ufw allow 3000/tcp

4. Verificar configuración de red de VirtualBox:

  • Con Puente: Verifica que la VM tiene IP (hostname -I) y haz ping desde tu PC
  • Con NAT: Verifica que configuraste port forwarding 3000 → 3000

5. Ver logs si persiste el problema:

docker-compose logs grafana

Problema: Contenedores no inician

# Ver logs detallados
docker-compose logs

# Verificar sintaxis de archivos
docker-compose config

# Reiniciar todo
docker-compose down
docker-compose up -d

Problema: Prometheus no muestra métricas

# Verificar targets
curl http://localhost:9090/api/v1/targets

# Verificar conectividad entre contenedores
docker-compose exec prometheus ping node-exporter

# Ver logs de Prometheus
docker-compose logs prometheus | grep error

Problema: Alertas no se disparan

# Verificar que las reglas se cargaron
curl http://localhost:9090/api/v1/rules

# Verificar sintaxis del archivo de reglas
docker-compose exec prometheus promtool check rules /etc/prometheus/alert.rules.yml

# Recargar configuración de Prometheus
curl -X POST http://localhost:9090/-/reload

Problema: Dashboard de Grafana en blanco

  • Verificar que el data source de Prometheus está configurado correctamente
  • Verificar que Prometheus tiene datos: http://TU_IP:9090/graph
  • Ejecutar una query manual: up o node_cpu_seconds_total
  • Verificar el rango de tiempo del dashboard (arriba a la derecha)

📊 Queries PromQL Útiles

Copia estas queries para explorar métricas:

# CPU usage por core
rate(node_cpu_seconds_total{mode!="idle"}[5m])

# CPU usage total
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Memoria disponible
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100

# Uso de disco
(node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes * 100

# Tráfico de red (recibido)
rate(node_network_receive_bytes_total[5m])

# Tráfico de red (enviado)
rate(node_network_transmit_bytes_total[5m])

# Procesos en ejecución
node_procs_running

# Load average
node_load1
node_load5
node_load15

# Uptime del sistema
node_time_seconds - node_boot_time_seconds

🎓 Conceptos Clave Aprendidos

1. Métricas vs Logs vs Traces

  • Métricas (lo que usamos aquí): Datos numéricos agregados (CPU, RAM)
  • Logs: Eventos discretos (errores, accesos)
  • Traces: Flujo de requests (APM)

2. Pull vs Push

  • Prometheus usa modelo Pull (él va a buscar las métricas)
  • Ventaja: Control centralizado, no sobrecarga los servicios

3. Exporters

  • Node Exporter: Sistema operativo
  • MySQL Exporter: Bases de datos
  • Blackbox Exporter: Endpoints HTTP
  • Hay exporters para casi todo

4. PromQL (Prometheus Query Language)

  • Lenguaje específico para consultar métricas
  • Ejemplos:
  • up: Estado de targets
  • rate(): Tasa de cambio
  • sum(), avg(), max(): Agregaciones

5. Alertas: Firing vs Resolved

  • Pending: Condición se cumple pero aún no dispara
  • Firing: Alerta activa
  • Resolved: Condición ya no se cumple

🚀 Siguientes Pasos

Nivel 1: Mejoras Inmediatas

  • [ ] Configurar persistencia de datos de Grafana
  • [ ] Añadir más dashboards (hay miles en grafana.com)
  • [ ] Configurar Alertmanager para enviar a Slack/Email
  • [ ] Añadir autenticación más robusta

Nivel 2: Exporters Adicionales

  • [ ] cAdvisor: Monitorear contenedores Docker
  • [ ] Blackbox Exporter: Monitorear URLs/endpoints
  • [ ] MySQL/PostgreSQL Exporter: Métricas de bases de datos

Nivel 3: Producción

  • [ ] Configurar HTTPS con Nginx reverse proxy
  • [ ] Implementar HA (High Availability) de Prometheus
  • [ ] Configurar retention policies
  • [ ] Integrar con servicios externos (PagerDuty, Opsgenie)

📚 Recursos Adicionales

Documentación Oficial

Dashboards Pre-hechos

  • Grafana Dashboards
  • Node Exporter Full: ID 1860
  • Docker Monitoring: ID 193
  • Prometheus Stats: ID 3662

Comunidad


🧹 Limpieza del Lab

Cuando termines de practicar:

# Detener y eliminar contenedores
docker-compose down

# Eliminar también los volúmenes (datos)
docker-compose down -v

# Eliminar archivos del proyecto
cd ~
rm -rf prometheus-stack

✅ Conclusión

¡Felicidades! 🎉 Has montado un stack completo de observabilidad profesional.

Lo que lograste:

✅ Stack de monitoreo funcional con 4 componentes
✅ Dashboards profesionales importados y personalizados
✅ Alertas configuradas y probadas en tiempo real
✅ Entendimiento de la arquitectura de Prometheus
✅ Queries PromQL para explorar métricas

Skills ganadas:

  • Configuración de Prometheus
  • Creación de dashboards en Grafana
  • Definición de reglas de alertas
  • Troubleshooting de stacks Docker
  • PromQL básico

Aplicación Real:

Este mismo stack (con ajustes) se usa en producción en miles de empresas para:

  • Monitorear infraestructura (servidores, K8s)
  • Detectar problemas antes que los usuarios
  • Generar reportes de SLOs/SLIs
  • Troubleshooting en tiempo real

📝 Feedback

Este lab es parte de la serie de Mini-Labs de Observabilidad de observasistemas.com

¿Encontraste algún error? ¿Sugerencias de mejora?
Comparte tu experiencia en los comentarios del blog.


Autor: ObservaSistemas Team
Versión: 1.0
Última actualización: Diciembre 2024
Licencia: Creative Commons BY-SA 4.0

¡Happy Monitoring! 📊🔍🚀

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.

ACEPTAR
Aviso de cookies