コンテンツにスキップ

アーキテクチャ

Yagra は、単一ノード構成では数個のコンテナに同居して動作し、書き直しではなく設定だけで 分散ポーラーや高可用ストアへスケールアウトできるように作られています。各要素は最初から疎結合です。

コンポーネント 役割 動作場所
Core オーケストレーション、スケジューリング、ノースバウンド REST API コア
Poller ICMP / SNMP / API ポーリングとパッシブ受信 — ステートレスで水平スケール可能 ポーラー
WebUI ダッシュボードと可視化(React + TypeScript) ブラウザ
Bus NATS 上でのジョブ配信とポーラーへのファンアウト コア + ポーラー
Transport すべての機器 I/O が通る ICMP / SNMP / HTTP 抽象 ポーラー
Topology 抑制とネットワークマップを支える依存関係グラフ コア
Discovery 機器のディスカバリと分類 コア + ポーラー
Alert ステートマシン、ヒステリシス、依存関係抑制 コア
Ingest syslog と SNMP トラップの解析、フローのデコード、エッジでのレート制限 ポーラー
Forward 受信イベント/フローの外部コレクタへのフィルタ付きティー コア
Secrets 機器の認証情報をエンベロープ暗号で保護 — 鍵を持つのはコアだけ コア
Telemetry 構造化ログ、Prometheus メトリクス、OpenTelemetry トレース コア + ポーラー

デプロイする単位は最初の 3 つだけです。 残りを担うのは 2 つの Rust プロセス — コア (オーケストレーション側)とポーラー(機器側) — に、nginx が配信する静的な WebUI を加えた ものです。表の残りは、そのどちらか(または両方)にコンパイルされて入るライブラリであり、 ingest コンテナも alert サービスも独立した discovery デーモンも存在しません。「動作場所」列は それぞれがどのプロセスの中に収まるかを示しています。

紛らわしい 2 つの名前を区別しておきます。Bus はコアと各ポーラーの両方に組み込まれる クライアントのクレートであり、NATS はその両者が経由するブローカー本体です。後者は コンポーネントではなくバックエンドサービスで、下のストア一覧に含まれます。

コアとポーラーはバス経由でのみ通信し、直接呼び出しは一切行いません。これがポーラーをステート レスかつ水平スケール可能にし、NAT やファイアウォールを越えたリモート拠点への配置を可能にして います。リモートのポーラーは受信接続を待ち受けるのではなく、中央のバスへダイヤルアウトする ため、拠点に必要なのはアウトバウンドルール 1 本だけで、インバウンドの穴は不要です。

ポーラーは永続的な状態を持たず、データベースにも触れません。必要なもの — ジョブ仕様、デバイス 認証情報、作業セットの割当 — はすべてバス経由で届き、生み出すもの — 結果、イベント、フロー バッチ、ハートビート — もすべて同じ経路を通って出ていきます。ジョブメッセージはデバイス認証 情報を運びうるため、バスをリモート拠点へ公開するには同梱の TLS + 認証設定が必要です (セキュリティを参照)。

データの種類ごとに、それ専用に作られたストアへ保存します。バックエンドサービスのうち 3 つは 必須で、残る 3 つは任意 — 設定すると対応する機能が有効になります。 インストールガイドと同じ枠組みです:

バックエンドサービス 保持するもの 必須?
PostgreSQL メタデータ: ノード、設定、しきい値、ユーザー、アラート履歴 必須
NATS コア ⇄ ポーラーのバス: ジョブ、作業セット、結果、イベント 必須
VictoriaMetrics 時系列メトリクス 必須
Redis 一時的なポーラーの死活/割当ミラー — 再構築可能で、失っても安全 任意
VictoriaLogs パッシブイベントのログストア — syslog/トラップの全文検索 任意
ClickHouse トラフィックフローレコード 任意

この表の背後にあるルールはこうです: 高カーディナリティの時系列は決して PostgreSQL に入れず、 永続的な設定は決して Redis に入れません。VictoriaLogs がなければパッシブイベントはすべて PostgreSQL に留まり、ClickHouse がなければフロー監視は無効になります。

ポーラーは生の SNMP カウンタを保存し、レートや利用率はクエリ時に導出します(この方式なら カウンタのラップやリセットも正しく扱えます)。そのためポーラーは前回値の状態を持ちません。

コアはすべてのチェックをスケジュールし — 数千のノードが同じタイミングでプローブしないよう ジッタを加えます — バスへ作業を配信します。割り当てられたポーラーが Transport 抽象(ICMP・ SNMP・HTTP)を通してプローブを実行し、結果を返します。コアは状態としきい値を評価して アラートパイプラインを駆動し、生のメトリクスサンプルを VictoriaMetrics へ書き込みます。収集時にレート関連の計算は一切行いません。レートはクエリ時 および評価時に時系列ストアから得られます。

機器が syslog や SNMP トラップをポーラーの UDP リスナーへ送ります。ポーラーはこれを解析し、送信元 ごとおよび全体のレート制限をエッジで適用したうえで、元のデータグラムのバイト列のコピーとともに イベントをバス経由で転送します。コアは送信元 IP でノードに対応付け、イベントルールと突き合わせ てアラートを発報または解消し、PostgreSQL へ(設定されていれば、全文検索のために VictoriaLogs へも)永続化します。受信 Webhook はポーラーを経由せず、送信元ごとの Bearer トークンを添えてコア の API へ直接届きます。詳細: パッシブイベント

フローエクスポーターが NetFlow・IPFIX・sFlow のデータグラムをポーラーのフローリスナーへ送ります。 ポーラーはこれをデコードしてエッジで集約し — 固定の時間バケット、エクスポーターごとのバイト数 上位フロー — その集約結果をコアへストリーミングします。あわせて、転送機能が機器の送ったもの をそのまま中継できるよう、原本のデータグラムも送ります。コアはフローに AS 番号(オフラインの IP→ASN データセット)を補完し、ClickHouse へ書き込みます。詳細: トラフィックフロー

転送は、受信した syslog・トラップ・フローエクスポートを外部の コレクタへ中継します。そしてその外向き通信は、ポーラーではなくコアから出ていきます。ポーラー は受信した原本のバイト列をバス経由でコアへ運び、アクティブなコアが転送先ごとのフィルタを 適用して、中継も BigQuery へのストリーミングもすべて行います。いくつの拠点が流し込んでいても、 ファイアウォールで面倒を見る出口は 1 か所だけです。

ポーラープール。 すべてのノードは pool 属性を持ち、各プールのノードはコンシステント ハッシュによって稼働中のポーラーへ分散されます — プールにポーラーを足せばコアが再バランスし、 1 台失えばその担当ノードは残りのポーラーへフェイルオーバーします。プールは拠点に自然に対応します: 東京プールのポーラーは東京の機器をローカルで監視します。 分散ポーリングを参照してください。

作業セット。 コアは各ポーラーへ、割り当てたノード集合をバス経由で配布し — スナップショット と増分の差分の組み合わせです — ポーラーは自分のプローブをローカルでスケジュールします。コアが 一つひとつのチェックを細かく管理しなくてもポーリング能力は水平にスケールし、一時的にポーラーが いなくなったプールはジョブ単位の配信へフォールバックするため、監視の止まるノードは出ません。

高可用性。 同じストア群に対して複数のコアを動かし、自動リーダー選出を行えます。実際に 作業をするのはリーダー 1 台で、スタンバイは数秒のうちに引き継ぎ、/readyz がどちらがどちらか をロードバランサに伝えます。高可用性を参照してください。

バージョンアップは、低コストかつ非破壊になるよう設計されています。コアの起動時に自動実行される expand-contract 方式の DB マイグレーション、バージョン耐性のあるバスメッセージ(ローリング アップグレード中、新しいコアは 1 つ前のリリースのポーラーと動作します — したがってコアを先に、 その後ポーラーを任意の順で上げてください)、そしてアップグレード前のバックアップ手順を伴う永続 ストアの保持です。手順はインストールガイド にあります。