Data plane de telemetría
Los edges de Ongrid hablan al manager sobre dos paths físicos:
- Control plane — el túnel geminio (ADR-001 / ADR-007). Usado para lifecycle de edge, RPC, heartbeats, eventos de alerta y push de métrica (
push_prom_samples). - Telemetry data plane — POST HTTPS saliente directo del edge a los endpoints públicos de ingest del manager. Usado para logs (API de Loki) y trazas (OTLP).
Esta página explica la división, el modelo de autenticación y el trigger de migración para métricas.
Esta página es la referencia concisa. El record de decisión completo es ADR-014 en el árbol fuente.
La división
| Plano | Canal | Carga |
|---|---|---|
| Control plane | túnel geminio (ADR-001 existente) | lifecycle del edge, RPCs, heartbeats, eventos de alerta, push de métrica (por ahora) |
| Telemetry data plane | edge → HTTPS público del manager, conexiones salientes independientes | logs (ADR-012), trazas (ADR-013) |
Ambos planos son salientes desde el edge — el agente marca al manager. Sin puertos entrantes en el edge.
¿Por qué dividir?
El túnel geminio fue diseñado como un bus de control-RPC. Multiplexa llamadas RPC de baja latencia dentro de una conexión persistente. El push de métrica fue un "free ride" añadido en ADR-009 porque el volumen de métrica es pequeño (unos KB/s por edge) y el túnel tenía capacidad libre.
Logs y trazas no son pequeños.
| Señal | Per-edge steady state | Per-edge peak |
|---|---|---|
| metric | unos KB/s | ~10 KB/s |
| log | decenas de KB/s | 1–10 MB/s |
| trace | depende del sample rate | comparable a log |
100 edges × 1 MB/s = 100 MB/s sostenidos de ingress en el manager. El túnel no fue diseñado para eso. Forzar logs y trazas sobre él pega dos problemas:
- La CPU del manager se derrite. La codificación/decodificación de tunnel frames + forwarding a stores downstream pasa en el proceso Go. nginx + store downstream directamente es varias veces más barato.
- HOL blocking. Streams de bytes high-throughput compiten con RPCs de control en el mux. Los operadores experimentan jitter a nivel de segundo al preguntar "¿qué pasa con el edge 42?".
El túnel es control plane. El data plane es data plane. Mezclarlos fue un expediente bajo restricciones de NAT; la división hace el límite explícito.
Arquitectura
┌──────────────────────────────┐
┌──────────────┐ │ manager │
│ ongrid-edge │ │ │
│ │ │ nginx :443 ──► /api/* ───► ongrid (manager)
│ ┌─────────┐ │ geminio tunnel │ │
│ │ agent │ ├────► :40012 ──────►│ frontier (geminio broker) ──┤
│ └─────────┘ │ (control plane) │ │
│ │ │ nginx :443 ──► /loki/* ───► loki ← data plane
│ ┌─────────┐ │ │ ──► /v1/traces ─► tempo ← data plane
│ │promtail │ ├────► :443 ────────►│ ──► /api/v1/write─► prom (today)
│ └─────────┘ │ (data plane) │ │
│ │ │ edgeauth verifies the token │
│ ┌─────────┐ │ │ via /internal/auth/ │
│ │otelcol │ ├────► :443 ────────►│ dataplane-verify before │
│ └─────────┘ │ (data plane) │ proxying. │
└──────────────┘ └──────────────────────────────┘El agente usa una conexión TLS por plugin (promtail, otelcol-contrib). Todas son salientes desde el edge a ONGRID_PUBLIC_URL.
Autenticación
Una raíz de confianza, dos paths.
El par access-key/secret-key del edge autentica el túnel vía credenciales de sesión de geminio. El mismo par de credenciales se intercambia por un Bearer token usado en cada POST HTTPS del data-plane. La directiva auth_request de nginx llama de vuelta al manager en /internal/auth/dataplane-verify para validar el token; ante 200, el request se proxiya a Loki o Tempo. Ante 401/403, el edge ve un error HTTP y hace backoff.
Esto significa:
- Rotar la
secret_keydel edge invalida ambos planos simultáneamente. - No hay segundo store de secretos, sin credencial por-plugin, sin ACL separada.
- El manager posee la auth — Loki y Tempo nunca ven identidad de edge directamente.
El Bearer token es de corta vida. El agente lo refresca transparentemente sobre el túnel; un edge cuyo túnel está down por un período extendido verá los POSTs del data-plane empezar a 401 una vez que el token expire, lo que fuerza un reconnect del túnel.
Compatibilidad NAT
HTTPS saliente al puerto público del manager es la misma clase de red que el túnel saliente — ambos se originan desde el edge a un rango de puerto destino único (443 para data, 40012 para túnel). Ambos pasan a través de firewalls de egreso corporativos ordinarios. Sin carve-outs especiales, sin reglas entrantes.
Para edges NAT-only que solo pueden abrir una conexión saliente, geminio tiene un fallback de raw-stream (payloads de log zstd-compressed, buffer acotado, drop-old en overflow). Esta es una escape hatch, no el default — no hemos tenido que enviarla a un cliente todavía.
¿Qué pasa con las métricas?
push_prom_samples está todavía en el túnel hoy.
| Por qué la mantuvimos en el túnel |
|---|
| El volumen de métrica per-edge está muy por debajo de saturación. |
| El path existente funciona; el costo de migración supera el beneficio actual. |
push_prom_samples se ejercita en cada release; tocarlo es arriesgado. |
Moveremos las métricas al data plane (remote_write de Prometheus directamente a https://<manager>/api/v1/write) cuando cualquiera de las siguientes se mantenga:
- CPU sostenida del túnel de un único manager > 60%.
- Tasa de push de métrica sostenida de un único edge > 100 KB/s (casi siempre significa cardinalidad runaway — arregla eso primero; si persiste después, migra).
- Latencia P95 de RPC de control se degrada > 500ms bajo presión de stream de métrica.
El cliente remote_write de Prometheus ya está en node_exporter y el plugin de métrica del edge puede ser re-apuntado vía env. El trigger arriba solo establece la prioridad.
Implementación del edge
En disco, el agente envía cada sender de telemetría a través de internal/edgeagent/dataplane/. Ese package centraliza:
- Reutilización de token desde la credencial de sesión del túnel.
- Routing dual-destination (túnel para control, HTTPS para data).
- Retry + backoff exponencial con jitter, topado en 1 minuto.
- Queue acotada local (in-memory; el agente no spoolea a disco).
Cada plugin (promtail, otelcol-contrib, futuros) consume este package — no hay lógica de retry / auth por-plugin. Eso mantiene a ongrid-edge como un único binario más cuatro subprocesos; sin sidecar por-plugin, sin unit systemd por-plugin.
Lo que afinas
| Variable | Dónde | Efecto |
|---|---|---|
ONGRID_PUBLIC_URL | manager | La URL entregada a los edges como raíz del data-plane. Requerida para que el data plane funcione. |
ONGRID_LOG_QUERY_URL | manager | Path de lectura — manager → Loki para la página de Logs. Independiente del push del edge. |
ONGRID_TRACE_QUERY_URL | manager | Path de lectura — manager → Tempo para la página de Trazas. |
ONGRID_EDGE_PLUGIN_BIN_DIR | edge | Dónde viven los binarios de plugin (promtail, otelcol-contrib). |
ONGRID_EDGE_PLUGIN_WORK_DIR | edge | Dirs runtime por-plugin (configs, PID, queue spool). |
ONGRID_PUBLIC_URL es el setting de producción más importante en el lado del manager. Vacío deshabilita el data plane totalmente — los edges conectan sobre el túnel, el agente bootea, pero logs y trazas nunca se envían.
Ver también
- Arquitectura — diagrama de sistema completo.
- Capacidades → Logs — tour de operador del plane de logs.
- Capacidades → Trazas — tour de operador del plane de trazas.
- Variables de entorno — las perillas que cablean todo esto.