架构
Ongrid 是一个四层系统。edge 跑在每台被监控主机上;manager 是云端。它们之间通过一条出站隧道(控制面)通信,遥测数据走一条独立鉴权的直推路径(数据面)。
四层模型
┌──────────────────────────────────────────────────────────────────┐
│ 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,加上它的子进程插件(promtail、node_exporter、process_exporter、otelcol-contrib)。 - L2 —— 可观测三件套。 Prometheus / Loki / Tempo 存信号。它们在 docker-compose 里随包发;同一套 UI 对外部托管等价物(Grafana Cloud、Mimir、VictoriaMetrics)也通用,从 Settings 切换即可。一条独立的 edge 直达通道载着
push_host_metrics走隧道,用于低基数、封闭集的主机指标(这就是在 Prom 还没配好时内置 CPU / mem / disk / load 告警就能工作的原因)。 - L3 —— 智能。 Graph-kernel ReAct agent:coordinator 拆解问题,派发给 specialist 子 Agent,调技能,综合答案。
- L4 —— 告警与通知。 内置规则 + 自定义 kind 评估 L2 / L1 流,命中后触发到通道(Slack、Telegram、飞书、钉钉、企业微信、裸 webhook)。
战略下注是 L1 + L2 edge 直达通道:单 tarball、一条出站隧道、主机指标不绕 Prom。这就是 10 分钟安装真的能跑下来的原因。
Edge → frontier → manager
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。不接受任何入站。无端口转发、无跳板机、无反向隧道 SaaS。 - Geminio 多路复用。 多条逻辑 RPC 流跑在一条 TCP 连接上。双向:manager 能调进 edge(
bash、host_probe_*、query_processes),edge 也能调回 manager(push_host_metrics、report_register)。 - Frontier 是 broker。 上游 singchia/frontier,随发布 tarball 出。ADR-007 给了理由(外部 broker 已经做好的事情就不重造)。
- Manager 是一个 Go 二进制。 大约十个 bounded context(edges、alerts、incidents、agent、knowledge、channels、identity、audit……),都挂在 nginx 前门后面。
数据面 vs 控制面
按设计,edge 有两条独立的出向链路:
┌──────── 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。日志 + 链路天生是高吞吐、大批量、HTTP 形态。把它们塞回隧道,吞吐量在压力下会塌。直推走 nginx auth_request 既保住安全姿态(只有已注册 edge 能推),又让数据面跑得快。
还有什么仍走隧道?
- 指标 —— 目前仍是
push_host_metricsRPC 走 geminio。从 edge 直接remote_write到 Prometheus 在 roadmap 上,等集群规模真撑不住再切。在那之前指标量是能接受的。 - 所有 RPC ——
query_processes、bash、query_logs_tail、host_probe_*、expand_topology、文件读、WebShell。
容器分布(docker-compose)
sudo ./install.sh 在 manager 主机上起来的东西:
| 容器 | 镜像 | 主机端口 | 角色 |
|---|---|---|---|
ongrid | ongrid:<version> | 9100(metrics) | Manager。Go 二进制;HTTP API 在 :8080,由 nginx 反代。 |
ongrid-nginx | ongrid-web:<version> | 443、80 | TLS 终结 + SPA + 反向代理。提供 /api/*、/grafana/*、/install.sh、/edge/*。 |
ongrid-mysql | mysql:8.0 | 3306 | 所有运行态(edges、告警、用户、审计日志、通道配置)。 |
ongrid-frontier | singchia/frontier:1.2.5 | 40012 | Geminio broker。Edge 拨 40012;manager 在 compose 网内拨 40011。 |
ongrid-prometheus | prom/prometheus:v2.54.0 | (无) | TSDB。接 manager 的 remote_write,被 query_promql 技能查询。 |
ongrid-loki | grafana/loki:3.4.0 | (无) | 日志后端。在 /loki/api/v1/push 经 nginx 鉴权后写入。 |
ongrid-tempo | grafana/tempo:2.5.0 | (无) | 链路后端。OTLP push 在 /v1/traces 经 nginx 鉴权后写入。 |
ongrid-grafana | grafana/grafana-oss:11.1.4 | 3000 | 仪表盘。在 SPA 内以 iframe 形式嵌在 /grafana/ 下。 |
ongrid-qdrant | qdrant/qdrant | (无) | 知识库向量存储。 |
ongrid-searxng | searxng/searxng | (无) | 自托管元搜索,给 web_search 技能用。 |
所有有状态服务都 bind-mount 到 /var/lib/ongrid/ 下的主机路径——而不是 docker named volume——运维不用绕 docker 就能备份和检查文件。数据根用 ONGRID_DATA_DIR 改,日志根用 ONGRID_LOG_DIR 改。
Manager —— bounded context
Manager 二进制是单个 Go 进程。内部按 bounded context 切分(每个 BC 自有 DB schema、自有 HTTP 路由、自有后台 worker)。大致:
┌─────────┐ ┌─────────┐ ┌─────────────┐ ┌──────────────┐
│ 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│ │ │ │ │
└─────────┘ └──────────┘ └─────────┘ └──────────┘ └─────────┘BC 之间的调用走 Go 函数调用(biz 层)——二进制内部没有 RPC。架构 lint(make arch-lint)强制依赖方向(cmd → service → biz → data,禁环)。
Edge —— 插件运行时
ongrid-edge 是一个 Go 二进制,管理一组子进程。每个子进程是行业现成的采集器,包装成"插件":
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 subprocessADR-015 是理由:每个采集器在自己的生态里都是 best-of-breed;用 Go 库重造没希望。所以 edge 持有 runtime 契约(配置下发、健康检查、日志捕获、升级),数据相关的活儿外包给子进程。
升级 —— stage-then-swap
ADR-024 管整包升级。流程:
- 运维把
edge-bundle-<arch>-<ver>.tar.gz+.sha256放到 manager 的/opt/ongrid/edge/(发布 tarball 的install.sh和upgrade.sh都会做这事)。 - 运维在 UI 点 "upgrade all edges"。Manager 通过隧道发
MethodFetchPackage。 - Edge 下载 bundle,校验 sha256,把文件落到
/var/lib/ongrid-edge/.upgrade/incoming/。 - Edge 写下 marker,干净退出。systemd 重启它。
- 重启时
apply-pending-upgrade.sh以 root 跑(通过 ExecStartPre+前缀)——校验每个文件的 sha,把<dest>备份成<dest>.previous,原子mv新文件到位。 - 如果新 agent 在下次重启前没写
healthy_marker,apply-pending-upgrade.sh自动把每个.previous回滚。
这就是 edge 升级只用"重启 unit"的原因——没有脆弱的进程内热切换。
磁盘上各文件的位置
在 manager 上:
| 路径 | 内容 |
|---|---|
/opt/ongrid/ | Compose 文件、配置、证书、.env、edge 资源。 |
/opt/ongrid/.env | Secrets + 可调参数(mode 0600)。 |
/opt/ongrid/certs/ | nginx 的 tls.crt、tls.key。生产换掉。 |
/opt/ongrid/edge/ | Edge 升级 bundle + 每架构的散二进制。 |
/var/lib/ongrid/ | 有状态容器的 bind-mount 根。 |
/var/log/ongrid/ | Manager 和 nginx 的日志文件。 |
在 edge 上:
| 路径 | 内容 |
|---|---|
/usr/local/bin/ongrid-edge | Agent 二进制。 |
/usr/local/lib/ongrid-edge/ | 插件二进制 + apply-pending-upgrade.sh。 |
/etc/ongrid-edge/ | ongrid-edge.env(access/secret key)、插件配置。 |
/var/lib/ongrid-edge/.upgrade/ | 暂存的升级文件 + marker。 |
/var/log/ongrid-edge/ | 插件 stdout/stderr 捕获。Agent 自己的日志归 journal 管。 |
/etc/systemd/system/ongrid-edge.service | Systemd unit。 |