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 / 1024Conclusió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.