routerctl doctor — ランタイム健全性診断

routerctl doctor は読み取り専用のチェックを一通り実行し、いまこの routerd が
家庭ゲートウェイとして機能しているかを報告します。ホスト状態は変更しません。
運用者・CI・監視エージェント・下流ツール(Prometheus exporter、Web Console、
LLM 補助診断など)から使われることを想定しています。
使い方
# 全エリア実行(既定)
routerctl doctor
# 単一エリア
routerctl doctor dns
# ホストコマンドを使わない(リソース status のみ)
routerctl doctor --no-host
# 機械可読出力
routerctl doctor -o json
routerctl doctor -o yaml
オプションは diagnose と共通: --config, --state-file,
--no-host / --host, -o / --output, --timeout。
エリア
| エリア | チェック内容 |
|---|---|
wan | EgressRoutePolicy と HealthCheck のリソース status、IPv4 / IPv6 のデフォルト経路(ip -4/-6 route show default)。 |
dns | DNSResolver のリソース status、dig @127.0.0.1 での A レコード応答プローブ。 |
dslite | DSLiteTunnel のリソース status、AFTR FQDN の AAAA プローブ、tunnel device の存在(ip link show)。 |
dhcpv6-pd | DHCPv6PrefixDelegation の status(Bound、委任 prefix)。PD 未取得時は設計上 WARN(壊れている IPv6 を LAN に出さない)。 |
nat | NAT44Rule のリソース status、nft list table ip routerd_nat の存在。 |
firewall | FirewallZone / FirewallPolicy の status、nft list table inet routerd_filter の存在と input チェインの policy drop(無いと permissive)、current config から render される ruleset に含まれない routerd-prefixed nft table が Linux host 上に残っていないか。 |
rollback | 1 つ以上の世代が保存されていて routerctl rollback --to が使えること。 |
disk | /var/lib/routerd と /run/routerd の容量。90% 以上 or 256 MiB 未満で WARN、98% 以上 or 64 MiB 未満で FAIL。Linux では一時ディレクトリの不変条件も確認します。/tmp と /var/tmp は root:root の sticky 1777 directory である必要があります。 |
mgmt | 管理用 interface の存在(ManagementAccess または FirewallZone role=mgmt から推定)。WebConsole の bind 先(0.0.0.0 / :: は WARN/FAIL)。 |
reconcile | 読み取り専用ステータスソケットから、コントローラーごとの reconcile 失敗履歴を確認します。--since <duration> で対象期間を区切ります。期間内に 1 件以上で WARN、10 件以上で FAIL。detail に最大 5 件のサンプルを表示します。 |
runtime | 読み取り専用ステータスソケットから、routerd 自身の heap / goroutine / fd を確認します: heapAlloc、heapObjects、numGoroutine、numGC、openFds/maxFds。numGoroutine が 10000 超、または open fd が RLIMIT_NOFILE の 80% 以上で WARN。観測用で FAIL にはなりません。 |
dynamic | DynamicConfigPart の鮮度、mask、override policy を確認し、effective config が意図した生成状態からズレる原因になる stale part や mask を検出します。 |
routes | Installed な IPv4Route status と Linux host FIB(ip -4 route show <destination>)を比較します。destination、type、gateway、device、必要な場合の preferred source、metric を確認します。drift の証跡用であり、dataplane probe の代替ではありません。 |
plugin | trusted local plugin executable の存在、権限、status から見える直近実行の鮮度を確認します。 |
hybrid | HybridRoute / OverlayPeer の参照、Selective Address Mobility の設定参照、デフォルト経路を触らない安全性、MTU 推定、任意の HealthCheck status、読み取り専用の経路表確認(ip -4 route show <prefix>)。Linux SAM では /32 delivery route、provider local-address absence、proxy neighbor capture、proxy_arp、ip_forward、route lookup、warning-only の rp_filter、default-drop FORWARD policy heuristic も確認します。 |
sam | CloudEdge SAM の ownership/capture 診断です。provider ownership の鮮度、OS capture state、delivery route lookup、forwarding prerequisites、blocking reasons、owner-table/FIB drift を確認します。host check が有効な場合、doctor sam は ownershipResolverOwnerTable の endpoint owner としてローカル所有する行を Linux main FIB と比較します。これらの /32 行は SAM overlay route ではなく local/cloud route に解決される必要があります。一方で、BGP remote owner 向けの provider-secondary capture ホルダー行は、この local-route 要件の対象外です。no-local のまま、delivery/forwarding check と dataplane probe で overlay path を確認します。MobilityPool prefix 内に owner-table へ載っていない予期しない /32 route residue が残っていれば報告します。ただし provider DHCP/link state と観測済み BGP return route は除外します。これは診断ビューであり、CloudEdge acceptance は実 dataplane check で判断します。 |
各チェックは pass / warn / fail / skip(該当リソース/シグナルが無い)のいずれかを返します。
JSON 出力契約
routerctl doctor -o json は安定した機械可読インターフェースです。形:
{
"summary": {
"overall": "pass", // "pass" | "warn" | "fail" | "skip"
"pass": 7,
"warn": 1,
"fail": 0,
"skip": 2
},
"checks": [
{
"area": "dns", // 上記エリア表のいずれか
"name": "DNSResolver/lan-resolver", // 人間可読の対象名
"status": "warn", // "pass" | "warn" | "fail" | "skip"
"detail": "phase=Degraded,waiting=...", // 任意
"remedy": "wait for or repair dependency wan-pd" // 任意
}
// ...
]
}
保証内容:
summary.overallはchecks[].statusの最悪値(fail>warn>unknown/skip>pass)。summary.pass/warn/fail/skipは整数件数で、合計はlen(checks)。checks[].statusはpass,warn,fail,skipのいずれか(他の値は出ない)。checks[].areaはエリア表の識別子のいずれか。集合は安定。checks[].nameは人間可読。厳密な形にパターンマッチしないこと。detail/remedyは任意のフリーフォーム文字列で、運用者向け。
例えば routerctl doctor runtime -o json は、読み取り専用ステータス
ソケットから routerd 自身のプロセス footprint を表示します:
{
"summary": { "overall": "pass", "pass": 1, "warn": 0, "fail": 0, "skip": 0 },
"checks": [
{
"area": "runtime",
"name": "process",
"status": "pass",
"detail": "heapAlloc=11.0MiB heapObjects=84213 numGoroutine=187 numGC=14 openFds=23/1024"
}
]
}
終了コード
0—failが 1 件も無い(pass/warn/skipは失敗扱いではない)。- 非0 —
failが 1 件以上。routerctl doctor || alertのように使えます。
warn は exit code を非0 にしません(例: 起動直後で DHCPv6-PD がまだ Bound でない、など情報的なもの)。
厳しめのゲートが欲しい場合はエリアを絞ってください(routerctl doctor wan は wan の fail でだけ非0)。
安定性
JSON の形、エリア識別子、status の enum は v1alpha1 の運用者向け契約です。今後のバージョンで エリアやオプショナルフィールドが追加されることはありますが、既存エリア名や status 値は v1alpha1 の minor 間で改名・再用途化しません。