分散ポーラー
Yagra は、ステートレスなポーラーのプールでポーリングを水平にスケールし、プローブを測定対象の機器の 近くに保ち、ネットワーク分断をまたいで監視を継続します。本ページでは、その挙動 — 割当、 フェイルオーバー、バスの保護、そして store-and-forward バッファ — を説明します。手順を追った デプロイ手引きはインストールガイドのセクション Dを 参照してください。
これらはどれも独立した「分散モード」ではありません。単一ノードのインストールでも、ここで説明する
仕組みそのままに "default" プールでポーラーが 1 台動いています。分散化とは、アーキテクチャを
変えることではなく、ポーラーとプールを増やすことです。単一ノード構成と分散構成は同じイメージで
動きます。
プールと割当
Section titled “プールと割当”すべてのノードは pool 属性を持ちます(既定は "default")。ポーラーは安定した ID
(YAGRA_POLLER_ID)と担当するプール(YAGRA_POLLER_POOL)で自身を識別し、バス経由で
ハートビートを送ります。コアのコーディネーターはそのハートビートを追跡し、各プールのノードを
稼働中のポーラーへコンシステントハッシュで割り当てます — ポーラーが増えても失われても、プール
全体ではなく最小限の数のノードだけが再配置されます。
各ポーラーは自分の割当を作業セットとしてバス経由で受け取ります。最初にスナップショットが届き、 以後はノードの追加・移動・再割当に応じて差分が届きます。ポーラーはその作業セットからローカルに 自分のプローブをスケジュールし — コアが個々のチェックを逐一指示することはありません — 再起動後に 再接続したポーラーは完全な再同期を受け取るため、再起動をまたいでポーリングが途切れることは ありません。
障害時の扱いも同じ仕組みから導かれます。
- ポーラーが離脱した場合 — ハートビートが止まり、コーディネーターはそのノードを同じプールで 生き残っているポーラーへ自動的にフェイルオーバーします。
- ポーラーが参加した場合 — プールは新しい構成に合わせてリバランスし、このときも動かすのは 最小限の割合だけです。
- プールに稼働ポーラーが 1 台もない場合 — コアは、そのプールのジョブをバス経由で個別に配信する 経路(作業セット以前からある経路)にフォールバックします。これはローリングアップグレードの 安全網です。ポーラーが再起動中のプールや、まだ前のリリースを動かしているプールも、監視が止まる ことなくノードを見続けられます。
死活と割当の状態は(オプションの)Redis ミラーに置かれ、再構築可能です — 失っても永続的なものは
何も損なわれません。プールのスケールは、同じ YAGRA_POLLER_POOL と異なる YAGRA_POLLER_ID を
持つポーラーをさらに動かすだけです。
プールの割り当てと、担当ポーラーの確認
Section titled “プールの割り当てと、担当ポーラーの確認”ノードの実効プールは「ノード自身のプール → プールを設定している最も近い祖先フォルダ →
"default"」の順に解決されます。どちらも WebUI から編集でき、ノード単体・フォルダ単体に加えて、
インベントリツリーで右クリックすると既存のプール一覧+継承+任意名の入力が出ます。重要なのは
フォルダです — ツリーには複数選択が無いため、拠点まるごとのノードを一度に移す手段はフォルダ継承
だけだからです。
各選択肢には、そのプールに稼働中のポーラーがいるかが表示されます。これは見た目以上に重要です。 登録済みポーラーのいないプールにノードを割り当てると、そのジョブは誰も購読していないバスサブジェクトへ 配信され、当該ノードは黙って監視されなくなります。
逆方向の問いにはノード詳細が答えます。プールは実効プールとその由来を示し、ポーリング元は 実際に担当しているポーラーを示します(割当済み / 保留(割当が未配布)/ レガシー fan-out(上記の ポーラー 0 台時のフォールバック)/ Meraki(クラウド収集のためリング割当の対象外)/ 不明の 5 状態)。 この答えはハッシュリングから再計算するのではなく、コアが実際に配布した作業セットから読むため、 スイープが除外したノードに存在しない担当者をでっち上げることがなく、ポーラー側のノード一覧と食い違う こともありません。設定 ▸ ポーラーは逆向きに、各ポーラーの担当ノード一覧をその場で展開します。
アップグレードも同じ性質に支えられています。バスは隣接するリリース間で互換性を保つため、新しい コアは前のリリースのポーラーと問題なく動きます。まずコアを、次にポーラーをアップグレードして ください — リモート拠点も含め、1 台ずつ、順序は問いません。ポーラーはステートレスなので入れ替えの コストはなく、一時的にポーラーが居なくなったプールは、アップグレードされたポーラーが再登録するまで ジョブ単位のフォールバックで凌ぎます。手順の全体は アップグレードとバックアップにあります。
拠点に寄せる(ロケーションアフィニティ)
Section titled “拠点に寄せる(ロケーションアフィニティ)”プールは拠点に自然に対応します。ポーラーはステートレスで、中央のバスへダイヤルアウトするため、 リモート拠点に必要なのはアウトバウンドルール 1 本だけで、インバウンドの穴は不要です — NAT や ファイアウォールの内側にあるポーラーも、手を加えずに動きます。拠点ごとにプールを 1 つ運用し (「tokyo」「osaka」、クラウドリージョンなど)、その拠点のノードを割り当てれば、プローブは拠点内に 留まります。ICMP と SNMP のトラフィックが WAN を越えることはなく、コアへ戻るのは結果・イベント・ ハートビートだけです。
受信のエッジもプールに従います。 拠点のポーラーは、その拠点のパッシブテレメトリを受け止める 場所でもあります。オプションの UDP リスナー — syslog、SNMP トラップ、NetFlow/IPFIX、sFlow — が ローカル機器の出力を受け取り、送信元ごとと全体のレート制限をエッジで適用し、同じ認証済みバスで イベントを持ち帰ります。フローのデータグラムはさらにエッジで集約されてから(固定の時間バケット、 エクスポーターごとのバイト数上位フロー)コアへ送られます。これが、繁忙な拠点のフロー量をアップリンクに 載る範囲に抑えている仕組みです。パッシブイベントはデータグラムの送信元 IP でノードに突き合わせられる ため、リモートポーラーの構成はホストネットワーク上で動きます — ブリッジの NAT はアドレスを書き換えて しまうからです。
拠点のアップリンクは、実際にそこを通るものを見込んで設計してください。ポーラーは解析済みのイベントと 並べて受信した元のバイト列も運ぶため(後から転送が、機器が送った とおりのものを中継できるようにするためです)、フローではおよそ 1,000 flows/s あたり 1 Mbit/s に なります。バーストの上限は設定リファレンスにある送信元ごと・ 全体の受信レート制限で抑えられます。
典型的なマルチ拠点構成は次のようになります。
| 拠点 | プール | ポーラー |
|---|---|---|
| データセンター / 本社 | default |
コアと同居 |
| 東京支社 | tokyo |
支社 LAN 上にリモートで 1〜2 台 |
| 大阪支社 | osaka |
支社 LAN 上にリモートで 1〜2 台 |
各プール内では、冗長性は単なる台数です。拠点のプールでポーラーを 2 台動かせば、片方が落ちても もう片方がそのノードを引き継ぎます。上で説明した稼働ポーラーゼロ時のフォールバックはアップグレード 互換のための経路であって、拠点の冗長化ではありません — 拠点の冗長化は 2 台目のポーラーです。
1 つ特別なのが Cisco Meraki 監視で、これは拠点の機器をプローブするのではなく、組織単位で Meraki の
クラウド API をポーリングします。このクラウド収集ジョブは YAGRA_MERAKI_POOL(既定は
default)で指定したプールへ振り分けられます — インターネットへの外向き通信ができるプールを
指定してください。
ポーラーの登録
Section titled “ポーラーの登録”ポーラーは WebUI の**設定 ▸ ポーラー ▸「ポーラーを登録」**から登録します。このダイアログは、
リモートポーラーが必要とする 3 つの変数 — YAGRA_POLLER_ID(安定かつ一意)、YAGRA_POLLER_POOL、
そして tls:// のバス URL — を埋めた、そのまま使える .env をリモートホスト用に生成します。これは
docker-compose.poller.yml(またはネイティブバイナリの環境)にそのまま置けます。イメージも
YAGRA_IMAGE_TAG でそこに固定してください。ポーラーは起動から数秒でこのページに現れ、コアは
そのプールのノードを割り当て始めます。
設定 ▸ ポーラーページは、ポーリング層全体を見渡すビューでもあります。ポーラーごとに次を 表示します。
- 死活 — 現在のステータスと、最後に受信したハートビート。
- 割当 — 担当するプールと現在の作業セットのサイズ。プールのノードがどう分散しているかが 分かります。
- バージョン — そのポーラーが動かしているバージョン。ロールアウトの途中で役立ちます。
- 監視ギャップ — コアがポーラーとの連絡を失っていた直近の期間(どのポーラーか、どのプールか、 いつ、どれだけの長さか)。監視が見えていなかった時間帯が一目で分かり、メトリクスが後から 補完されたことも確認できます。
ノードはあるのに稼働ポーラーが居ないプールがあれば、警告も表示します。デプロイ手順の全体 — compose ファイル、ホストネットワーキング、受信リスナーの特権ポートに関する注意 — は インストールガイドのセクション Dにあります。
ジョブメッセージは平文のデバイス認証情報を運びます。ポーラーがプローブするのにそれを必要とするから
です。単一ホストならこれで問題ありません — バスは内部の Docker ネットワークから出ないからです。
バスが信頼境界を越えてリモート拠点へ届く瞬間から、必ず先に TLS 暗号化と認証を施さなければ
なりません。NATS の :4222 を平文で公開しないでください。5 つのステップからなるセットアップ —
サーバー証明書、バスのパスワード、NATS の認証/TLS 設定、同居クライアントの tls:// への切り替え、
そして各拠点への公開証明書の配布 — は
インストールのセクション D、ステップ 1に
あります。各ポーラーは YAGRA_BUS_CA_FILE でサーバー証明書をピン留めするため、リモート拠点は
システムの CA ストアではなく、ちょうど 1 つのバスエンドポイントだけを信頼します。
同梱の NATS 設定は、core ユーザーにフルアクセスを、poller ユーザーに最小権限を与えます。結果・
イベント・ハートビートの publish はでき、subscribe できるのはジョブと作業セットの割当だけです。
ただし、その限界も知っておいてください — poller アカウントは 1 つで、すべてのポーラーが共有
します。認証済みのポーラーはどのプールの割当も読めるため、この共有アカウントはポーラー群を認証しは
しますが、拠点間のテナント境界ではありません。それが問題になる構成では、次に説明するポーラー
単位の認証情報スコープを使ってください。
ポーラー単位の認証情報スコープ
Section titled “ポーラー単位の認証情報スコープ”オプションで、コアをバスの認証サービス(NATS Auth Callout)として動かし、各ポーラーに自分の
プールのサブジェクトだけにスコープされた、接続ごとの認証情報を発行できます。接続時、コアは共有の
ブートストラップシークレット(YAGRA_NATS_POLLER_PASSWORD)で接続してきたポーラーを検証し、その
ポーラー自身の ID とプールに対応するサブジェクト — 自分のジョブストリームと自分の割当サブジェクト —
だけを許可する認証情報を発行します。それ以外は何も許可しません。
その効果はこうです。侵害されたリモート拠点が見られるのは、全体に手の届く共有アカウントではなく、 自分のプールのジョブとデバイス認証情報だけになります。各ポーラーが何を読めるかは、拠点ごとに NATS サーバーの設定を編集するのではなく、接続時にコアが中央で決めます。
有効化はオプトインで、バスの TLS + 認証のセットアップと合わせて行います。
- NATS のアカウント nkey シードをファイルとしてコアにマウントし、
YAGRA_NATS_CALLOUT_SEED_FILEでそこを指してください — シークレットはマウントしたファイルで あって、環境変数の値ではありません。 - callout アカウントが既定(
$G)でない場合はYAGRA_NATS_CALLOUT_ACCOUNTを設定します。これは NATS サーバーの callout 設定で指定したアカウントと一致していなければならず、サーバー側には そのアカウントの公開鍵をYAGRA_NATS_CALLOUT_ISSUERとして与える必要があります。Compose ファイルには双方のコメントアウト済みブロックが入っています。
シードファイルを設定しなければ callout レスポンダは起動せず、NATS は上記の静的アカウントに フォールバックします — 既定は無効で、有効にするまで何も変わりません。詳細は セキュリティを参照してください。
store-and-forward
Section titled “store-and-forward”コアから切り離されたリモートポーラー — WAN 障害やファイアウォールの一時的な不調 — も監視を続けます。 ローカルで機器のポーリングを継続し、結果を捨てずに 2 段構えでバッファします。
- メモリ上のリングバッファ(既定で 20,000 件)。バッファリングがポーリングループを止めることは ありません。
- リングが埋まったときのディスクへのスピル — セグメントは
/var/lib/yagra/buffer(Compose ではpollerbufボリューム)配下に書かれるため、障害の途中でポーラーが再起動してもバッファは残ります。
バッファはあらゆる軸で上限が決まっており、溢れたときの方針はどこでも古いものから破棄なので、 ポーラーのディスクを埋め尽くすことは決してありません。
| 上限 | 既定 | 変数 |
|---|---|---|
| マスタースイッチ | 有効 | YAGRA_STORE_FORWARD(off で無効化) |
| メモリ上のリング | 20,000 件 | YAGRA_STORE_FORWARD_MEM_MAX |
| ディスクスピルの合計 | 512 MB — 超えた分は最も古いセグメントから破棄 | YAGRA_STORE_FORWARD_DISK_MAX_MB |
| 最大保持期間 | 24 時間 — これより古い結果は再送時に破棄 | YAGRA_STORE_FORWARD_MAX_AGE_SECS |
| 空き容量の下限 | 1 GB — 空きがこれを下回るとスピルを停止 | YAGRA_STORE_FORWARD_DISK_FREE_FLOOR_MB |
| スピルのセグメントサイズ | 16 MiB — ディスク上限の粒度 | YAGRA_STORE_FORWARD_SEGMENT_MB |
| スピル先ディレクトリ | /var/lib/yagra/buffer |
YAGRA_STORE_FORWARD_DIR |
バッファは失敗するのではなく、安全に劣化します。スピル先ディレクトリを作成も読み取りもできない 場合、ポーラーは警告をログに出し、メモリのみのバッファリングで続行します — ストレージの問題が ポーリングを落とすことはありません。
再接続すると、ポーラーは専用のバックフィルチャネル(保護されたバスでも poller アカウントに許可されて
います)でバッファをまとめて再送し、コアはメトリクスを元のタイムスタンプのまま取り込みます —
グラフと履歴は、偽のスパイクを作らずに障害期間を埋めます。再送が運ぶのは測定レコードそのもの、
すなわちメトリクスのサンプルとインターフェースのメタデータだけで、それ以外はありません。ディスク上で
待っているスピルにシークレットは含まれません。
アラートは決してバックフィルされません。 アラート評価は、再接続後の「今」から再開します。これは 意図的です。ドウェル時間のヒステリシスはサンプル数ベースのため、溜まった古いサンプルを再生すると 状態遷移をでっち上げ、すでに解消済みの古いアラートで埋め尽くしてしまうからです。したがって回線が 復旧しても、インシデントを再発報させることなく履歴だけが復元されます — そして回復した障害期間は それぞれ監視ギャップとして設定 ▸ ポーラーに記録されるので、誰も呼び出さなかったとしても、 見えていなかった期間は可視のまま残ります。
store-and-forward は既定で有効です。YAGRA_STORE_FORWARD=off を設定すると、素の即時送信の挙動
(バスに到達できなければ結果は破棄)に戻ります。上限値はすべて
設定リファレンスにあります。
ポーラーの監視
Section titled “ポーラーの監視”ポーリング層は 3 つの角度から観測できます。
- 設定 ▸ ポーラー — ポーラーごとの健全性。ステータス、プール、バージョン、作業セットのサイズ、 最後のハートビート、プールの警告、そして上で説明した直近の監視ギャップ一覧。
- ダッシュボード — 作業セットの分布ウィジェットが、各プールのノードがポーラー間にどう散らばって いるかを示すため、偏ったプールや劣化したプールが一目で分かります。
- Prometheus — 各ポーラーは
:9100で自身の/metricsを提供し、コアは API ポートで自身の メトリクスを提供するため、既存の監視系で監視する側を監視できます。 可観測性を参照してください。
監視ギャップの一覧と合わせると、これで運用上の問いに順番に答えられます。すべてのプールが担当されて いるか → どのノードを誰が持っているか → いつ見えていなかったのか、そしてそれは補完されたのか?