Плоскость данных телеметрии
Edges Ongrid говорят с manager'ом по двум физическим путям:
- Control plane — geminio-туннель (ADR-001 / ADR-007). Используется для жизненного цикла edge, RPC, heartbeat'ов, событий алертов и push'а метрик (
push_prom_samples). - Telemetry data plane — прямой исходящий HTTPS POST от edge к публичным ingest-эндпоинтам manager'а. Используется для логов (Loki API) и трейсов (OTLP).
Эта страница объясняет разделение, модель аутентификации и триггер миграции для метрик.
Эта страница — краткий справочник. Полный decision record — ADR-014 в дереве исходного кода.
Разделение
| Плоскость | Канал | Несёт |
|---|---|---|
| Control plane | geminio-туннель (существующий ADR-001) | жизненный цикл edge, RPC, heartbeat'ы, события алертов, push метрик (пока что) |
| Telemetry data plane | edge → manager публичный HTTPS, независимые исходящие соединения | логи (ADR-012), трейсы (ADR-013) |
Обе плоскости исходящие от edge — агент дозванивается до manager'а. Никаких входящих портов на edge.
Зачем разделять?
Geminio-туннель был спроектирован как шина control-RPC. Он мультиплексирует RPC-вызовы с низкой задержкой внутри одного persistent-соединения. Push метрик был "бесплатной поездкой", добавленной в ADR-009, потому что объём метрик мал (несколько KB/s на edge) и у туннеля была свободная ёмкость.
Логи и трейсы — не маленькие.
| Сигнал | Steady state per-edge | Пик per-edge |
|---|---|---|
| metric | несколько KB/s | ~10 KB/s |
| log | десятки KB/s | 1–10 MB/s |
| trace | зависит от sample rate | сопоставимо с log |
100 edges × 1 MB/s = 100 MB/s sustained ingress на manager'е. Туннель не был спроектирован для этого. Принуждение логов и трейсов идти через него упирается в две проблемы:
- CPU manager'а плавится. Encoding/decoding фреймов туннеля + форвардинг к downstream-хранилищам происходит в Go-процессе. nginx + downstream-хранилище напрямую в несколько раз дешевле.
- HOL blocking. Высокопропускные байтовые потоки конкурируют с control RPC на mux'е. Операторы испытывают секундный джиттер, когда спрашивают "что не так с edge 42?".
Туннель — это control plane. Data plane — это data plane. Их смешение было ad-hoc решением под ограничениями NAT; разделение делает границу явной.
Архитектура
┌──────────────────────────────┐
┌──────────────┐ │ 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. │
└──────────────┘ └──────────────────────────────┘Агент использует одно TLS-соединение на плагин (promtail, otelcol-contrib). Все они — исходящие от edge к ONGRID_PUBLIC_URL.
Аутентификация
Один trust-корень, два пути.
Пара access-key/secret-key edge'а аутентифицирует туннель через session-credentials geminio. Та же пара credential'ов обменивается на Bearer-токен, используемый на каждом data-plane HTTPS POST'е. Директива auth_request nginx коллбэкает в manager на /internal/auth/dataplane-verify для валидации токена; на 200 запрос проксируется к Loki или Tempo. На 401/403 edge видит HTTP-ошибку и отступает.
Это значит:
- Ротация
secret_keyedge'а инвалидирует обе плоскости одновременно. - Нет второго хранилища секретов, нет per-plugin credential, нет отдельного ACL.
- Manager владеет auth — Loki и Tempo никогда не видят identity edge'а напрямую.
Bearer-токен короткоживущий. Агент обновляет его прозрачно через туннель; edge, чей туннель не работает продолжительное время, увидит, как data-plane POST'ы начинают давать 401 после истечения токена, что вынуждает переподключение туннеля.
Совместимость с NAT
Исходящий HTTPS к публичному порту manager'а — это тот же сетевой класс, что и исходящий туннель — оба инициируются от edge к единому диапазону destination-портов (443 для data, 40012 для туннеля). Оба проходят через обычные corporate egress-firewall'ы. Никаких специальных carve-out'ов, никаких входящих правил.
Для NAT-only edges, которые могут открыть только одно исходящее соединение, у geminio есть fallback на raw-stream (zstd-сжатые log payload'ы, ограниченный буфер, drop-old при переполнении). Это запасной выход, не дефолт — мы ещё не должны были поставлять его клиенту.
А что с метриками?
push_prom_samples всё ещё на туннеле сегодня.
| Почему мы оставили это на туннеле |
|---|
| Объём метрик per-edge далеко ниже насыщения. |
| Существующий путь работает; стоимость миграции перевешивает текущую выгоду. |
push_prom_samples упражняется в каждом релизе; трогать его рискованно. |
Мы переместим метрики в data plane (Prometheus remote_write напрямую на https://<manager>/api/v1/write), когда выполнится любое одно из следующего:
- CPU туннеля одного manager'а sustained > 60%.
- Скорость push'а метрик одного edge'а sustained > 100 KB/s (почти всегда означает runaway cardinality — сначала исправьте это; если сохраняется после, мигрируйте).
- Latency P95 control RPC деградирует > 500ms под давлением metric-stream.
Клиент Prometheus remote_write уже есть в node_exporter, и плагин метрик edge можно переориентировать через env. Триггер выше просто задаёт приоритет.
Реализация на edge
На диске агент отправляет каждый sender телеметрии через internal/edgeagent/dataplane/. Этот пакет централизует:
- Переиспользование токена из session-credential туннеля.
- Маршрутизация по двум destination'ам (туннель для control, HTTPS для data).
- Retry + экспоненциальный backoff с джиттером, ограниченный 1 минутой.
- Локальная ограниченная очередь (in-memory; агент не сбрасывает на диск).
Каждый плагин (promtail, otelcol-contrib, будущие) потребляет этот пакет — нет per-plugin retry/auth-логики. Это держит ongrid-edge единым бинарём плюс четыре subprocess'а; нет per-plugin sidecar'а, нет per-plugin systemd-юнита.
Что вы настраиваете
| Переменная | Где | Эффект |
|---|---|---|
ONGRID_PUBLIC_URL | manager | URL, выдаваемый edges как корень data-plane. Обязателен для работы data plane. |
ONGRID_LOG_QUERY_URL | manager | Read-путь — manager → Loki для страницы Логов. Независимо от push'а edge. |
ONGRID_TRACE_QUERY_URL | manager | Read-путь — manager → Tempo для страницы Трейсов. |
ONGRID_EDGE_PLUGIN_BIN_DIR | edge | Где живут бинари плагинов (promtail, otelcol-contrib). |
ONGRID_EDGE_PLUGIN_WORK_DIR | edge | Per-plugin runtime-директории (configs, PID, queue spool). |
ONGRID_PUBLIC_URL — единственная самая важная production-настройка на стороне manager'а. Пустое полностью отключает data plane — edges подключаются по туннелю, агент стартует, но логи и трейсы никогда не отправляются.
См. также
- Архитектура — полная системная диаграмма.
- Возможности → Логи — operator-тур по log-плоскости.
- Возможности → Трейсы — operator-тур по trace-плоскости.
- Environment-переменные — крутилки, которые всё это связывают.