Por qué monitorizar
Sin monitorización, los problemas se detectan cuando ya es demasiado tarde. Un stack basado en Prometheus y Grafana permite recopilar métricas, configurar alertas y visualizar el estado de toda tu infraestructura desde un solo panel. Es más flexible pero también más laborioso de mantener que una solución todo-en-uno como Zabbix, o que un monitor de disponibilidad ligero como Uptime Kuma si solo necesitas saber si un servicio está caído.
Arquitectura del stack
El flujo es sencillo:
- Node Exporter expone métricas del sistema (CPU, RAM, disco, red) en cada servidor
- Prometheus recopila esas métricas periódicamente (scraping)
- Grafana las visualiza en dashboards interactivos
Servidor monitorizado
│
▼
1. Node Exporter — expone métricas en :9100/metrics
│
▼
2. Prometheus — scrapea :9100 y las almacena en :9090
│
▼
3. Grafana — consulta Prometheus y las visualiza en :3000
Instalar Node Exporter en los servidores
Node Exporter se ejecuta en cada máquina que quieras monitorizar.
# Comprueba la última versión en https://github.com/prometheus/node_exporter/releases
wget https://github.com/prometheus/node_exporter/releases/download/v1.12.1/node_exporter-1.12.1.linux-amd64.tar.gz
tar xvfz node_exporter-1.12.1.linux-amd64.tar.gz
sudo mv node_exporter-1.12.1.linux-amd64/node_exporter /usr/local/bin/
Crear el servicio de systemd:
sudo tee /etc/systemd/system/node_exporter.service > /dev/null <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
Activar y arrancar:
sudo useradd -rs /bin/false node_exporter
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
Las métricas estarán disponibles en http://servidor:9100/metrics.
Instalar Prometheus
En el servidor central de monitorización:
# Comprueba la última versión en https://github.com/prometheus/prometheus/releases
wget https://github.com/prometheus/prometheus/releases/download/v3.13.1/prometheus-3.13.1.linux-amd64.tar.gz
tar xvfz prometheus-3.13.1.linux-amd64.tar.gz
sudo mv prometheus-3.13.1.linux-amd64/{prometheus,promtool} /usr/local/bin/
sudo mkdir -p /etc/prometheus /var/lib/prometheus
Configurar los targets
Edita /etc/prometheus/prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'nodos'
static_configs:
- targets:
- '192.168.1.10:9100'
- '192.168.1.11:9100'
- '192.168.1.12:9100'
Crear el servicio
sudo tee /etc/systemd/system/prometheus.service > /dev/null <<EOF
[Unit]
Description=Prometheus
After=network.target
[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus
[Install]
WantedBy=multi-user.target
EOF
sudo useradd -rs /bin/false prometheus
sudo chown -R prometheus: /var/lib/prometheus /etc/prometheus
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
Prometheus estará accesible en http://servidor:9090.
Instalar Grafana
# RHEL/Rocky/Oracle Linux — comprueba la última versión en https://grafana.com/grafana/download?edition=oss
sudo dnf install -y https://dl.grafana.com/oss/release/grafana-13.1.1-1.x86_64.rpm
# Ubuntu/Debian
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/grafana.key > /dev/null
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" \
| sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana -y
Activar el servicio:
sudo systemctl enable --now grafana-server
Accede a http://servidor:3000 (usuario y contraseña por defecto: admin/admin).
## Importante
Grafana te pedirá cambiar la contraseña en el primer login — no la omitas. Mientras uses las credenciales por defecto, cualquiera con acceso a ese puerto puede entrar al panel.
Conectar con Prometheus
- Ve a Connections > Data Sources > Add data source
- Selecciona Prometheus
- En URL introduce
http://localhost:9090 - Pulsa Save & Test
Importar un dashboard
El dashboard más popular para Node Exporter es el 1860:
- Ve a Dashboards > Import
- Introduce el ID
1860 - Selecciona la fuente de datos Prometheus
- Pulsa Import
Tendrás un panel completo con CPU, memoria, disco, red y más para cada servidor.
Consultas PromQL útiles
Node Exporter expone dos tipos de métrica que se consultan de forma distinta. Las de uso instantáneo (memoria, disco) son gauges: su valor actual ya es lo que quieres graficar, sin transformación. Las acumulativas (CPU, red, disco I/O) son counters: solo suben con el tiempo (o se reinician a 0 si el proceso se reinicia), así que no tiene sentido graficar su valor absoluto — necesitas rate() para convertirlas en “cuánto por segundo” en la ventana indicada. rate() además detecta y compensa automáticamente los reinicios del contador, así que no hace falta tratarlos como caso especial.
# Uso de CPU por nodo (porcentaje)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Memoria usada (porcentaje)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Espacio en disco usado (porcentaje)
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100
# Tráfico de red recibido (bytes/s)
rate(node_network_receive_bytes_total{device="eth0"}[5m])
# Carga del sistema relativa a los cores disponibles (>1 = más procesos en cola de los que hay CPU)
node_load1 / count(count(node_cpu_seconds_total) by (cpu))
# Errores de red recibidos por segundo — un valor > 0 sostenido suele indicar un problema físico (cable, NIC, MTU)
rate(node_network_receive_errs_total{device="eth0"}[5m])
# Tiempo que el disco pasa ocupado con I/O (porcentaje aproximado de saturación)
rate(node_disk_io_time_seconds_total{device="sda"}[5m]) * 100
## Consejo
Las consultas anteriores usan
rate(), pensado para dashboards y alertas: promedia toda la ventana ([5m]) y suaviza picos puntuales, lo que da una señal estable para decidir si algo está realmente mal. Si en cambio estás depurando un problema en vivo y quieres ver la variación más reciente sin ese suavizado,irate()usa solo las dos últimas muestras — reacciona antes a un pico, pero es más ruidoso y no es buena base para una alerta (dispararía y se resolvería con cada fluctuación breve).
Configurar alertas básicas
Una alerta de Prometheus por sí sola no notifica a nadie: define cuándo una condición es cierta. Quien decide a quién avisar y cómo es un componente aparte, Alertmanager, que se instala y configura por separado. Esta sección cubre ambas mitades.
Regla evaluada cada 15s (scrape_interval)
│
▼
1. expr se cumple (ej. up == 0)
│
▼
2. Estado "pending" — Prometheus espera a que se cumpla `for` (ej. 2m)
│
├── deja de cumplirse antes de `for` → se descarta, no llega a notificar (evita falsas alarmas por un blip)
└── sigue cumpliéndose tras `for` → estado "firing"
│
▼
3. Prometheus envía la alerta a Alertmanager
│
▼
4. Alertmanager agrupa, deduplica y enruta según `severity`
│
├── severity: critical → receiver con notificación inmediata
└── severity: warning → receiver con notificación agrupada
Crea un archivo de reglas /etc/prometheus/alerts.yml:
groups:
- name: nodos
rules:
- alert: NodoCaido
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: 'Nodo {{ $labels.instance }} no responde'
- alert: DiscoLleno
expr: (1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: 'Disco al {{ $value | humanizePercentage }} en {{ $labels.instance }}'
for: 2m es lo que separa una alerta útil de una que satura a golpe de falsos positivos: exige que la condición se mantenga cierta durante ese tiempo antes de pasar a estado “firing”, así un reinicio de 10 segundos o un pico de disco momentáneo no dispara una notificación. Cuanto más crítico el servicio, menor conviene ese margen; cuanto más ruidosa la métrica (como el disco, que puede subir y bajar con un proceso puntual), mayor.
Añade la referencia en prometheus.yml:
rule_files:
- 'alerts.yml'
Instalar y conectar Alertmanager
# Comprueba la última versión en https://github.com/prometheus/alertmanager/releases
wget https://github.com/prometheus/alertmanager/releases/download/v0.33.1/alertmanager-0.33.1.linux-amd64.tar.gz
tar xvfz alertmanager-0.33.1.linux-amd64.tar.gz
sudo mv alertmanager-0.33.1.linux-amd64/{alertmanager,amtool} /usr/local/bin/
sudo mkdir -p /etc/alertmanager
Un /etc/alertmanager/alertmanager.yml mínimo, con un receiver de tipo webhook (válido para integrar con ntfy, Telegram vía un pequeño proxy, o cualquier endpoint HTTP propio) y una ruta que separa lo crítico de lo que no lo es:
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'critico'
repeat_interval: 30m
receivers:
- name: 'default'
webhook_configs:
- url: 'http://localhost:8080/notificar'
- name: 'critico'
webhook_configs:
- url: 'http://localhost:8080/notificar-urgente'
group_wait da un margen antes de enviar la primera notificación de un grupo nuevo, por si llegan más alertas relacionadas que conviene agrupar en un solo aviso en vez de uno por alerta. repeat_interval controla cada cuánto se re-notifica una alerta que sigue activa — más corto para critico (30m) que para el resto (4h), porque un nodo caído merece un recordatorio más frecuente que un disco al 86%.
Crea el servicio y arráncalo:
sudo tee /etc/systemd/system/alertmanager.service > /dev/null <<EOF
[Unit]
Description=Alertmanager
After=network.target
[Service]
User=alertmanager
ExecStart=/usr/local/bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml
[Install]
WantedBy=multi-user.target
EOF
sudo useradd -rs /bin/false alertmanager
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager
Y apunta Prometheus hacia él en prometheus.yml:
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
Reinicia ambos para aplicar los cambios:
sudo systemctl restart prometheus alertmanager
## Nota
Este ejemplo usa un receiver webhook genérico para no atarte a un servicio concreto. Alertmanager trae integraciones nativas para email, Slack, PagerDuty y Opsgenie con su propia sintaxis de configuración — revisa la documentación oficial de receivers si usas alguno de esos canales directamente.
## Consejo
Prometheus guarda sus datos localmente 15 días por defecto (
--storage.tsdb.retention.time=15d); pasado ese plazo, las métricas más antiguas se descartan. Si necesitas comparar con el mismo periodo del año anterior, súbelo explícitamente en elExecStartdel servicio (por ejemplo--storage.tsdb.retention.time=90d), teniendo en cuenta que más retención significa más disco ocupado en/var/lib/prometheus.
Conclusión
Con Prometheus, Node Exporter, Alertmanager y Grafana tienes un stack de monitorización completo, gratuito y con notificaciones reales cuando algo falla — no solo un panel bonito que hay que estar mirando activamente. Para el próximo nivel de detalle: exporters especializados (mysqld_exporter, blackbox_exporter para comprobar endpoints HTTP desde fuera) amplían lo que este stack puede vigilar más allá de las métricas de sistema operativo que cubre Node Exporter.
## Nota
✍️ Transparencia: Este artículo ha sido creado con el apoyo de herramientas de inteligencia artificial. Toda la información técnica ha sido revisada y validada por el autor antes de su publicación.