監視アーキテクチャ設計
データ収集フロー、SSEコマンド配信、ライフサイクル制御
1. 通信方式とデータフロー
エージェントとサーバー(バックエンド)間の通信は、セキュリティとファイアウォール透過性を考慮し、エージェントからのアウトバウンド通信のみで構成されます。サーバーからエージェントへの直接的なポート開放(インバウンド接続)は不要です。
リアルタイムな双方向通信を実現するため、以下の2つの経路を併用します。
- 定期プッシュ (HTTP POST): 10秒に1回(調整可能)、システムメトリクスと Docker 状態をプッシュします。
- リアルタイム配信 (HTTP SSE): エージェントが確立した
Server-Sent Events接続を用いて、サーバー側の操作(Docker コンテナの起動・停止・ログ取得など)を遅延なくエージェントに通知します。
2. シーケンス図 (Telemetries & Commands Flow)
2.1. 接続確立と定期メトリクス送信
エージェントの起動時、SSE 接続をオープンして常時待機状態に入ると同時に、10秒間隔でリソースデータをサーバーに報告します。
sequenceDiagram
autonumber
participant Agent as Node Agent (agent.js)
participant BE as Backend (Express)
participant DB as SQLite DB
Agent->>BE: GET /api/agent/nodes/:id/stream (Authorize Bearer Key)
Note over BE: 接続を検証、SSE 用レスポンスを保持
(X-Accel-Buffering: no) BE-->>Agent: HTTP 200 OK (Keep-Alive Stream Open) loop 10秒周期 (COLLECT_INTERVAL_SEC) Agent->>Agent: systeminformation からメトリクス収集 Agent->>BE: POST /api/agent/nodes/:id/metrics (Metrics + System Info) BE->>DB: node_metrics_history にメトリクスを INSERT BE->>DB: nodes テーブルの status='online', updated_at=datetime('now') 更新 Note over BE: 保留中のコマンド (pending) があるか確認 BE-->>Agent: HTTP 200 OK (ok: true, pendingCommands: []) end
(X-Accel-Buffering: no) BE-->>Agent: HTTP 200 OK (Keep-Alive Stream Open) loop 10秒周期 (COLLECT_INTERVAL_SEC) Agent->>Agent: systeminformation からメトリクス収集 Agent->>BE: POST /api/agent/nodes/:id/metrics (Metrics + System Info) BE->>DB: node_metrics_history にメトリクスを INSERT BE->>DB: nodes テーブルの status='online', updated_at=datetime('now') 更新 Note over BE: 保留中のコマンド (pending) があるか確認 BE-->>Agent: HTTP 200 OK (ok: true, pendingCommands: []) end
2.2. コンソールからの即時 Docker コマンド実行
管理者がコンソール画面で「コンテナ再起動」などのアクションを行った場合、SSE 経由でエージェントへシグナルが送られ、ミリ秒単位で処理が開始されます。
sequenceDiagram
autonumber
actor User as 管理者 (Console UI)
participant FE as Frontend (Vue 3)
participant BE as Backend (Express)
participant DB as SQLite DB
participant Agent as Node Agent (agent.js)
participant Docker as Docker Engine
User->>FE: 「Restart Container」ボタンをクリック
FE->>BE: POST /api/infra/nodes/:id/docker/command (cmd='restart', container='web')
BE->>DB: docker_commands に status='pending' で保存し ID 発行
BE->>BE: SSE コネクションマップから対象ノードのセッションを取得
BE->>Agent: SSE イベント送信 (event: 'command', data: { id, type: 'restart', container: 'web' })
BE->>DB: コマンドの status を 'running' (実行中) に更新
BE-->>FE: HTTP 200 OK (commandId を返却)
FE->>User: 実行中のローディング表示
Note over Agent: SSE からコマンドを受信
Agent->>Docker: Docker API (dockerode) 経由で再起動実行
Docker-->>Agent: 実行完了
Agent->>BE: POST /api/agent/nodes/:id/docker/results (commandId, success: true, output: "...")
BE->>DB: docker_commands の status='completed', result, completed_at を更新
Note over BE: コマンド完了イベントを UI 向け SSE または WS に流す
FE->>FE: 結果を検知して画面を更新
FE->>User: 「再起動に成功しました」と通知
3. 接続切断とハートビート監視
ネットワーク障害やエージェントサーバーのダウンを迅速に検知するため、以下のヘルスチェック機構を実装します。
オンライン判定の定義
- Online 状態: 最終 metrics プッシュ時刻 (
nodes.updated_at) が 30秒以内 であること。 - Stale (警告) 状態: 最終 metrics プッシュが 30秒超過 120秒以内。一時的なネットワーク遅延や負荷高騰を想定。
- Offline (異常) 状態: 最終 metrics プッシュが 120秒超過、または SSE 接続のクローズを検出した時点。
バックエンドでは、2分に1回自動実行される cron タスクが nodes.updated_at を検証し、期日を過ぎたノードを offline に更新し、アラートエンジンへ通知します。
4. エージェントのインストールとライフサイクル
4.1. インストール・セットアップシーケンス
新規ノード追加時、コンソールで「インストールワンライナー」を発行し、エージェントを全自動で配置します。
sequenceDiagram
autonumber
actor Admin as 管理者
participant Target as 対象サーバー
participant BE as Backend API
participant DB as SQLite DB
participant UI as Console UI
Admin->>UI: ノード名「Tokyo-DB」で登録
UI->>BE: POST /api/infra/nodes (ノード登録)
BE->>DB: nodes にレコード挿入 (ID: tokyo-db-01, status: 'offline')
BE->>DB: 一度限りの API キーを作成・保存 (ハッシュ化)
BE-->>UI: ワンライナーコマンド & Raw APIキーを返却
Note over UI: 「疎通待機中...」インジケータ表示
Admin->>Target: ワンライナーを実行
(curl -sS https://.../install/tokyo-db-01 | bash) Note over Target: 1. Node.js/systemd 等の環境要件チェック
2. /opt/meshconsole-agent 作成
3. npm アーカイブダウンロード・展開 Target->>BE: GET /api/infra/nodes/install/tokyo-db-01/config (APIキー暗号化通信) BE-->>Target: 接続先情報 & APIキーを設定ファイルとして応答 Note over Target: 4. .env 自動生成
5. npm install --production 実行
6. systemd サービス登録 Target->>Target: systemctl daemon-reload && systemctl enable --now meshconsole-agent Note over Target: エージェント (agent.js) 起動 Target->>BE: POST /api/agent/nodes/tokyo-db-01/metrics (初期データ送信) BE->>DB: nodes テーブルの status='online' 更新 Note over BE: UI へ SSE または WebSocket で状態変更を通知 BE-->>Target: 疎通成功応答 UI-->>Admin: 「エージェント疎通確認完了。監視を開始しました」を表示
(curl -sS https://.../install/tokyo-db-01 | bash) Note over Target: 1. Node.js/systemd 等の環境要件チェック
2. /opt/meshconsole-agent 作成
3. npm アーカイブダウンロード・展開 Target->>BE: GET /api/infra/nodes/install/tokyo-db-01/config (APIキー暗号化通信) BE-->>Target: 接続先情報 & APIキーを設定ファイルとして応答 Note over Target: 4. .env 自動生成
5. npm install --production 実行
6. systemd サービス登録 Target->>Target: systemctl daemon-reload && systemctl enable --now meshconsole-agent Note over Target: エージェント (agent.js) 起動 Target->>BE: POST /api/agent/nodes/tokyo-db-01/metrics (初期データ送信) BE->>DB: nodes テーブルの status='online' 更新 Note over BE: UI へ SSE または WebSocket で状態変更を通知 BE-->>Target: 疎通成功応答 UI-->>Admin: 「エージェント疎通確認完了。監視を開始しました」を表示
4.3. 自動更新 (Self-Update) フロー
コンソール側でアップデート指示が出された場合、または定期チェックによりバージョン差異が検出された場合、以下の流れで自己更新が走ります。
graph TD
A[Console: アップデート要求] -->|SSE 送信| B[Agent: イベント受信]
B --> C[Agent: selfUpdate.js をバックグラウンドで起動]
C --> D[Agent: 自身 (agent.js) を終了]
D --> E[selfUpdate.js: 最新パッケージを fetch]
E --> F[selfUpdate.js: npm install 実行]
F --> G[selfUpdate.js: systemd サービスを再起動
systemctl restart meshconsole-agent] G --> H[systemd: 新バージョンで agent.js を起動] H --> I[Agent: 起動完了、更新完了を報告] I --> J[selfUpdate.js: 終了]
systemctl restart meshconsole-agent] G --> H[systemd: 新バージョンで agent.js を起動] H --> I[Agent: 起動完了、更新完了を報告] I --> J[selfUpdate.js: 終了]