メインコンテンツまでスキップ

設計思想

routerd には明確な方針があります。実際のルーターホストで重要だと判明したいくつかの 原則に沿って実装されており、ここを一度読んでおくと日々の設計判断が分かりやすくなります。

1. YAML が真実の元 (source of truth)

ルーターの振る舞いは、レビューでき、差分で見られ、戻せるファイルに置くべきです。 routerd は YAML を真実の元として扱い、ホストの状態をその投影として保ちます。

これは次のような意味です。

  • 運用者は YAML を変えます。生成されたファイルは触りません。 /etc/dnsmasq.d/routerd.conf を手で書き換えても、次の apply で上書きされ、 ホストを作り直すと消えます。
  • 変更履歴は git にあります。routerd apply が「何が変わったか」をログに残さなくて いいのは、git の diff にすでにあるからです。
  • ロールバックは git revertrouterd apply です。

2. OS 標準のデーモンを優先する。ports ツールは標準で足りないときだけ使う

routerd 自身はネットワークスタックではありません。OS が持っているデーモンを設定し 監督します。各プラットフォームで、その仕事に最も標準的なデーモンを使い、 標準で実現できないときに限って ports / 外部ツールを使います。

例:

  • Ubuntu: インターフェースと IPv4/IPv6 DHCP は systemd-networkd、LAN の DNS/DHCP は dnsmasq、フィルタと NAT は nftables。すべて base 標準。
  • FreeBSD: IPv4 DHCP は base の dhclient、IPv6 SLAAC のルーター要請は base の rtsoldただし IPv6 プレフィックス委譲だけは KAME 由来の dhcp6c (ports) を使います。FreeBSD base には PD を扱えるクライアントが無いためです。
  • NixOS: 使うデーモンは Linux と同じですが、Nix のモジュール体系から導入・設定します。

こうすることで、運用者は OS の既存知識でホストを観察できます。各 OS が リース更新・デーモン再起動・クラッシュ復帰をどう扱うかを信頼し、routerd では 再実装しません。

3. kubectl 流の動詞

routerd のリソースは Kubernetes のリソースに似た形をしていて、CLI も同じ動詞を使います。

  • apply: ホストを YAML の形に合わせる
  • validate: YAML をスキーマに照らして確認する
  • render: 今の YAML から書き出されるファイルを見る
  • get / describe / show: リソースと観測状態を 3 段階の粒度で見る (一行要約、構造化要約、完全データ)

見た目を寄せているだけではありません。この動詞集合は実績あるコントロールループに 対応していて、リソース所有モデル も同じ考え方 (管理対象・所有者参照・ファイナライザに相当する設計) で組み立てています。

4. 観測ファースト

routerd は宣言だけでなく、ホストで観測した状態も記録します。DHCPv6 のプレフィックス 委譲、ホストインベントリ (カーネル、仮想化、サービス管理、使えるコマンドの一覧)、 routerd が入れた成果物 (artifacts) などが、YAML とは別にローカルの SQLite に 保存されます。

これで「今このルーターが実際に何をしているか」を、複数のデーモンログを grep して 回らなくても答えられます。将来の routerd は、推測ではなく観測値に基づいて 分岐できるようになります (物理機 vs 仮想機、systemd vs rc.d など)。

5. 小さく、見渡せる。リモートコントロールプレーンを持たない

routerd はプラットフォームではありません。型付きの YAML スキーマと SQLite の状態 ファイルを持つ、小さなコントロールループです。新しいリソース種を増やすのは意図的な 決定で、機能の穴埋めとして増やしません。集中 API サーバも、エージェントの艦隊も、 テナント抽象もありません。

routerctl といくつかの SQL クエリでデーモンの挙動を端から端まで読めます。小規模 ネットワークの運用者は、自分のルーターを動かしているツールを完全に理解できる べきです。

6. 既定で冪等

すでに収束しているホストに同じ YAML を再 apply しても、何も変わらない。これが 基本です。レンダラは決定論的で、リコンサイルループは観測状態と望む状態を diff して、本当に違うときだけ動きます。この性質があるので、routerd を長時間 動くデーモンとして apply ループを回しっぱなしにしても、ホストを揺らすことなく 任せられます。

各原則のつながり

これらは互いに補強し合います。

  • 「YAML が真実の元」 + 「kubectl 流の動詞」 で、運用者が知っている流儀の作業手順になる
  • 「OS 標準のデーモン」 + 「観測ファースト」 で、ホストは普段の道具でデバッグでき、 routerd の状態が「期待値」を説明する
  • 「小さい・見渡せる」 + 「冪等」 で、デーモンを動かしっぱなしで信頼できる

routerd の中で実装の選択肢が複数あるとき、勝つのは「次の運用者が YAML だけ読んで 動いているルーターをより速く理解できる方」です。