Skip to content

アーキテクチャ

Ongrid は 4 レイヤー構成のシステムです。edge は監視対象の各ホストで動作し、 manager はクラウド側です。両者は 1 本のアウトバウンドトンネル (コントロールプレーン)に加え、テレメトリ用の認証ゲート付き直送アップロード経路 (データプレーン)で通信します。

4 レイヤーモデル

text
┌──────────────────────────────────────────────────────────────────┐
│ L4  アラート / 通知                                              │
│      組み込みルール + カスタム kind → チャネル(Slack / TG / IM)│
├──────────────────────────────────────────────────────────────────┤
│ L3  インテリジェンス(グラフカーネル ReAct エージェント)         │
│      coordinator → specialist サブエージェント → 約 30 スキル    │
├──────────────────────────────────────────────────────────────────┤
│ L2  可観測性トライアド + edge 直送パス                            │
│      Prometheus · Loki · Tempo  +  push_host_metrics RPC          │
├──────────────────────────────────────────────────────────────────┤
│ L1  クラスター(シグナル収集)                                    │
│      各ホスト上の ongrid-edge + プラグイン                        │
└──────────────────────────────────────────────────────────────────┘
  • L1 —— クラスター。 シグナルの発生源。ホストごとに 1 つの ongrid-edge と、 そのサブプロセスプラグイン(promtailnode_exporterprocess_exporterotelcol-contrib)。
  • L2 —— 可観測性トライアド。 Prometheus / Loki / Tempo がシグナルを格納します。 docker-compose に同梱されており、Settings から差し替えれば外部マネージド相当 (Grafana Cloud、Mimir、VictoriaMetrics)に対しても同じ UI が動きます。 別の edge 直送パス では push_host_metrics がトンネル上を流れ、 カーディナリティの低いクローズドセットのホストメトリクスを運びます (Prom 未設定でも組み込みの CPU / mem / disk / load アラートが動くのはこのおかげです)。
  • L3 —— インテリジェンス。 グラフカーネル ReAct エージェント: coordinator が質問を分解し、specialist サブエージェントへディスパッチし、 スキルを呼び出し、回答を合成します。
  • L4 —— アラート & 通知。 組み込みルール + カスタム kind が L2 / L1 ストリームを 評価し、チャネル(Slack、Telegram、Larksuite、DingTalk、WeCom、生 webhook)へ発火します。

戦略上の賭けは L1 + L2 edge 直送パス です:単一の tarball、1 本のアウトバウンドトンネル、 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
  • ホストごとに 1 本の TCP 接続。 ongrid-edgefrontier:40012 に アウトバウンドでダイヤルします。インバウンドは一切なし。 ポートフォワードもジャンプボックスもリバーストンネル SaaS も不要です。
  • Geminio 多重化。 多数の論理 RPC ストリームが 1 本の TCP 接続を共有します。 双方向:manager は edge を呼び出せ(bashhost_probe_*query_processes)、 edge は manager を呼び出せます(push_host_metricsreport_register)。
  • frontier はブローカー。 アップストリームの singchia/frontier で、リリース tarball に同梱されています。 ADR-007 がその根拠です(外部ブローカーが既に解決している問題を再実装しません)。
  • manager は 1 つの Go バイナリ。 10 程度の bounded context (edges、alerts、incidents、agent、knowledge、channels、identity、audit…)が すべて nginx のフロントドア配下にあります。

データプレーン vs. コントロールプレーン

edge にはクラウドへのエグレス経路が 2 つ、意図的に分離されています:

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 を参照。ログ + トレースは大容量・大バッチで、 本質的に HTTP 向きです。これらをトンネル上に多重化すると高負荷時にスループットが破綻します。 nginx auth_request 経由の直接 push なら、セキュリティ姿勢 (登録済み edge のみ push 可)を保ちつつデータプレーンを高速に保てます。

トンネルに残るものは?

  • メトリクス —— 現状はまだ push_host_metrics RPC が geminio 上を流れています。 edge から Prometheus への直接 remote_write は、クラスター規模が正当化される段階で ロードマップに乗ります。それまでメトリクスの流量は許容範囲です。
  • すべての RPC —— query_processesbashquery_logs_tailhost_probe_*expand_topology、ファイル読み取り、WebShell。

コンテナマップ(docker-compose)

manager ホスト上で sudo ./install.sh が立ち上げるもの:

コンテナイメージホストポート役割
ongridongrid:<version>9100 (metrics)manager。Go バイナリ。HTTP API を :8080 で公開し、nginx で proxy。
ongrid-nginxongrid-web:<version>443, 80TLS ターミネーター + SPA + リバースプロキシ。/api/*/grafana/*/install.sh/edge/* を提供。
ongrid-mysqlmysql:8.03306すべての運用状態(edges、alerts、users、監査ログ、チャネル設定)。
ongrid-frontiersingchia/frontier:1.2.540012Geminio ブローカー。edge は 40012、manager は compose 内ネットワーク経由で 40011 にダイヤル。
ongrid-prometheusprom/prometheus:v2.54.0(なし)TSDB。manager からの remote_write を受け、query_promql スキルがクエリ。
ongrid-lokigrafana/loki:3.4.0(なし)ログバックエンド。nginx 認証ゲート経由で /loki/api/v1/push に push。
ongrid-tempografana/tempo:2.5.0(なし)トレースバックエンド。nginx 認証ゲート経由で /v1/traces に OTLP push。
ongrid-grafanagrafana/grafana-oss:11.1.43000ダッシュボード。SPA 内の /grafana/ 配下に iframe として埋め込み。
ongrid-qdrantqdrant/qdrant(なし)ナレッジベース用のベクトルストア。
ongrid-searxngsearxng/searxng(なし)web_search スキル用のセルフホストメタ検索。

ステートフルなサービスはすべて Docker named volume ではなく /var/lib/ongrid/ 配下のホストパスに bind-mount されています —— オペレーターは docker のテクニックなしにバックアップやファイル検査ができます。 データルートは ONGRID_DATA_DIR、ログルートは ONGRID_LOG_DIR で上書きできます。

Manager —— bounded context

manager バイナリは単一の Go プロセスです。内部的には bounded context に分かれており、 それぞれが自身の DB スキーマ、HTTP ルート、バックグラウンドワーカーを持ちます。およそ:

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

BC 間の通信は Go の関数呼び出し(biz 層)で行われます —— バイナリ内に RPC はありません。 arch lint (make arch-lint) が依存方向(cmd → service → biz → data、循環なし)を強制します。

Edge —— プラグインランタイム

ongrid-edge は小さなサブプロセス群を監督する 1 つの Go バイナリです。 各サブプロセスは既成のコレクターを「プラグイン」として再パッケージしたものです:

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 がその根拠です:各コレクターは自身のエコシステムでベスト・オブ・ブリードであり、 それらを Go ライブラリとして再実装するのは現実的ではありません。 したがって edge は ランタイム契約(設定配布、ヘルスチェック、ログキャプチャ、 アップグレード)を担い、実際のデータ処理はサブプロセスに委譲します。

アップグレード —— stage-then-swap

ADR-024 がバンドル全体のアップグレードを規定します。フロー:

  1. オペレーターが edge-bundle-<arch>-<ver>.tar.gz + .sha256 を manager の /opt/ongrid/edge/ に置きます(リリース tarball の install.shupgrade.sh がどちらもこれを行います)。
  2. オペレーターが UI から「全 edge のアップグレード」をトリガー。 manager は MethodFetchPackage をトンネル経由で送信。
  3. edge がバンドルをダウンロードし、sha256 を検証し、ファイルを /var/lib/ongrid-edge/.upgrade/incoming/ にステージング。
  4. edge がマーカーを書いて正常終了。systemd が再起動。
  5. 再起動時に apply-pending-upgrade.shroot で (ExecStartPre の + 経由で)動き、各ファイルの sha を検証し、 <dest><dest>.previous にバックアップし、新ファイルをアトミックに mv
  6. 新エージェントが次回再起動までに healthy_marker を書かなければ、 apply-pending-upgrade.sh が自動的に各 .previous をロールバック。

これが edge のアップグレードを「ユニットを再起動するだけ」にしている理由です —— 脆弱な in-process 配線変更はありません。

ディスク上の配置

manager 側:

パス内容
/opt/ongrid/compose ファイル、設定、証明書、.env、edge アーティファクト。
/opt/ongrid/.envシークレット + 調整値(mode 0600)。
/opt/ongrid/certs/nginx 用の tls.crttls.key。本番では差し替え。
/opt/ongrid/edge/edge アップグレードバンドル + アーキ別の単独バイナリ。
/var/lib/ongrid/ステートフルコンテナの bind-mount ルート。
/var/log/ongrid/manager と nginx のログファイル。

edge 側:

パス内容
/usr/local/bin/ongrid-edgeエージェントバイナリ。
/usr/local/lib/ongrid-edge/プラグインバイナリ + apply-pending-upgrade.sh
/etc/ongrid-edge/ongrid-edge.env(access/secret key)、プラグイン設定。
/var/lib/ongrid-edge/.upgrade/ステージング中のアップグレードファイル + マーカー。
/var/log/ongrid-edge/プラグインの stdout/stderr キャプチャ。エージェントログは journal が管理。
/etc/systemd/system/ongrid-edge.servicesystemd ユニット。

さらに読むには