Sistema de alarmas de PROD (vmalert + Alertmanager)
Runbook del alerting de producción: arquitectura, reglas, secret, proxies NetBird y operación. Hito A del Plan Hardening (s95, 29-05-2026). PRs #49/#50/#51.
Arquitectura
web /metrics → (scrape) → VictoriaMetrics → (query) → vmalert → (fire) → Alertmanager → (SMTP) → Resend → logcrearack@esfericlabs.com
- VictoriaMetrics hace scrape de
web:8000/metrics(django-prometheus) cada 60s vía--promscrape.config(observability/victoriametrics/scrape.yml). Antes solo recibía push (ping/snmp/http de targets de clientes); sin scrape no había métricas de salud de la app. - vmalert evalúa
observability/victoriametrics/alerts.ymlcada 30s y dispara a Alertmanager. - Alertmanager entrega por email vía Resend SMTP (
smtp.resend.com:587, STARTTLS, remitenteCreaRack Pro <noreply@crearack.com>). Configobservability/alertmanager/alertmanager.yml.
Reglas activas (5)
| Alerta | Condición | Severidad |
|---|---|---|
CreaRackDown | up{job="crearack-web"}==0 1m | critical |
HighResponseTime | p95 latencia > 2s, 5m | warning |
HighErrorRate | 5xx excluyendo 501 > 5%, 5m | warning |
DatabaseConnectionError | django_db_errors_total > 10, 2m | critical |
HighMemoryUsage | RSS > 3GB, 15m | warning |
Por qué se excluye el 501 (v1.81.2, 22-08-2026): CreaRack responde 501 a propósito a las sondas WebDAV (OPTIONS/PROPFIND) de los reproductores SpinetiX contra /publish/<token>/ — fuerza el fallback spx-listing.xml (signage/views_publish.publish_root). Es protocolo correcto, no un error, pero contaba como 5xx en la métrica y un player sondeando en horas de poco tráfico disparaba la alarma. Los 5xx reales (500/502/503/504) siguen contando igual.
Piezas y footguns
- Scrape + ALLOWED_HOSTS: el scrape entra con
Host: web:8000.config/settings/production.pyincluyewebenALLOWED_HOSTS; sin él Django responde 400 →up=0→ falsa alarmaCreaRackDown. - Secret Resend: la API key NO está en git. Vive en
files/smtp_passwordde cada Dokploy (bind../files/smtp_password,smtp_auth_password_file). Permisos 644 (Alertmanager corre comonobody; con 600 dapermission denied). STAGE y PROD tienen Dokploy independiente; STAGE usa dummy (no envía email). - Panel por NetBird:
--web.external-url=http://crearack-prod.netbird.cloud:9093. El panel se expone a la VPN consocatsobrewt0. - Footgun socat: los proxies socat apuntan a la IP interna del contenedor, que cambia en cada recreate/deploy.
scripts/netbird-proxies.sh(idempotente) los relanza re-resolviendo IPs. Ejecutar tras cada deploy. - ⚠️ Footgun bind de FICHERO (22-08-2026):
alerts.ymlse monta en vmalert a nivel de fichero (Source: .../code/observability/victoriametrics/alerts.yml→/etc/alerts/alerts.yml, ro). El checkout de un deploy reemplaza el inode → el contenedor (que puede llevar semanas Up, Dokploy no lo recrea si su imagen no cambia) sigue viendo el contenido viejo, y unSIGHUPrecarga… lo viejo. Tras cualquier cambio enalerts.yml:docker restart crearack-pro-zcmvsl-vmalert-1(corte de segundos en la evaluación, sin impacto en la app) y verificar la regla en memoria víacurl http://<ip-vmalert>:8880/api/v1/rules. Descubierto al desplegar v1.81.2: la exclusión del 501 no entraba ni con SIGHUP.
Operar
- Ver/silenciar alarmas:
http://crearack-prod.netbird.cloud:9093(con NetBird conectado). - Tras un deploy (recrea contenedores → rompe proxies):
bash <app>/code/scripts/netbird-proxies.shen el servidor. - Tras cambiar
alerts.yml: además,docker restartdel contenedor vmalert + verificar la regla en memoria (ver footgun bind de fichero). - Rotar el secret Resend: actualizar
files/smtp_password(key nueva,chmod 644) +docker compose -p <proj> -f compose.prod.yml up -d --force-recreate alertmanager. - Probar el email:
POSTuna alerta de prueba a/api/v2/alertsdel Alertmanager → confirmar quealertmanager_notifications_total{integration="email"}sube yfailed_totalno.
Troubleshooting
| Síntoma | Causa | Fix |
|---|---|---|
up{crearack-web}=0 con la app sana | Host web no en ALLOWED_HOSTS (400) | añadir web a ALLOWED_HOSTS + rebuild web |
permission denied al enviar email | secret con permisos 600 | chmod 644 files/smtp_password |
| Botón “View in Alertmanager” roto | falta --web.external-url o socat 9093 caído | external-url + netbird-proxies.sh |
| Acceso NetBird a VM/AM roto tras deploy | IPs de contenedor cambiaron | netbird-proxies.sh |
HighErrorRate FIRING/RESOLVED cada hora sin errores reales | player SpinetiX sondeando /publish/<token>/ (501 deliberado; con token viejo, ráfaga de reintentos a la hora en punto) | desde v1.81.2 el 501 no cuenta; re-apuntar el player físico a su publish URL vigente (caso 21/22-08-2026: HMP400 del CCIB con token de un alta borrada) |
Un cambio en alerts.yml desplegado no surte efecto | bind a nivel de fichero: vmalert ve el inode viejo; SIGHUP recarga lo viejo | docker restart de vmalert + verificar /api/v1/rules |
Hito A · Plan Hardening post-Máster · s95 (29-05-2026). Última actualización: 22-08-2026 (v1.81.2, exclusión del 501 + footgun bind de fichero).
Véase también
- [[entity—observability—service—vmalert]]
- [[entity—observability—service—alertmanager]]
- [[feature—observability—alerting-prod-s95]]