Skip to content

Architektur

Ongrid ist ein vierschichtiges System. Die Edge läuft auf jedem überwachten Host; der Manager ist die Cloud. Sie kommunizieren über einen ausgehenden Tunnel (die Steuerungsebene) plus einen separaten auth-gated direkten Upload-Pfad für Telemetrie (die Datenebene).

Das 4-Schichten-Modell

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 — Cluster. Wo die Signale herkommen. Eine ongrid-edge pro Host, plus ihre Subprozess-Plugins (promtail, node_exporter, process_exporter, otelcol-contrib).
  • L2 — Observability-Triade. Prometheus / Loki / Tempo speichern die Signale. Sie werden im docker-compose ausgeliefert; dieselbe UI funktioniert gegen externe Managed-Equivalente (Grafana Cloud, Mimir, VictoriaMetrics), wenn Sie sie aus den Einstellungen austauschen. Ein separater Edge-Direktpfad transportiert push_host_metrics über den Tunnel für Host-Metriken mit niedriger Kardinalität und geschlossener Menge (das ist es, was die eingebauten CPU- / mem- / disk- / load-Alarme schon vor der Konfiguration von Prom antreibt).
  • L3 — Intelligenz. Der Graph-Kernel-ReAct-Agent: der coordinator zerlegt die Frage, dispatcht zu specialist Sub-Agenten, ruft Skills auf, synthetisiert eine Antwort.
  • L4 — Alarme & Benachrichtigungen. Eingebaute Regeln + benutzerdefinierte Arten evaluieren gegen L2- / L1-Streams, feuern in Kanäle (Slack, Telegram, Larksuite, DingTalk, WeCom, Roh-Webhook).

Die strategische Wette ist L1 + L2 Edge-Direktpfad: ein einzelnes Tarball, ein ausgehender Tunnel, Host-Metriken fließen ohne Prom-Roundtrip. Das macht die 10-Minuten-Installation tatsächlich zu 10 Minuten.

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
  • Eine TCP-Verbindung pro Host. ongrid-edge wählt ausgehend frontier:40012. Nichts eingehend. Kein Port-Forwarding, keine Jumpbox, kein Reverse-Tunnel-SaaS.
  • Geminio-Multiplex. Viele logische RPC-Streams fahren über eine TCP-Verbindung. Bidirektional: der Manager kann in die Edge hineinrufen (bash, host_probe_*, query_processes) und die Edge kann in den Manager hineinrufen (push_host_metrics, report_register).
  • Frontier ist der Broker. Upstream singchia/frontier, im Release-Tarball ausgeliefert. ADR-007 liefert die Begründung (wir reimplementieren nicht, was ein externer Broker bereits leistet).
  • Manager ist ein Go-Binary. Etwa zehn Bounded Contexts (edges, alerts, incidents, agent, knowledge, channels, identity, audit…), alle hinter dem Nginx-Frontdoor.

Datenebene vs. Steuerungsebene

Edges haben absichtlich zwei verschiedene Egress-Pfade zur Cloud:

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
 │  └─────────────────────────┘ │
 │                              │
 └──────────────────────────────┘

Warum die Trennung? ADR-014. Logs + Traces sind hochvolumig, in großen Batches und naturgemäß HTTP. Sie auf den Tunnel zu multiplexen, killt den Durchsatz unter Last. Direkter Push über nginx auth_request erhält die Sicherheitsposition (nur registrierte Edges können pushen), während die Datenebene schnell bleibt.

Was fährt noch im Tunnel?

  • Metriken — derzeit noch push_host_metrics-RPC über geminio. Direktes remote_write von der Edge zu Prometheus steht auf der Roadmap, sobald die Clustergrößen es rechtfertigen. Bis dahin ist das Metrik-Volumen tolerierbar.
  • Alle RPCs — query_processes, bash, query_logs_tail, host_probe_*, expand_topology, Dateilesungen, WebShell.

Container-Karte (docker-compose)

Was sudo ./install.sh auf dem Manager-Host startet:

ContainerImageHost-PortsRolle
ongridongrid:<version>9100 (metrics)Der Manager. Go-Binary; HTTP-API auf :8080, durch nginx proxiert.
ongrid-nginxongrid-web:<version>443, 80TLS-Terminator + SPA + Reverse Proxy. Bedient /api/*, /grafana/*, /install.sh, /edge/*.
ongrid-mysqlmysql:8.03306Der gesamte operative Zustand (Edges, Alarme, Benutzer, Audit-Log, Kanal-Konfigurationen).
ongrid-frontiersingchia/frontier:1.2.540012Geminio-Broker. Edges wählen 40012; Manager wählt 40011 über das Compose-Netz.
ongrid-prometheusprom/prometheus:v2.54.0(keiner)TSDB. Empfängt remote_write vom Manager, Abfragen vom query_promql-Skill.
ongrid-lokigrafana/loki:3.4.0(keiner)Logs-Backend. Push unter /loki/api/v1/push via nginx auth-gate.
ongrid-tempografana/tempo:2.5.0(keiner)Traces-Backend. OTLP-Push unter /v1/traces via nginx auth-gate.
ongrid-grafanagrafana/grafana-oss:11.1.43000Dashboards. Als iframes unter /grafana/ in der SPA eingebettet.
ongrid-qdrantqdrant/qdrant(keiner)Vector Store für die Wissensbasis.
ongrid-searxngsearxng/searxng(keiner)Selbstgehostete Meta-Suche für das web_search-Skill.

Alle zustandsbehafteten Dienste binden per Bind-Mount auf Host-Pfade unter /var/lib/ongrid/, nicht auf benannte Docker-Volumes — Operatoren können Dateien sichern und inspizieren, ohne Docker-Gymnastik. Überschreiben Sie das Datenroot mit ONGRID_DATA_DIR und das Log-Root mit ONGRID_LOG_DIR.

Manager — Bounded Contexts

Das Manager-Binary ist ein einzelner Go-Prozess. Intern ist es in Bounded Contexts aufgeteilt (jeder besitzt sein eigenes DB-Schema, seine eigenen HTTP-Routen, seine eigenen Hintergrund-Worker). Grob:

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-Traffic läuft über Go-Funktionsaufrufe (biz-Schicht) — es gibt kein RPC innerhalb des Binarys. Der Arch-Lint (make arch-lint) erzwingt die Abhängigkeitsrichtung (cmd → service → biz → data, keine Zyklen).

Edge — Plugin-Laufzeit

ongrid-edge ist ein Go-Binary, das eine kleine Flotte von Subprozessen überwacht. Jeder Subprozess ist ein Off-the-Shelf-Collector, der als „Plugin" neu eingekleidet ist:

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 liefert die Begründung: jeder Collector ist Best-of-Breed in seinem eigenen Ökosystem; sie als Go-Bibs neu zu erfinden, ist aussichtslos. Die Edge besitzt also den Runtime-Vertrag (Konfigurationszustellung, Healthcheck, Log-Erfassung, Upgrade) und schält für die eigentliche Datenarbeit aus.

Upgrades — Stage-then-Swap

ADR-024 regelt Whole-Bundle-Upgrades. Der Ablauf:

  1. Operator legt edge-bundle-<arch>-<ver>.tar.gz + .sha256 in /opt/ongrid/edge/ auf dem Manager ab (die install.sh und upgrade.sh des Release-Tarballs tun beides).
  2. Operator löst „upgrade all edges" aus der UI aus. Der Manager sendet MethodFetchPackage über den Tunnel.
  3. Die Edge lädt das Bundle herunter, verifiziert das sha256, lagert Dateien nach /var/lib/ongrid-edge/.upgrade/incoming/.
  4. Die Edge schreibt einen Marker und beendet sich sauber. systemd startet sie neu.
  5. Beim Neustart läuft apply-pending-upgrade.sh als root (via ExecStartPre mit +) — verifiziert das sha jeder Datei, sichert <dest> zu <dest>.previous, verschiebt die neue Datei atomar mit mv an ihren Platz.
  6. Wenn der neue Agent vor dem nächsten Neustart keinen healthy_marker schreibt, rollt apply-pending-upgrade.sh jedes .previous automatisch zurück.

Deshalb ist ein Edge-Upgrade nur „die Unit neu starten" — keine fragile In-Process-Verdrahtung.

Wo Dinge auf der Disk liegen

Auf dem Manager:

PfadWas
/opt/ongrid/Compose-Datei, Konfigurationen, Zertifikate, .env, Edge-Artefakte.
/opt/ongrid/.envSecrets + Tunables (Mode 0600).
/opt/ongrid/certs/tls.crt, tls.key für nginx. Für Prod ersetzen.
/opt/ongrid/edge/Edge-Upgrade-Bundles + per-arch lose Binaries.
/var/lib/ongrid/Bind-Mount-Root für zustandsbehaftete Container.
/var/log/ongrid/Manager- und nginx-Log-Dateien.

Auf der Edge:

PfadWas
/usr/local/bin/ongrid-edgeDas Agent-Binary.
/usr/local/lib/ongrid-edge/Plugin-Binaries + apply-pending-upgrade.sh.
/etc/ongrid-edge/ongrid-edge.env (Access/Secret-Keys), Plugin-Konfigurationen.
/var/lib/ongrid-edge/.upgrade/Gelagerter Upgrade-Eingang + Marker.
/var/log/ongrid-edge/Plugin-stdout/stderr-Erfassung. Das Journal besitzt Agent-Logs.
/etc/systemd/system/ongrid-edge.serviceSystemd-Unit.

Wo Sie mehr lesen können

  • Konzepte — Glossar der Substantive.
  • Server-Installation — der docker-compose-Pfad.
  • Edge-Installation — curl-pipe + Verifizierung.
  • Upgradeapply-pending-upgrade.sh, Bundle-Invarianten, Rollback.
  • Telemetrie-Datenebene (Reference) — exakte Endpunkte, Auth und Limits.