Arquitetura
O Ongrid é um sistema de quatro camadas. O edge roda em todo host monitorado; o manager é a nuvem. Eles se comunicam por um tunnel outbound (o control plane) mais um caminho de upload direto auth-gated separado para telemetria (o data plane).
O modelo de 4 camadas
┌──────────────────────────────────────────────────────────────────┐
│ L4 Alerta / notificação │
│ regras built-in + kinds custom → canais (Slack / TG / IM) │
├──────────────────────────────────────────────────────────────────┤
│ L3 Inteligência (agent ReAct de graph-kernel) │
│ coordinator → specialist sub-agents → ~30 skills │
├──────────────────────────────────────────────────────────────────┤
│ L2 Tríade de observabilidade + caminho direto do edge │
│ Prometheus · Loki · Tempo + RPC push_host_metrics │
├──────────────────────────────────────────────────────────────────┤
│ L1 Cluster (coleta de sinal) │
│ ongrid-edge + plugins em cada host │
└──────────────────────────────────────────────────────────────────┘- L1 — Cluster. De onde os sinais vêm. Um
ongrid-edgepor host, mais seus plugins subprocess (promtail,node_exporter,process_exporter,otelcol-contrib). - L2 — Tríade de observabilidade. Prometheus / Loki / Tempo armazenam os sinais. Vêm no docker-compose; a mesma UI funciona contra equivalentes externos gerenciados (Grafana Cloud, Mimir, VictoriaMetrics) se você trocar a partir de Settings. Um caminho direto do edge separado carrega
push_host_metricspelo tunnel para métricas de host de baixa cardinalidade de conjunto fechado (é o que alimenta os alertas built-in de CPU / mem / disco / load mesmo antes do Prom ser configurado). - L3 — Inteligência. O agent ReAct de graph-kernel: coordinator decompõe a pergunta, despacha a sub-agents specialist, chama skills, sintetiza uma resposta.
- L4 — Alertas & notificações. Regras built-in + kinds custom avaliam contra streams L2 / L1, disparam em canais (Slack, Telegram, Larksuite, DingTalk, WeCom, webhook cru).
A aposta estratégica é L1 + caminho direto L2: um único tarball, um tunnel outbound, métricas de host fluindo sem um round-trip do Prom. É o que faz a instalação de 10 minutos ser de fato 10 minutos.
Edge → frontier → manager
host (seu) cloud (sua, self-hosted)
┌──────────────────┐
│ ongrid-edge │
│ ├─ plugins/ │ ┌─────────────────────────────┐
│ │ promtail │ │ frontier (broker, port 40012)│
│ │ node_exporter │ │ · geminio multiplex │
│ │ 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- Uma conexão TCP por host.
ongrid-edgedisca parafrontier:40012outbound. Nada inbound. Sem port-forward, sem jumpbox, sem reverse-tunnel SaaS. - Multiplex Geminio. Muitos streams RPC lógicos rodam em uma conexão TCP. Bidirecional: o manager pode chamar para dentro do edge (
bash,host_probe_*,query_processes) e o edge pode chamar para dentro do manager (push_host_metrics,report_register). - Frontier é o broker. Upstream singchia/frontier, distribuído no tarball de release. ADR-007 é a justificativa (não reimplementamos o que um broker externo já faz).
- Manager é um único binário Go. Cerca de dez bounded contexts (edges, alerts, incidents, agent, knowledge, channels, identity, audit…), todos atrás da porta da frente do nginx.
Data plane vs control plane
Edges têm dois caminhos de egress distintos para a nuvem, por design:
┌──────── ongrid-edge ────────┐
│ │
│ ┌──────── runtime ────────┐ │ ── control plane ──▶ frontier:40012
│ │ geminio client (RPC) │ │ (TLS-por-padrão se cert fornecido)
│ └─────────────────────────┘ │ multiplex, bidirecional, low rate
│ │
│ ┌──────── plugins ────────┐ │ ── data plane ──▶ nginx :443
│ │ promtail → Loki push │ │ https POST por batch
│ │ otelcol → OTLP push │ │ auth_request → manager edgeauth
│ │ exporters → /metrics │ │ high rate, payloads grandes
│ └─────────────────────────┘ │
│ │
└──────────────────────────────┘Por que o split? ADR-014. Logs + traces são de alto volume, batch grande, naturalmente HTTP. Multiplexá-los no tunnel mata o throughput sob carga. Push direto sobre nginx auth_request mantém a postura de segurança (só edges enrolled podem fazer push) mantendo o data plane rápido.
O que ainda anda pelo tunnel?
- Métricas — atualmente ainda RPC
push_host_metricspor geminio.remote_writedireto de edge a Prometheus está no roadmap quando tamanhos de cluster justificarem. Até lá o volume de métrica é tolerável. - Todos os RPCs —
query_processes,bash,query_logs_tail,host_probe_*,expand_topology, leituras de arquivo, WebShell.
Mapa de containers (docker-compose)
O que sudo ./install.sh sobe no host manager:
| Container | Imagem | Portas no host | Papel |
|---|---|---|---|
ongrid | ongrid:<version> | 9100 (metrics) | O manager. Binário Go; API HTTP em :8080 proxiada pelo nginx. |
ongrid-nginx | ongrid-web:<version> | 443, 80 | Terminador TLS + SPA + reverse proxy. Serve /api/*, /grafana/*, /install.sh, /edge/*. |
ongrid-mysql | mysql:8.0 | 3306 | Todo estado operacional (edges, alerts, users, audit log, configs de canal). |
ongrid-frontier | singchia/frontier:1.2.5 | 40012 | Broker geminio. Edges discam 40012; manager disca 40011 pela rede do compose. |
ongrid-prometheus | prom/prometheus:v2.54.0 | (nenhuma) | TSDB. Recebe remote_write do manager, queries da skill query_promql. |
ongrid-loki | grafana/loki:3.4.0 | (nenhuma) | Backend de logs. Push em /loki/api/v1/push via auth-gate do nginx. |
ongrid-tempo | grafana/tempo:2.5.0 | (nenhuma) | Backend de traces. Push OTLP em /v1/traces via auth-gate do nginx. |
ongrid-grafana | grafana/grafana-oss:11.1.4 | 3000 | Dashboards. Embarcados como iframes sob /grafana/ no SPA. |
ongrid-qdrant | qdrant/qdrant | (nenhuma) | Vector store para a base de conhecimento. |
ongrid-searxng | searxng/searxng | (nenhuma) | Meta-search self-hosted para a skill web_search. |
Todos os serviços com estado fazem bind-mount em paths do host sob /var/lib/ongrid/, não em volumes nomeados do docker — operadores podem fazer backup e inspecionar arquivos sem ginástica de docker. Override do data root com ONGRID_DATA_DIR e o log root com ONGRID_LOG_DIR.
Manager — bounded contexts
O binário do manager é um único processo Go. Internamente é dividido em bounded contexts (cada um detém seu próprio schema de DB, suas próprias rotas HTTP, seus próprios background workers). Aproximadamente:
┌─────────┐ ┌─────────┐ ┌─────────────┐ ┌──────────────┐
│ 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│ │ │ │ │
└─────────┘ └──────────┘ └─────────┘ └──────────┘ └─────────┘Tráfego inter-BC é por chamadas de função Go (camada biz) — não há RPC dentro do binário. O arch lint (make arch-lint) impõe a direção de dependência (cmd → service → biz → data, sem ciclos).
Edge — plugin runtime
ongrid-edge é um binário Go que supervisiona uma pequena frota de subprocessos. Cada subprocesso é um collector off-the-shelf reskinado como um "plugin":
ongrid-edge (PID 1)
├─ geminio runtime ← control plane para frontier
├─ plugin: logs
│ └─ subprocess promtail
│ config: /etc/ongrid-edge/promtail.yaml
│ data plane: https://<manager>/loki/api/v1/push
├─ plugin: traces
│ └─ subprocess otelcol-contrib
│ config: /etc/ongrid-edge/otelcol.yaml
│ data plane: https://<manager>/v1/traces
├─ plugin: hostmetrics
│ └─ subprocess node_exporter
│ /metrics raspado pelo Prometheus dentro do manager
└─ plugin: procmetrics
└─ subprocess process_exporterADR-015 é a justificativa: cada collector é best-of-breed em seu próprio ecossistema; reinventá-los como libs Go é desesperançoso. Então o edge detém o contrato de runtime (entrega de config, healthcheck, captura de log, upgrade) e shell out para o trabalho de dado real.
Upgrades — stage-then-swap
ADR-024 governa upgrades de bundle inteiro. O fluxo:
- Operador joga
edge-bundle-<arch>-<ver>.tar.gz+.sha256em/opt/ongrid/edge/no manager (oinstall.she oupgrade.shdo tarball de release fazem isso). - Operador dispara "upgrade all edges" da UI. O manager envia
MethodFetchPackagepelo tunnel. - Edge baixa o bundle, verifica o sha256, faz stage dos arquivos em
/var/lib/ongrid-edge/.upgrade/incoming/. - Edge escreve um marker, sai limpo. systemd reinicia.
- Em restart,
apply-pending-upgrade.shroda como root (via ExecStartPre com+) — verifica o sha de cada arquivo, faz backup de<dest>em<dest>.previous, fazmvatômico do arquivo novo para o lugar. - Se o agent novo não escreve um
healthy_markerantes do próximo restart,apply-pending-upgrade.shrolla back cada.previousautomaticamente.
É por isso que um upgrade de edge é só "restart a unit" — sem rewire frágil in-process.
Onde as coisas vivem em disco
No manager:
| Path | O que |
|---|---|
/opt/ongrid/ | Compose file, configs, certs, .env, artefatos de edge. |
/opt/ongrid/.env | Secrets + tunables (mode 0600). |
/opt/ongrid/certs/ | tls.crt, tls.key para nginx. Substitua para prod. |
/opt/ongrid/edge/ | Bundles de upgrade de edge + binários soltos por arch. |
/var/lib/ongrid/ | Root de bind-mount para containers com estado. |
/var/log/ongrid/ | Arquivos de log do manager e nginx. |
No edge:
| Path | O que |
|---|---|
/usr/local/bin/ongrid-edge | O binário do agent. |
/usr/local/lib/ongrid-edge/ | Binários de plugin + apply-pending-upgrade.sh. |
/etc/ongrid-edge/ | ongrid-edge.env (access/secret keys), configs de plugin. |
/var/lib/ongrid-edge/.upgrade/ | Incoming de upgrade staged + markers. |
/var/log/ongrid-edge/ | Captura de stdout/stderr de plugin. Journal detém logs do agent. |
/etc/systemd/system/ongrid-edge.service | Unit do Systemd. |
Onde ler mais
- Conceitos — glossário dos substantivos.
- Instalação do servidor — o caminho docker-compose.
- Instalação do edge — curl-pipe + verificação.
- Upgrade —
apply-pending-upgrade.sh, invariantes de bundle, rollback. - Telemetry data plane (Reference) — endpoints exatos, auth, e limites.