Instalación de Grafana OnCall para Gestión de Incidentes

Grafana OnCall es una plataforma de gestión de incidentes de código abierto que centraliza las alertas de múltiples sistemas, permite definir calendarios de guardia y escala automáticamente las notificaciones hasta que alguien responde. Con integraciones nativas para Alertmanager, Grafana, PagerDuty, Slack, Telegram y decenas de otras herramientas, OnCall simplifica la coordinación de respuesta ante incidentes sin depender de servicios de pago. Esta guía cubre la instalación con Docker, la configuración de calendarios de guardia y las integraciones más comunes.

Requisitos Previos

  • Ubuntu 20.04/22.04 o CentOS 8+/Rocky Linux 8+
  • Docker 20.10+ y Docker Compose 2.x
  • Grafana 9.0+ instalado y en funcionamiento
  • 2 GB de RAM para OnCall
  • PostgreSQL o MySQL para la base de datos de OnCall

Instalación con Docker Compose

# docker-compose.yml para Grafana OnCall

version: "3.8"

services:
  engine:
    image: grafana/oncall:latest
    container_name: oncall-engine
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      DATABASE_TYPE: postgresql
      DATABASE_HOST: oncall-db
      DATABASE_PORT: 5432
      DATABASE_NAME: oncall
      DATABASE_USER: oncall
      DATABASE_PASSWORD: oncall_password_segura
      BROKER_TYPE: redis
      REDIS_URI: redis://oncall-redis:6379/0
      SECRET_KEY: tu_clave_secreta_aleatoria_y_larga
      DJANGO_SETTINGS_MODULE: settings.hobby
      BASE_URL: https://oncall.tudominio.com
      GRAFANA_API_URL: http://grafana:3000
      # Token de API de Grafana con permisos de admin
      GRAFANA_TOKEN: glsa_tu_token_de_grafana_aqui
    volumes:
      - oncall-data:/var/lib/oncall
    depends_on:
      - oncall-db
      - oncall-redis

  celery:
    image: grafana/oncall:latest
    container_name: oncall-celery
    restart: unless-stopped
    command: sh -c "celery -A engine worker --loglevel=info"
    environment:
      DATABASE_TYPE: postgresql
      DATABASE_HOST: oncall-db
      DATABASE_PORT: 5432
      DATABASE_NAME: oncall
      DATABASE_USER: oncall
      DATABASE_PASSWORD: oncall_password_segura
      BROKER_TYPE: redis
      REDIS_URI: redis://oncall-redis:6379/0
      SECRET_KEY: tu_clave_secreta_aleatoria_y_larga
      DJANGO_SETTINGS_MODULE: settings.hobby
    depends_on:
      - engine
      - oncall-db
      - oncall-redis

  oncall-db:
    image: postgres:15-alpine
    container_name: oncall-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: oncall
      POSTGRES_USER: oncall
      POSTGRES_PASSWORD: oncall_password_segura
    volumes:
      - oncall-db-data:/var/lib/postgresql/data

  oncall-redis:
    image: redis:7-alpine
    container_name: oncall-redis
    restart: unless-stopped
    volumes:
      - oncall-redis-data:/data

volumes:
  oncall-data:
  oncall-db-data:
  oncall-redis-data:
# Iniciar los servicios
docker compose up -d

# Ver logs de inicio
docker compose logs -f engine

# Ejecutar las migraciones de base de datos
docker compose exec engine python manage.py migrate

# Crear el superusuario inicial de OnCall
docker compose exec engine python manage.py createsuperuser

Configuración Inicial en Grafana

Primero, instala el plugin de OnCall en Grafana:

# Si Grafana está en un contenedor separado
docker exec grafana grafana-cli plugins install grafana-oncall-app
docker restart grafana

# Si Grafana está instalado como servicio
sudo grafana-cli plugins install grafana-oncall-app
sudo systemctl restart grafana-server
# Crear un token de API en Grafana para OnCall
# Grafana → Configuration → API Keys → New API Key
# Nombre: oncall-integration
# Role: Admin
# Guardar el token y añadirlo a la variable GRAFANA_TOKEN en docker-compose.yml

En la interfaz de Grafana:

  1. Ve a Plugins → Grafana OnCall
  2. Haz clic en Enable
  3. Configura la URL del backend de OnCall: http://oncall-engine:8080
  4. Haz clic en Connect

Usuarios y Turnos de Guardia

Configurar datos de contacto

Cada usuario debe configurar sus canales de notificación en OnCall → Usuarios → Tu perfil:

  • Teléfono: para notificaciones SMS y llamadas
  • Telegram: vincular cuenta de Telegram
  • Slack: vincular cuenta de Slack
  • Email: dirección de correo electrónico

Crear un calendario de guardia

  1. Ve a OnCall → Calendarios
  2. Haz clic en + Nuevo calendario
  3. Configura el nombre y la zona horaria
  4. Añade turnos haciendo clic en el calendario:
Turno semanal rotativo:
- Semana 1: Alice (lunes-domingo, 00:00-23:59)
- Semana 2: Bob (lunes-domingo, 00:00-23:59)
- Semana 3: Carlos (lunes-domingo, 00:00-23:59)

Turno diurno/nocturno:
- Diurno: Alice, Bob (lunes-viernes, 08:00-20:00)
- Nocturno: Carlos (lunes-viernes, 20:00-08:00)
- Fin de semana: David (sábado-domingo, 00:00-23:59)
# También via API REST de OnCall
curl -X POST http://oncall-engine:8080/api/v1/on_call_shifts/ \
  -H "Authorization: Token TU_TOKEN_ONCALL" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Turno semanal",
    "type": "rolling_users",
    "frequency": "weekly",
    "duration": 604800,
    "users": ["usuario_id_1", "usuario_id_2"],
    "week_start": "MO",
    "schedule": "calendario_id"
  }'

Políticas de Escalado

Las políticas de escalado definen quién notificar y cuándo, con reglas de reescalado automático:

  1. Ve a OnCall → Políticas de escalado
  2. Haz clic en + Nueva política
  3. Configura los pasos de escalado:

Ejemplo de política con reescalado:

PasoTiempoAcción
1InmediatoNotificar al usuario de guardia (notificación push/SMS)
2+5 minNotificar al usuario de guardia (llamada telefónica)
3+10 minNotificar al backup de guardia
4+20 minNotificar al manager de turno
5+30 minNotificar al canal de Slack del equipo
# Crear política de escalado via API
curl -X POST http://oncall-engine:8080/api/v1/escalation_chains/ \
  -H "Authorization: Token TU_TOKEN_ONCALL" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Escalado estándar de producción",
    "team_id": "equipo_id"
  }'

Integración con Alertmanager

Crea una integración de tipo Alertmanager en OnCall:

  1. Ve a OnCall → Integraciones → + Nueva integración
  2. Selecciona Alertmanager
  3. Copia la URL webhook generada

Configura Alertmanager para enviar alertas a OnCall:

# /etc/alertmanager/alertmanager.yml

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 12h
  receiver: 'oncall-default'

  routes:
    # Alertas críticas van directamente a OnCall
    - matchers:
        - severity=~"critical|page"
      receiver: oncall-critical
      continue: true

    # Alertas de warning van solo a Slack
    - matchers:
        - severity="warning"
      receiver: slack-solo

receivers:
  - name: oncall-default
    webhook_configs:
      - url: "https://oncall.tudominio.com/integrations/v1/alertmanager/TOKEN_AQUI/"
        send_resolved: true

  - name: oncall-critical
    webhook_configs:
      - url: "https://oncall.tudominio.com/integrations/v1/alertmanager/TOKEN_CRITICO/"
        send_resolved: true

  - name: slack-solo
    slack_configs:
      - api_url: "https://hooks.slack.com/services/..."
        channel: "#alertas-warning"
# Reiniciar Alertmanager
sudo systemctl restart alertmanager

# Verificar que OnCall recibe las alertas
docker compose logs -f engine | grep -i "alert"

Integración con Slack y Telegram

Slack

  1. Crea una aplicación en api.slack.com
  2. Añade permisos: chat:write, channels:read, users:read
  3. En OnCall → Configuración → Slack: introduce el Bot Token y el Signing Secret
# En OnCall, configurar el canal de Slack por defecto
# OnCall → Configuración → Slack → Canal por defecto: #on-call-alerts

Telegram

  1. Crea un bot en Telegram con @BotFather
  2. Obtén el token del bot
  3. En OnCall → Configuración → Telegram: introduce el token

Cada usuario puede vincular su Telegram en Perfil → Notificaciones → Añadir Telegram:

  • Busca el bot de OnCall en Telegram
  • Envía el comando /start
  • OnCall vincula automáticamente la cuenta

Rutas de Alerta

Las rutas determinan qué política de escalado usar según las características de la alerta:

  1. Ve a OnCall → Integraciones → [tu integración] → Rutas
  2. Crea rutas con condiciones:
# Ejemplos de condiciones de rutas (sintaxis Jinja2)
# Alertas de base de datos van al equipo de datos
{{ payload.labels.service == "postgresql" }}

# Alertas críticas usan escalado urgente
{{ payload.labels.severity == "critical" }}

# Alertas de un clúster específico
{{ "prod-cluster" in payload.labels.cluster }}

Solución de Problemas

OnCall no puede conectar con Grafana:

# Verificar el token de Grafana
curl http://grafana:3000/api/org \
  -H "Authorization: Bearer glsa_tu_token"

# Verificar la conectividad de red entre los contenedores
docker compose exec engine curl http://grafana:3000/api/health

Las alertas de Alertmanager no llegan:

# Verificar la URL del webhook desde Alertmanager
curl -X POST "https://oncall.tudominio.com/integrations/v1/alertmanager/TOKEN/" \
  -H "Content-Type: application/json" \
  -d '{"alerts": [{"labels": {"alertname": "test"}}]}'

# Revisar logs de OnCall
docker compose logs -f engine | grep -i "webhook\|alert"

Las notificaciones no se envían:

# Verificar que Celery está activo (gestiona el envío de notificaciones)
docker compose ps celery
docker compose logs celery | tail -50

# Verificar que el usuario tiene canales de notificación configurados
# OnCall → Usuarios → [usuario] → Canales de notificación

El plugin de Grafana muestra "Connection error":

# Verificar que OnCall está accesible desde Grafana
docker compose exec grafana curl http://oncall-engine:8080/api/v1/
# Debe devolver una respuesta JSON, no error de conexión

# Revisar las variables de entorno de OnCall
docker compose exec engine env | grep GRAFANA

Conclusión

Grafana OnCall centraliza la gestión de incidentes con una herramienta de código abierto que elimina la dependencia de servicios como PagerDuty para la mayoría de los casos de uso. La combinación de calendarios de guardia rotativa, políticas de escalado con múltiples pasos e integraciones bidireccionales con Slack y Telegram proporciona una respuesta ante incidentes completa y auditada. Integrado con el ecosistema Grafana, permite correlacionar alertas con dashboards y trazas en un único flujo de trabajo de resolución.