Ir al contenido

Monitoreo en tiempo real con Prometheus y Grafana en Docker: alertas y dashboards personalizados

Rogelio Guerra Riverón
Autor
Rogelio Guerra Riverón
Construyendo mi propia infraestructura web desde cero. Aquí documento cada paso: servidores, redes, contenedores y lo que vaya surgiendo.

Introducción
#

Llevo meses con servidores Docker corriendo en mi máquina doméstica y llegó el momento en que necesitaba visibilidad real sobre qué estaba pasando. Cansado de revisar logs manualmente, decidí meter Prometheus y Grafana. Hoy te cuento cómo lo hice.

El stack que usamos
#

  • Prometheus: recolecta métricas de tus contenedores y servicios
  • Grafana: visualiza esas métricas en dashboards bonitos
  • node-exporter: expone métricas del sistema operativo
  • cAdvisor: métricas específicas de Docker
  • Alertmanager: gestiona notificaciones

Docker Compose: punto de partida
#

Aquí está mi configuración base:

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./alerts.yml:/etc/prometheus/alerts.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=micontraseña
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - monitoring

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
    networks:
      - monitoring

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    networks:
      - monitoring

  alertmanager:
    image: prom/alertmanager:latest
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
      - alertmanager_data:/alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

volumes:
  prometheus_data:
  grafana_data:
  alertmanager_data:

Configurar Prometheus
#

El archivo prometheus.yml:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

rule_files:
  - "alerts.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

  - job_name: 'docker'
    static_configs:
      - targets: ['localhost:9323']

Reglas de alertas
#

En alerts.yml defino cuándo quiero notificaciones:

groups:
  - name: sistema
    interval: 30s
    rules:
      - alert: MemoriaAlta
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) > 0.85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Uso de memoria por encima del 85%"

      - alert: DiskAlto
        expr: (1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) > 0.90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Espacio en disco crítico"

      - alert: ContenedorCaido
        expr: up{job="cadvisor"} == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Contenedor no disponible"

Alertmanager con notificaciones por email
#

En alertmanager.yml:

global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.gmail.com:587'
  smtp_auth_username: 'tu_email@gmail.com'
  smtp_auth_password: 'tu_app_password'
  smtp_from: 'alertas@tudominio.local'

route:
  receiver: 'email-alertas'
  repeat_interval: 1h

receivers:
  - name: 'email-alertas'
    email_configs:
      - to: 'tu_email@gmail.com'
        from: 'alertas@tudominio.local'
        smarthost: 'smtp.gmail.com:587'
        auth_username: 'tu_email@gmail.com'
        auth_password: 'tu_app_password'
        headers:
          Subject: 'Alerta de infraestructura'

Dashboard en Grafana
#

Una vez que Grafana esté corriendo en localhost:3000, añado Prometheus como fuente de datos. Luego importo el dashboard ID 1860 (Node Exporter Full) desde Grafana.com o creo uno personalizado con queries como:

rate(node_cpu_seconds_total[5m])
node_memory_MemAvailable_bytes / 1024 / 1024 / 1024

Conclusión
#

Con esto en marcha, duermo mejor. Recibo emails cuando algo falla, veo gráficas bonitas de qué consume recursos y puedo tomar decisiones basadas en datos reales. El setup inicial tarda 30 minutos, pero el retorno es enorme para una infraestructura doméstica seria.