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ónFunción
globalValores por defecto compartidos por los receptores, como los ajustes SMTP y resolve_timeout.
routeUn árbol. La ruta raíz recoge todas las alertas; las rutas hijas filtran por etiquetas y eligen un receptor.
receiversDestinos de notificación con nombre, cada uno con una o varias integraciones (correo, Slack, webhook...).
inhibit_rulesSilencian 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 #alerts y se repiten cada 4 horas (heredado de la ruta raíz).
  • Todo lo que no tenga un severity que 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.