Alertmanager recibe las alertas que dispara Prometheus, las agrupa y deduplica, y envía las notificaciones a canales como correo electrónico, Slack o cualquier webhook. Prometheus decide cuándo algo va mal; Alertmanager decide quién se entera, con qué frecuencia y qué se silencia. En este tutorial instalarás Prometheus y Alertmanager en Ubuntu 24.04, escribirás dos reglas de alerta y construirás un árbol de enrutamiento que envía las alertas críticas y los avisos a receptores distintos, con reglas de inhibición y silencios gestionados con amtool.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con
sudo. - Una cuenta SMTP que acepte envío autenticado en el puerto 587 (tu proveedor de correo o un servicio de correo transaccional) si quieres notificaciones por correo.
- La URL de un webhook entrante de Slack si quieres notificaciones en Slack. Puedes crearla desde una app de Slack, en Incoming Webhooks.
Si Prometheus ya funciona en el servidor instalado desde los paquetes de Ubuntu, puedes saltarte la parte de Prometheus del paso 1.
Paso 1: Instalar Prometheus y Alertmanager
Ubuntu 24.04 incluye ambos componentes en sus repositorios, con unidades de systemd y la configuración en /etc/prometheus. El paquete prometheus instala también prometheus-node-exporter, que expone las métricas del host que usan las reglas de ejemplo:
sudo apt update
sudo apt install -y prometheus prometheus-alertmanager
Comprueba que los tres servicios están en marcha:
systemctl is-active prometheus prometheus-node-exporter prometheus-alertmanager
active
active
active
Los paquetes incluyen amtool, el cliente de línea de comandos de Alertmanager, y promtool, el de Prometheus. Comprueba las versiones:
amtool --version
promtool --version
Por defecto Alertmanager escucha en todas las interfaces en el puerto 9093 (API) y 9094 (gossip del clúster), sin autenticación. En un único servidor no necesitas clúster, y solo Prometheus, en el mismo host, tiene que llegar a la API. Abre el archivo de valores por defecto del servicio:
sudo nano /etc/default/prometheus-alertmanager
Define la línea ARGS para que Alertmanager escuche solo en localhost y sin clúster:
ARGS="--web.listen-address=127.0.0.1:9093 --cluster.listen-address="
Reinicia el servicio y confirma la dirección de escucha:
sudo systemctl restart prometheus-alertmanager
sudo ss -tlnp | grep 9093
LISTEN 0 4096 127.0.0.1:9093 0.0.0.0:* users:(("prometheus-aler",pid=4121,fd=3))
Para escribir menos, indica a amtool dónde está Alertmanager:
mkdir -p ~/.config/amtool
echo "alertmanager.url: http://127.0.0.1:9093" > ~/.config/amtool/config.yml
Paso 2: Conectar Prometheus con Alertmanager
Prometheus necesita dos cosas: la dirección de Alertmanager y un conjunto de reglas de alerta. Abre la configuración de Prometheus:
sudo nano /etc/prometheus/prometheus.yml
Asegúrate de que las secciones alerting y rule_files quedan así (la configuración por defecto de Ubuntu ya apunta a localhost:9093; lo principal es añadir la ruta de las reglas):
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- /etc/prometheus/rules/*.yml
Crea el directorio de reglas y un archivo de reglas:
sudo mkdir -p /etc/prometheus/rules
sudo nano /etc/prometheus/rules/node.yml
Las dos reglas siguientes saltan cuando desaparece un objetivo de scrape y cuando el sistema de archivos raíz está casi lleno. La etiqueta severity es la que usará Alertmanager para enrutar:
groups:
- name: node
rules:
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} no responde"
description: "El job {{ $labels.job }} en {{ $labels.instance }} lleva 2 minutos inaccesible."
- alert: RootDiskAlmostFull
expr: (node_filesystem_avail_bytes{mountpoint="/",fstype!="tmpfs"} / node_filesystem_size_bytes{mountpoint="/",fstype!="tmpfs"}) * 100 < 15
for: 10m
labels:
severity: warning
annotations:
summary: "Disco raíz de {{ $labels.instance }} por debajo del 15% libre"
description: "Solo queda libre un {{ printf \"%.1f\" $value }}% de / en {{ $labels.instance }}."
Valida ambos archivos con promtool antes de reiniciar:
promtool check rules /etc/prometheus/rules/node.yml
promtool check config /etc/prometheus/prometheus.yml
Checking /etc/prometheus/rules/node.yml
SUCCESS: 2 rules found
Reinicia Prometheus y confirma que ha descubierto Alertmanager:
sudo systemctl restart prometheus
curl -s http://localhost:9090/api/v1/alertmanagers
{"status":"success","data":{"activeAlertmanagers":[{"url":"http://localhost:9093/api/v2/alerts"}],"droppedAlertmanagers":[]}}
Paso 3: Entender la configuración de Alertmanager
El archivo de configuración es /etc/prometheus/alertmanager.yml y tiene cuatro partes principales:
| Sección | Función |
|---|---|
global | Valores por defecto compartidos por los receptores, como los ajustes SMTP y resolve_timeout. |
route | Un árbol. La ruta raíz recoge todas las alertas; las rutas hijas filtran por etiquetas y eligen un receptor. |
receivers | Destinos de notificación con nombre, cada uno con una o varias integraciones (correo, Slack, webhook...). |
inhibit_rules | Silencian unas alertas mientras otras más importantes están activas. |
Tres temporizadores en cada ruta controlan cuánto ruido generan las notificaciones:
group_wait: cuánto esperar tras la primera alerta de un grupo nuevo antes de notificar, para que las alertas que saltan a la vez lleguen en un único mensaje.group_interval: cuánto esperar antes de notificar alertas nuevas añadidas a un grupo ya notificado.repeat_interval: cuánto tiempo pasa antes de reenviar la notificación de alertas que siguen activas.
Las alertas se agrupan por las etiquetas indicadas en group_by. Agrupar por alertname e instance significa un mensaje por problema y por servidor.
Paso 4: Escribir la configuración de enrutamiento
Haz una copia del archivo de ejemplo que instaló el paquete y ábrelo:
sudo cp /etc/prometheus/alertmanager.yml /etc/prometheus/alertmanager.yml.orig
sudo nano /etc/prometheus/alertmanager.yml
Sustituye su contenido por la configuración siguiente. Cambia smtp.your_provider.com, las direcciones de correo, your_smtp_password y la URL del webhook de Slack por tus propios valores:
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.your_provider.com:587'
smtp_from: 'alertmanager@your_domain'
smtp_auth_username: 'alertmanager@your_domain'
smtp_auth_password: 'your_smtp_password'
smtp_require_tls: true
route:
receiver: 'email-ops'
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- matchers:
- severity="critical"
receiver: 'critical'
group_wait: 10s
repeat_interval: 1h
- matchers:
- severity="warning"
receiver: 'slack-warnings'
receivers:
- name: 'email-ops'
email_configs:
- to: 'ops@your_domain'
send_resolved: true
- name: 'critical'
email_configs:
- to: 'oncall@your_domain'
send_resolved: true
slack_configs:
- api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
channel: '#alerts-critical'
send_resolved: true
title: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ "\n" }}{{ end }}'
- name: 'slack-warnings'
slack_configs:
- api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
channel: '#alerts'
send_resolved: true
title: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ "\n" }}{{ end }}'
inhibit_rules:
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
equal: ['instance']
Cómo se comporta esta configuración:
- Las alertas críticas van al buzón de guardia y a
#alerts-critical, se envían 10 segundos después de saltar y se repiten cada hora mientras no se resuelvan. - Los avisos van solo a
#alertsy se repiten cada 4 horas (heredado de la ruta raíz). - Todo lo que no tenga un
severityque coincida cae en el receptor raíz,email-ops. - Mientras una alerta crítica está activa para una instancia, los avisos de esa misma instancia se silencian, así un servidor caído no inunda además el canal con avisos de disco o carga.
La sintaxis matchers sustituye a las claves antiguas match y match_re, que están obsoletas. También admite !=, =~ y !~, por ejemplo - service=~"api-.*".
La configuración contiene una contraseña, así que limita la lectura a root y al usuario del servicio:
sudo chown root:prometheus /etc/prometheus/alertmanager.yml
sudo chmod 640 /etc/prometheus/alertmanager.yml
Paso 5: Validar y aplicar la configuración
Comprueba el archivo con amtool. Valida el YAML, las plantillas y las referencias a receptores:
amtool check-config /etc/prometheus/alertmanager.yml
Checking '/etc/prometheus/alertmanager.yml' SUCCESS
Found:
- global config
- route
- 1 inhibit rules
- 3 receivers
- 0 templates
Antes de ponerla en producción, prueba a qué receptor llegaría un conjunto de etiquetas. Es la forma más rápida de depurar un árbol de rutas:
amtool config routes test --config.file=/etc/prometheus/alertmanager.yml severity=critical alertname=InstanceDown
amtool config routes test --config.file=/etc/prometheus/alertmanager.yml severity=info
critical
email-ops
Muestra el árbol completo para revisarlo:
amtool config routes show --config.file=/etc/prometheus/alertmanager.yml
Aplica la nueva configuración. Alertmanager se recarga sin reiniciarse al recibir un POST en /-/reload; si el archivo no es válido, mantiene la configuración anterior y registra el error:
curl -X POST http://127.0.0.1:9093/-/reload
sudo journalctl -u prometheus-alertmanager -n 20 --no-pager
... msg="Loading configuration file" file=/etc/prometheus/alertmanager.yml
... msg="Completed loading of configuration file" file=/etc/prometheus/alertmanager.yml
Paso 6: Enviar una alerta de prueba
No hace falta romper nada para probar el envío. amtool alert add publica una alerta directamente en la API de Alertmanager:
amtool alert add alertname=TestAlert severity=warning instance=test01 --annotation=description="Aviso de prueba enviado con amtool"
Lista las alertas activas:
amtool alert query
Alertname Starts At Summary State
TestAlert 2026-09-25 10:12:04 UTC active
Tras group_wait (30 segundos) el mensaje debería aparecer en #alerts. Repite con severity=critical para probar el correo y el canal crítico. Las alertas de prueba se resuelven solas tras resolve_timeout (5 minutos), y recibirás entonces la notificación de resolución porque send_resolved está activado.
Para probar el recorrido real desde Prometheus, detén el node exporter un par de minutos, lo que hace que up == 0 se cumpla para ese objetivo:
sudo systemctl stop prometheus-node-exporter
Pasado el periodo for de 2 minutos, InstanceDown salta con severity=critical. Vuelve a arrancar el exporter:
sudo systemctl start prometheus-node-exporter
Paso 7: Gestionar silencios con amtool
Un silencio acalla las notificaciones de las alertas que coinciden con un conjunto de etiquetas durante un intervalo de tiempo, justo lo que necesitas durante un mantenimiento planificado. A diferencia de la inhibición, los silencios se crean en caliente y no requieren cambiar la configuración.
Silencia todas las alertas de una instancia durante dos horas:
amtool silence add instance="web01:9100" --duration=2h --comment="Actualización de kernel en web01"
El comando muestra el ID del silencio. Lista los silencios activos:
amtool silence query
ID Matchers Ends At Created By Comment
3f1a7c2e-8b4d-4e0f-9a51-2c6d7e8f9a01 instance="web01:9100" 2026-09-25 12:15:00 UTC your_user Actualización de kernel en web01
Termina un silencio antes de tiempo cuando acabe el mantenimiento:
amtool silence expire 3f1a7c2e-8b4d-4e0f-9a51-2c6d7e8f9a01
Los silencios se guardan en el directorio de datos de Alertmanager y sobreviven a los reinicios.
Paso 8: Enviar alertas a un webhook
Para integraciones que Alertmanager no soporta de forma nativa, un receptor webhook envía por POST un documento JSON que describe el grupo de alertas a cualquier endpoint HTTP. Añade un receptor como este en receivers:
- name: 'ticketing'
webhook_configs:
- url: 'https://hooks.your_domain/alertmanager'
send_resolved: true
http_config:
authorization:
type: Bearer
credentials: 'your_webhook_token'
Después haz referencia a él desde una ruta hija en route.routes, por ejemplo para enviarle todo lo que tenga la etiqueta team="billing":
- matchers:
- team="billing"
receiver: 'ticketing'
El contenido incluye status, groupLabels, commonLabels, commonAnnotations y la lista de alerts. Valida y recarga como en el paso 5.
Solución de problemas
No llega ninguna notificación. Revisa primero los logs; los errores de envío (autenticación SMTP, 404 de Slack) se registran con el nombre del receptor:
sudo journalctl -u prometheus-alertmanager -f
Las alertas saltan en Prometheus pero no llegan a Alertmanager. Consulta curl -s http://localhost:9090/api/v1/alertmanagers y confirma que activeAlertmanagers no está vacío. Si has limitado Alertmanager a 127.0.0.1, el objetivo en prometheus.yml debe ser localhost:9093, no la IP pública.
El correo falla con 535 Authentication failed o errores de TLS. Usa el puerto 587 con smtp_require_tls: true y una contraseña de aplicación si tu proveedor la exige. En servidores cloud, el puerto 25 de salida suele estar bloqueado.
Una notificación fue al receptor equivocado. Las rutas se evalúan de arriba abajo y gana la primera que coincide, salvo que una ruta tenga continue: true. Reproduce el caso con amtool config routes test y las etiquetas exactas de la alerta.
amtool devuelve connection refused. Comprueba que ~/.config/amtool/config.yml apunta a la dirección definida en --web.listen-address.
Conclusión
Ahora Prometheus envía sus alertas a Alertmanager, que las agrupa por alerta e instancia, enruta las críticas y los avisos a canales distintos, silencia los avisos mientras hay una alerta crítica activa y te permite acallar el ruido durante los mantenimientos.
Buenos siguientes pasos son añadir más reglas (memoria, unidades de systemd fallidas, caducidad de certificados con el blackbox exporter), mover el texto repetido de las notificaciones a un archivo de plantilla referenciado con templates: y añadir más objetivos a Prometheus para que el mismo árbol de rutas cubra toda tu flota.
