--- title: "Monitorización con Prometheus, Grafana y Alertmanager" description: "Monta en Ubuntu 24.04 un stack de monitorización con Prometheus, Node Exporter, Alertmanager y Grafana, con reglas de alerta por email y paneles listos." category: "Stack de Observabilidad" language: es source: https://cubepath.com/es/docs/stack-de-observabilidad/stack-completo-de-monitoreo-prometheus-y-grafana updated: 2026-09-25 --- # Monitorización con Prometheus, Grafana y Alertmanager Prometheus, Node Exporter, Alertmanager y Grafana forman el stack de monitorización de código abierto más extendido: Node Exporter expone las métricas de cada servidor, Prometheus las recoge y evalúa las reglas de alerta, Alertmanager agrupa las alertas y las envía por email, y Grafana las muestra en paneles. En este tutorial montarás los cuatro componentes en un servidor Ubuntu 24.04, añadirás otros servidores como objetivos, definirás alertas para caídas, CPU, memoria y disco, y comprobarás que el aviso llega provocando una caída real. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor de monitorización con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM y 20 GB de disco. - Un usuario no root con privilegios `sudo` en este servidor y en los servidores que quieras monitorizar. - UFW activo con el acceso SSH permitido en todos ellos. - Una cuenta SMTP para enviar los avisos (el servidor de correo de tu dominio o un servicio de envío transaccional), con su host, puerto, usuario y contraseña. - La IP pública desde la que accederás a Grafana, que en esta guía se llama `your_admin_ip`. ## Arquitectura Todos los componentes centrales se instalan en el servidor de monitorización, y solo Node Exporter se instala en cada servidor monitorizado: | Componente | Puerto | Dónde escucha | Función | |---|---|---|---| | Prometheus | 9090 | `127.0.0.1` | Recoge métricas cada 15 segundos y evalúa las reglas de alerta. | | Alertmanager | 9093 | `127.0.0.1` | Recibe las alertas de Prometheus, las agrupa y envía los emails. | | Grafana | 3000 | todas las interfaces, filtrado por UFW | Paneles y consulta visual de las métricas. | | Node Exporter | 9100 | cada servidor, filtrado por UFW | Expone CPU, memoria, disco y red del host. | Prometheus y Alertmanager solo escuchan en local porque ningún servicio externo necesita llegar a ellos: Grafana los consulta desde el mismo servidor. Para abrir sus interfaces web usarás un túnel SSH. ## Paso 1: Instalar Node Exporter Instala Node Exporter en el servidor de monitorización y repite este paso después en cada servidor que quieras vigilar. Crea un usuario sin privilegios y descarga la última versión desde la página de releases de `prometheus/node_exporter` (ajusta la variable si hay una más reciente): ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin node_exporter cd /tmp NE_VERSION=1.12.1 curl -LO "https://github.com/prometheus/node_exporter/releases/download/v${NE_VERSION}/node_exporter-${NE_VERSION}.linux-amd64.tar.gz" tar xzf "node_exporter-${NE_VERSION}.linux-amd64.tar.gz" sudo install -m 0755 "node_exporter-${NE_VERSION}.linux-amd64/node_exporter" /usr/local/bin/ ``` Crea la unidad de systemd: ```bash sudo nano /etc/systemd/system/node_exporter.service ``` ```ini [Unit] Description=Prometheus Node Exporter Wants=network-online.target After=network-online.target [Service] User=node_exporter Group=node_exporter Type=simple ExecStart=/usr/local/bin/node_exporter Restart=on-failure [Install] WantedBy=multi-user.target ``` Arranca el servicio y comprueba que publica métricas: ```bash sudo systemctl daemon-reload sudo systemctl enable --now node_exporter curl -s http://localhost:9100/metrics | grep '^node_load1' ``` ```output node_load1 0.12 ``` En los servidores monitorizados, permite el puerto 9100 solo desde la IP del servidor de monitorización, `your_monitoring_ip`. En el propio servidor de monitorización no hace falta abrirlo: ```bash sudo ufw allow from your_monitoring_ip to any port 9100 proto tcp ``` ## Paso 2: Instalar Prometheus En el servidor de monitorización, crea el usuario y los directorios de Prometheus: ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin prometheus sudo mkdir -p /etc/prometheus/rules /var/lib/prometheus sudo chown prometheus:prometheus /var/lib/prometheus ``` Descarga la última versión desde la página de releases de `prometheus/prometheus`, verifica la suma de comprobación e instala los binarios: ```bash cd /tmp PROM_VERSION=3.15.0 curl -LO "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz" curl -LO "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/sha256sums.txt" sha256sum --ignore-missing -c sha256sums.txt tar xzf "prometheus-${PROM_VERSION}.linux-amd64.tar.gz" sudo install -m 0755 "prometheus-${PROM_VERSION}.linux-amd64/prometheus" "prometheus-${PROM_VERSION}.linux-amd64/promtool" /usr/local/bin/ ``` ```output prometheus-3.15.0.linux-amd64.tar.gz: OK ``` Crea la configuración principal. Además de los objetivos, indica dónde está Alertmanager y dónde están los archivos de reglas. Sustituye `server1_ip` y `server2_ip` por las IP de los servidores monitorizados, o deja solo `localhost:9100` por ahora: ```bash sudo nano /etc/prometheus/prometheus.yml ``` ```yaml global: scrape_interval: 15s evaluation_interval: 15s alerting: alertmanagers: - static_configs: - targets: ["localhost:9093"] rule_files: - "/etc/prometheus/rules/*.yml" scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"] - job_name: "alertmanager" static_configs: - targets: ["localhost:9093"] - job_name: "node" static_configs: - targets: ["localhost:9100"] labels: name: "monitoring" - targets: ["server1_ip:9100"] labels: name: "web-01" - targets: ["server2_ip:9100"] labels: name: "db-01" ``` La etiqueta `name` da a cada servidor un nombre legible que aparecerá en los avisos y en los paneles. Crea la unidad de systemd. `--web.listen-address=127.0.0.1:9090` hace que Prometheus no sea accesible desde fuera: ```bash sudo nano /etc/systemd/system/prometheus.service ``` ```ini [Unit] Description=Prometheus Wants=network-online.target After=network-online.target [Service] User=prometheus Group=prometheus Type=simple ExecStart=/usr/local/bin/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus \ --storage.tsdb.retention.time=30d \ --web.listen-address=127.0.0.1:9090 ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target ``` No arranques Prometheus todavía: primero crearás las reglas de alerta a las que hace referencia la configuración. ## Paso 3: Definir las reglas de alerta Las reglas de alerta son consultas PromQL que Prometheus evalúa cada `evaluation_interval`. Cuando una consulta devuelve resultados durante el tiempo indicado en `for`, la alerta pasa a `firing` y se envía a Alertmanager. El `for` evita avisos por picos momentáneos. ```bash sudo nano /etc/prometheus/rules/node.yml ``` ```yaml groups: - name: node rules: - alert: InstanceDown expr: up == 0 for: 1m labels: severity: critical annotations: summary: "{{ $labels.instance }} no responde" description: "El objetivo {{ $labels.instance }} del job {{ $labels.job }} lleva más de 1 minuto sin responder." - alert: HighCpuUsage expr: 100 - (avg by (instance, name) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90 for: 10m labels: severity: warning annotations: summary: "CPU alta en {{ $labels.name }}" description: "El uso de CPU es del {{ $value | printf \"%.0f\" }} % desde hace más de 10 minutos." - alert: LowMemory expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10 for: 5m labels: severity: warning annotations: summary: "Poca memoria libre en {{ $labels.name }}" description: "Solo queda un {{ $value | printf \"%.0f\" }} % de memoria disponible." - alert: DiskSpaceLow expr: node_filesystem_avail_bytes{fstype!~"tmpfs|overlay|squashfs"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay|squashfs"} * 100 < 10 for: 10m labels: severity: critical annotations: summary: "Disco casi lleno en {{ $labels.name }}" description: "El sistema de archivos {{ $labels.mountpoint }} tiene solo un {{ $value | printf \"%.0f\" }} % libre." ``` Valida las reglas y la configuración completa: ```bash promtool check rules /etc/prometheus/rules/node.yml promtool check config /etc/prometheus/prometheus.yml ``` ```output Checking /etc/prometheus/rules/node.yml SUCCESS: 4 rules found Checking /etc/prometheus/prometheus.yml SUCCESS: 1 rule files found SUCCESS: /etc/prometheus/prometheus.yml is valid prometheus config file syntax Checking /etc/prometheus/rules/node.yml SUCCESS: 4 rules found ``` Arranca Prometheus y comprueba que está listo: ```bash sudo systemctl daemon-reload sudo systemctl enable --now prometheus curl -s http://localhost:9090/-/ready ``` ```output Prometheus Server is Ready. ``` ## Paso 4: Instalar Alertmanager Alertmanager recibe las alertas de Prometheus, agrupa las que llegan a la vez (por ejemplo, diez servidores caídos por el mismo problema de red en un solo email), evita repetirlas constantemente y las envía a los receptores configurados. Crea su usuario y directorios, descarga la última versión desde la página de releases de `prometheus/alertmanager` e instala los binarios `alertmanager` y `amtool`: ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin alertmanager sudo mkdir -p /etc/alertmanager /var/lib/alertmanager sudo chown alertmanager:alertmanager /var/lib/alertmanager cd /tmp AM_VERSION=0.34.1 curl -LO "https://github.com/prometheus/alertmanager/releases/download/v${AM_VERSION}/alertmanager-${AM_VERSION}.linux-amd64.tar.gz" tar xzf "alertmanager-${AM_VERSION}.linux-amd64.tar.gz" sudo install -m 0755 "alertmanager-${AM_VERSION}.linux-amd64/alertmanager" "alertmanager-${AM_VERSION}.linux-amd64/amtool" /usr/local/bin/ ``` Crea la configuración. Sustituye los valores de SMTP (`smtp.your_domain:587`, `alerts@your_domain`, `your_smtp_password`) y el destinatario `ops@your_domain` por los tuyos: ```bash sudo nano /etc/alertmanager/alertmanager.yml ``` ```yaml global: smtp_smarthost: "smtp.your_domain:587" smtp_from: "alerts@your_domain" smtp_auth_username: "alerts@your_domain" smtp_auth_password: "your_smtp_password" smtp_require_tls: true route: receiver: "email" group_by: ["alertname", "name"] group_wait: 30s group_interval: 5m repeat_interval: 4h receivers: - name: "email" email_configs: - to: "ops@your_domain" send_resolved: true inhibit_rules: - source_matchers: - severity="critical" target_matchers: - severity="warning" equal: ["instance"] ``` - `group_wait` es cuánto espera Alertmanager antes de enviar el primer aviso de un grupo, para juntar alertas relacionadas. - `repeat_interval` es cada cuánto se reenvía una alerta que sigue activa. - `send_resolved: true` envía también un email cuando el problema se resuelve. - La regla `inhibit_rules` silencia los avisos `warning` de un servidor mientras tenga una alerta `critical` activa, por ejemplo cuando está caído. El archivo contiene la contraseña SMTP, así que haz que solo lo pueda leer el usuario del servicio, y valida la sintaxis: ```bash sudo chown root:alertmanager /etc/alertmanager/alertmanager.yml sudo chmod 640 /etc/alertmanager/alertmanager.yml sudo amtool check-config /etc/alertmanager/alertmanager.yml ``` ```output Checking '/etc/alertmanager/alertmanager.yml' SUCCESS Found: - global config - route - 1 inhibit rules - 1 receivers - 0 templates ``` Crea la unidad de systemd. `--cluster.listen-address=` vacío desactiva el modo clúster de alta disponibilidad, que no necesitas con una sola instancia y que abriría el puerto 9094: ```bash sudo nano /etc/systemd/system/alertmanager.service ``` ```ini [Unit] Description=Prometheus Alertmanager Wants=network-online.target After=network-online.target [Service] User=alertmanager Group=alertmanager Type=simple ExecStart=/usr/local/bin/alertmanager \ --config.file=/etc/alertmanager/alertmanager.yml \ --storage.path=/var/lib/alertmanager \ --web.listen-address=127.0.0.1:9093 \ --cluster.listen-address= ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target ``` Arráncalo y comprueba que responde: ```bash sudo systemctl daemon-reload sudo systemctl enable --now alertmanager curl -s http://localhost:9093/-/ready ``` ```output OK ``` Comprueba desde Prometheus que ha descubierto Alertmanager: ```bash curl -s http://localhost:9090/api/v1/alertmanagers ``` ```output {"status":"success","data":{"activeAlertmanagers":[{"url":"http://localhost:9093/api/v2/alerts"}],"droppedAlertmanagers":[]}} ``` ## Paso 5: Instalar Grafana Añade el repositorio oficial de Grafana Labs con su clave e instala el paquete: ```bash sudo apt update sudo apt install -y apt-transport-https wget gnupg sudo mkdir -p /etc/apt/keyrings sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key sudo chmod 644 /etc/apt/keyrings/grafana.asc echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list sudo apt update sudo apt install grafana ``` Declara Prometheus como fuente de datos mediante un archivo de provisioning, para que quede configurada desde el primer arranque: ```bash sudo nano /etc/grafana/provisioning/datasources/prometheus.yaml ``` ```yaml apiVersion: 1 datasources: - name: Prometheus type: prometheus uid: prometheus access: proxy url: http://localhost:9090 isDefault: true jsonData: timeInterval: 15s ``` Arranca Grafana y permite el puerto 3000 solo desde tu IP de administración: ```bash sudo systemctl enable --now grafana-server sudo ufw allow from your_admin_ip to any port 3000 proto tcp ``` Comprueba que responde: ```bash curl -s http://localhost:3000/api/health ``` ```output { "database": "ok", "version": "13.2.2" } ``` Abre `http://your_server_ip:3000`, inicia sesión con `admin` / `admin` y establece una contraseña fuerte cuando Grafana te la pida. > Importante: el puerto 3000 sirve Grafana por HTTP sin cifrar. Si vas a acceder desde redes que no controlas o sin IP fija, publícalo detrás de Nginx con un certificado de Let's Encrypt en lugar de abrir el puerto. ## Paso 6: Importar el panel de servidores Para tener un panel completo de cada servidor sin construirlo a mano, importa **Node Exporter Full** desde grafana.com: 1. Ve a **Dashboards**, **New**, **Import**. 2. Escribe el ID `1860` y pulsa **Load**. 3. Elige **Prometheus** como fuente de datos y pulsa **Import**. Usa el desplegable **Host** o **Instance** de la parte superior para cambiar entre servidores. Verás CPU, carga, memoria, disco, red y más para cada uno de los objetivos del job `node`. ## Paso 7: Comprobar el estado de objetivos y reglas Las interfaces de Prometheus y Alertmanager solo escuchan en local. Para verlas desde tu equipo, abre un túnel SSH que reenvíe ambos puertos: ```bash ssh -L 9090:localhost:9090 -L 9093:localhost:9093 your_user@your_server_ip ``` Con el túnel abierto, visita en tu navegador: - `http://localhost:9090/targets`: todos los objetivos deben aparecer en estado `UP`. Si uno de los servidores remotos aparece `DOWN`, revisa la regla de UFW del paso 1 en ese servidor. - `http://localhost:9090/alerts`: las cuatro reglas del grupo `node`, en estado `Inactive` mientras todo esté bien. - `http://localhost:9093`: la interfaz de Alertmanager, con las alertas activas y los silencios. También puedes comprobar los objetivos desde el servidor sin navegador: ```bash curl -s http://localhost:9090/api/v1/targets | jq -r '.data.activeTargets[] | "\(.labels.job) \(.labels.instance) \(.health)"' ``` ```output alertmanager localhost:9093 up node localhost:9100 up node 203.0.113.21:9100 up node 203.0.113.22:9100 up prometheus localhost:9090 up ``` Instala `jq` con `sudo apt install jq` si no lo tienes. ## Paso 8: Probar el circuito de alertas La única forma fiable de saber que las alertas funcionan es provocar una. Detén Node Exporter en uno de los servidores monitorizados: ```bash sudo systemctl stop node_exporter ``` En unos 15 segundos Prometheus marcará el objetivo como caído y la alerta `InstanceDown` pasará a `Pending`. Tras el minuto de `for` pasará a `Firing` y se enviará a Alertmanager, que esperará los 30 segundos de `group_wait` antes de mandar el email. Desde el servidor de monitorización puedes ver la alerta activa en Alertmanager con `amtool`: ```bash amtool alert query --alertmanager.url=http://localhost:9093 ``` ```output Alertname Starts At Summary State InstanceDown 2026-09-25 12:41:03 UTC 203.0.113.21:9100 no responde active ``` Deberías recibir el email en `ops@your_domain` en menos de dos minutos. Vuelve a arrancar Node Exporter: ```bash sudo systemctl start node_exporter ``` Unos minutos después recibirás un segundo email indicando que la alerta se ha resuelto. Si necesitas hacer tareas de mantenimiento en un servidor sin recibir avisos, crea un silencio temporal en Alertmanager con `amtool`. Este silencia todas las alertas del servidor `web-01` durante dos horas: ```bash amtool silence add name="web-01" --duration=2h --comment="Mantenimiento" --alertmanager.url=http://localhost:9093 ``` ## Añadir más servidores Para cada servidor nuevo: 1. Instala Node Exporter siguiendo el paso 1 y permite el puerto 9100 desde `your_monitoring_ip`. 2. Añade su `IP:9100` con su etiqueta `name` a la lista del job `node` en `/etc/prometheus/prometheus.yml`. 3. Valida y recarga Prometheus sin reiniciarlo: ```bash promtool check config /etc/prometheus/prometheus.yml sudo systemctl reload prometheus ``` Si gestionas muchos servidores, en lugar de editar `prometheus.yml` cada vez puedes usar `file_sd_configs`: Prometheus lee la lista de objetivos de archivos JSON o YAML en un directorio y detecta los cambios sin necesidad de recargar. ## Solución de problemas **Un servicio no arranca.** Cada componente registra el motivo en el journal: ```bash sudo journalctl -u prometheus -n 50 --no-pager sudo journalctl -u alertmanager -n 50 --no-pager ``` **La alerta aparece en Prometheus pero no llega ningún email.** Comprueba si Alertmanager la ha recibido con `amtool alert query`. Si está ahí, el problema es el envío: busca errores de SMTP (autenticación, puerto o TLS) en el log de Alertmanager: ```bash sudo journalctl -u alertmanager --since "15 min ago" | grep -i -E "error|smtp" ``` Revisa también la carpeta de spam y que tu proveedor permita enviar desde la dirección de `smtp_from`. **Un objetivo remoto está `DOWN` con `context deadline exceeded`.** El firewall del servidor monitorizado está bloqueando el puerto 9100. Desde el servidor de monitorización, prueba `curl -s http://server1_ip:9100/metrics | head -3` y revisa `sudo ufw status` en el servidor remoto. **Los paneles de Grafana muestran `No data`.** Comprueba en **Connections**, **Data sources**, **Prometheus**, **Test** que Grafana llega a Prometheus, y que la métrica existe ejecutando la consulta en `http://localhost:9090` a través del túnel. ## Conclusión Tienes un stack de monitorización completo en Ubuntu 24.04: Node Exporter en cada servidor, Prometheus recogiendo métricas y evaluando alertas, Alertmanager enviando avisos agrupados por email y Grafana con un panel completo por servidor, con Prometheus y Alertmanager accesibles solo en local. Como siguientes pasos puedes añadir un segundo receptor en Alertmanager para avisos críticos en Slack o Discord, instalar exporters para tus servicios (MySQL, PostgreSQL, Nginx) y crear reglas específicas para ellos, o incorporar Blackbox Exporter para comprobar desde fuera que tus webs responden por HTTPS.