Skip to content

Архитектура

Ongrid — четырёхслойная система. Edge запускается на каждом мониторимом хосте; manager — это облако. Они общаются по одному исходящему туннелю (control plane) плюс отдельному auth-gated direct upload-пути для телеметрии (data plane).

4-слойная модель

text
┌──────────────────────────────────────────────────────────────────┐
│ L4  Alert / notification                                         │
│      built-in rules + custom kinds → channels (Slack / TG / IM)  │
├──────────────────────────────────────────────────────────────────┤
│ L3  Intelligence (graph-kernel ReAct agent)                      │
│      coordinator → specialist sub-agents → ~30 skills            │
├──────────────────────────────────────────────────────────────────┤
│ L2  Observability triad + edge direct path                       │
│      Prometheus · Loki · Tempo  +  push_host_metrics RPC         │
├──────────────────────────────────────────────────────────────────┤
│ L1  Cluster (signal collection)                                  │
│      ongrid-edge + plugins on every host                         │
└──────────────────────────────────────────────────────────────────┘
  • L1 — Кластер. Откуда приходят сигналы. Один ongrid-edge на хост, плюс его subprocess-плагины (promtail, node_exporter, process_exporter, otelcol-contrib).
  • L2 — Observability-триада. Prometheus / Loki / Tempo хранят сигналы. Они отгружаются в docker-compose; тот же UI работает против внешних managed-эквивалентов (Grafana Cloud, Mimir, VictoriaMetrics), если вы переключите их из Settings. Отдельный edge direct path несёт push_host_metrics через туннель для low-cardinality closed-set host-метрик (это то, что питает встроенные CPU / mem / disk / load алерты, даже до того, как Prom сконфигурирован).
  • L3 — Intelligence. Graph-kernel ReAct-агент: coordinator декомпозирует вопрос, диспетчирует на specialist sub-agents, вызывает скиллы, синтезирует ответ.
  • L4 — Алерты и уведомления. Встроенные правила + custom kinds оценивают против стримов L2 / L1, срабатывают в каналы (Slack, Telegram, Larksuite, DingTalk, WeCom, сырой webhook).

Стратегическая ставка — L1 + L2 edge direct path: один tarball, один исходящий туннель, host-метрики, текущие без round-trip к Prom. Это то, что делает 10-минутную установку реально 10-минутной.

Edge → frontier → manager

text
   host (yours)                  cloud (yours, self-hosted)
 ┌──────────────────┐
 │ ongrid-edge      │
 │ ├─ plugins/      │           ┌─────────────────────────────┐
 │ │  promtail      │           │ frontier (broker, port 40012)│
 │ │  node_exporter │           │  · multiplexed geminio       │
 │ │  process_exp.  │── one ───▶│  · auth: access/secret key   │
 │ │  otelcol       │  outbound │  · service-end → manager     │
 │ └─ runtime       │   TCP     └──────────────┬──────────────┘
 │    geminio client│   :40012                 │ service-end (40011)
 └──────────────────┘                          ▼
                                 ┌─────────────────────────────┐
                                 │ ongrid (manager)            │
                                 │  · http API (nginx 443)     │
                                 │  · bounded contexts         │
                                 │  · agent runtime            │
                                 └──────────────┬──────────────┘


                                       Prom / Loki / Tempo /
                                       MySQL / Qdrant /
                                       SearXNG / Grafana
  • Одно TCP-соединение на хост. ongrid-edge дозванивается до frontier:40012 исходящим. Ничего входящего. Без port-forward, без jumpbox, без reverse-tunnel SaaS.
  • Geminio мультиплексирует. Много логических RPC-стримов едут на одном TCP- соединении. Двунаправленно: manager может вызывать в edge (bash, host_probe_*, query_processes), а edge может вызывать в manager (push_host_metrics, report_register).
  • Frontier — это брокер. Upstream singchia/frontier, отгружается в release-tarball. ADR-007 — это rationale (мы не переизобретаем то, что внешний брокер уже делает).
  • Manager — это один Go-бинарь. Десяток bounded contexts (edges, alerts, incidents, agent, knowledge, channels, identity, audit…), все за nginx front-door.

Data plane vs. control plane

У edge'ей два различных egress-пути в облако, by design:

text
 ┌──────── ongrid-edge ────────┐
 │                              │
 │  ┌──────── runtime ────────┐ │     ── control plane ──▶ frontier:40012
 │  │ geminio client (RPC)    │ │       (TLS-by-default if cert provided)
 │  └─────────────────────────┘ │       multiplex, bidirectional, low rate
 │                              │
 │  ┌──────── plugins ────────┐ │     ── data plane ──▶ nginx :443
 │  │ promtail   → Loki push  │ │       https POST per batch
 │  │ otelcol    → OTLP push  │ │       auth_request → manager edgeauth
 │  │ exporters  → /metrics   │ │       high rate, large payloads
 │  └─────────────────────────┘ │
 │                              │
 └──────────────────────────────┘

Зачем разделение? ADR-014. Логи + трейсы — высокообъёмные, large-batch, естественно HTTP. Мультиплексирование их в туннель убивает throughput под нагрузкой. Прямой push через nginx auth_request держит security- постуру (только зачисленные edge'и могут пушить), сохраняя плоскость данных быстрой.

Что всё ещё едет в туннеле?

  • Метрики — в настоящее время всё ещё RPC push_host_metrics поверх geminio. Прямой remote_write от edge к Prometheus — на roadmap, когда размеры кластеров это оправдают. До тех пор объём метрик терпим.
  • Все RPC — query_processes, bash, query_logs_tail, host_probe_*, expand_topology, file reads, WebShell.

Карта контейнеров (docker-compose)

Что sudo ./install.sh поднимает на manager-хосте:

КонтейнерImageHost-портыРоль
ongridongrid:<version>9100 (metrics)Manager. Go-бинарь; HTTP API на :8080, проксированный nginx.
ongrid-nginxongrid-web:<version>443, 80TLS-терминатор + SPA + reverse proxy. Сервит /api/*, /grafana/*, /install.sh, /edge/*.
ongrid-mysqlmysql:8.03306Всё operational-состояние (edge'и, алерты, пользователи, audit log, channel-конфиги).
ongrid-frontiersingchia/frontier:1.2.540012Geminio-брокер. Edge'и дозваниваются 40012; manager дозванивается 40011 через compose-сеть.
ongrid-prometheusprom/prometheus:v2.54.0(нет)TSDB. Принимает remote_write от manager, запросы от скилла query_promql.
ongrid-lokigrafana/loki:3.4.0(нет)Backend логов. Push на /loki/api/v1/push через nginx auth-gate.
ongrid-tempografana/tempo:2.5.0(нет)Backend трейсов. OTLP push на /v1/traces через nginx auth-gate.
ongrid-grafanagrafana/grafana-oss:11.1.43000Дашборды. Встроены как iframe под /grafana/ в SPA.
ongrid-qdrantqdrant/qdrant(нет)Vector store для базы знаний.
ongrid-searxngsearxng/searxng(нет)Self-hosted meta-search для скилла web_search.

Все stateful-сервисы bind-mount'ятся к host-путям под /var/lib/ongrid/, не docker named volumes — операторы могут бэкапить и инспектировать файлы без docker-гимнастики. Override data root с ONGRID_DATA_DIR и log root с ONGRID_LOG_DIR.

Manager — bounded contexts

Manager-бинарь — один Go-процесс. Внутренне он разбит на bounded contexts (каждый владеет своей DB-схемой, своими HTTP-маршрутами, своими background workers). Грубо:

text
┌─────────┐   ┌─────────┐   ┌─────────────┐   ┌──────────────┐
│ identity│   │ edge    │   │ alert       │   │ incident     │
│ ┌─────┐ │   │ ┌─────┐ │   │ ┌─────────┐ │   │ ┌──────────┐ │
│ │users│ │   │ │edges│ │   │ │rules    │ │   │ │incidents │ │
│ │roles│ │   │ │tnls │ │   │ │events   │ │   │ │timeline  │ │
│ │JWT  │ │   │ │keys │ │   │ │evaluator│ │   │ │investig. │ │
│ └─────┘ │   │ └─────┘ │   │ └─────────┘ │   │ └──────────┘ │
└─────────┘   └─────────┘   └─────────────┘   └──────────────┘

┌─────────┐   ┌──────────┐   ┌─────────┐   ┌──────────┐   ┌─────────┐
│ agent   │   │ knowledge│   │ channels│   │ audit    │   │ skills  │
│ kernel  │   │ vault+   │   │ slack/  │   │ events / │   │ registry│
│ + sub-  │   │ embed+   │   │ telegram│   │ chains   │   │ marketp.│
│ agents  │   │ search   │   │ /lark/dt│   │          │   │         │
└─────────┘   └──────────┘   └─────────┘   └──────────┘   └─────────┘

Inter-BC трафик — через Go function calls (biz-слой) — нет RPC внутри бинаря. Arch lint (make arch-lint) форсит направление зависимостей (cmd → service → biz → data, без циклов).

Edge — plugin runtime

ongrid-edge — один Go-бинарь, который контролирует небольшой флот subprocess'ов. Каждый subprocess — это off-the-shelf collector, перекрашенный как «плагин»:

text
ongrid-edge (PID 1)
 ├─ geminio runtime  ← control plane to frontier
 ├─ plugin: logs
 │   └─ promtail subprocess
 │       config: /etc/ongrid-edge/promtail.yaml
 │       data plane: https://<manager>/loki/api/v1/push
 ├─ plugin: traces
 │   └─ otelcol-contrib subprocess
 │       config: /etc/ongrid-edge/otelcol.yaml
 │       data plane: https://<manager>/v1/traces
 ├─ plugin: hostmetrics
 │   └─ node_exporter subprocess
 │       /metrics scraped by Prometheus inside the manager
 └─ plugin: procmetrics
     └─ process_exporter subprocess

ADR-015 — rationale: каждый collector — best-of-breed в своей экосистеме; переизобретать их как Go-либы безнадёжно. Так что edge владеет runtime-контрактом (config delivery, healthcheck, log capture, upgrade) и shell out'ит для фактической работы с данными.

Апгрейды — stage-then-swap

ADR-024 управляет whole-bundle апгрейдами. Поток:

  1. Оператор кладёт edge-bundle-<arch>-<ver>.tar.gz + .sha256 в /opt/ongrid/edge/ на manager (release-tarball'а install.sh и upgrade.sh оба это делают).
  2. Оператор триггерит «upgrade all edges» из UI. Manager отправляет MethodFetchPackage через туннель.
  3. Edge скачивает bundle, верифицирует sha256, stage'ит файлы в /var/lib/ongrid-edge/.upgrade/incoming/.
  4. Edge пишет marker, чисто выходит. systemd рестартит его.
  5. На рестарте apply-pending-upgrade.sh запускается как root (через ExecStartPre с +) — верифицирует sha каждого файла, бэкапит <dest> в <dest>.previous, атомарно mv-ит новый файл в место.
  6. Если новый агент не пишет healthy_marker до следующего рестарта, apply-pending-upgrade.sh автоматически откатывает каждый .previous.

Поэтому edge-апгрейд — это просто «restart the unit» — без хрупкого in-process rewire.

Где что живёт на диске

На manager:

ПутьЧто
/opt/ongrid/Compose-файл, конфиги, сертификаты, .env, edge-артефакты.
/opt/ongrid/.envСекреты + tunables (mode 0600).
/opt/ongrid/certs/tls.crt, tls.key для nginx. Замените для prod.
/opt/ongrid/edge/Edge upgrade-bundle'ы + per-arch loose-бинари.
/var/lib/ongrid/Bind-mount root для stateful-контейнеров.
/var/log/ongrid/Manager и nginx log-файлы.

На edge:

ПутьЧто
/usr/local/bin/ongrid-edgeБинарь агента.
/usr/local/lib/ongrid-edge/Бинари плагинов + apply-pending-upgrade.sh.
/etc/ongrid-edge/ongrid-edge.env (access/secret keys), конфиги плагинов.
/var/lib/ongrid-edge/.upgrade/Stage'нутый upgrade incoming + markers.
/var/log/ongrid-edge/Plugin stdout/stderr capture. Journal владеет agent-логами.
/etc/systemd/system/ongrid-edge.serviceSystemd unit.

Где почитать больше