# SONiCのモジュール責務分離 ## 定義 SONiCのモジュール責務分離とは、サブシステム(コンテナ)内で動作する各プロセス(モジュール)を、扱うデータの向きと役割によって`*orch`・`*syncd`・`*mgrd`という接尾辞付きの命名規約で分類する設計原則である。この分類はswssコンテナのモジュール構成にもっとも明確に現れるが、`*syncd`という命名パターン自体はswssコンテナに閉じず、fpmsyncd(bgpコンテナ)・teamsyncd(teamdコンテナ)・lldp_syncd(lldpコンテナ)のように複数のサブシステムに分散配置される。命名規約は単なる表記上の慣習ではなく、各モジュールが「どちらの方向にデータを流すか」「どのデータベースを主に更新するか」を名前だけで判別できるようにする、SONiCアーキテクチャ全体を貫く責務分離の設計思想である。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] ch.7 §7.5.1, §7.5.3, §7.5.4) ## 命名規約による責務分離 | 接尾辞 | データの向き | 主な役割 | 代表例 | |---|---|---|---| | `*orch` | APPL_DB → ASIC_DB | APPL_DBの更新通知を受け、他モジュール/DBのステートを参照しながらsairedis経由でASIC_DBを更新する。1プロセスだが機能ごとに`*orch.cpp`へソース分割 | orchagent | | `*syncd` | ホスト(Netlink) → APPL_DB/STATE_DB | ホスト(Linux Kernel)からのステート通知をデータベースへ反映する。起動時は設定ファイル/CONFIG_DBをAPPL_DBへ反映し、warm reboot時はホストとDBを同期する | portsyncd, neighsyncd, fdbsyncd, gearsyncd(swss) / fpmsyncd(bgp) / teamsyncd(teamd) / lldp_syncd(lldp) | | `*mgrd` | CLI/CONFIG_DB → ホスト設定 | CLIやCONFIG_DBの変更を検知し、ip・brctl・bridge・conntrack等のコマンドでホストを設定し、APPL_DB/STATE_DBを更新する | coppmgrd, vlanmgrd, intfmgrd, portmgrd, buffermgrd, vrfmgrd, nbrmgrd, vxlanmgrd, tunnelmgrd(swss) / teammgrd(teamd。ただし配置はteamdコンテナ) | 同じ`*syncd`という接尾辞を持ちながら、syncdコンテナ(ASIC_DB⇔Switch ASIC間の連携)とswssコンテナ内の`*syncd`(ホスト⇔APPL_DB/STATE_DB間の連携)は担当するデータベースも通信相手もまったく異なる。名前の類似性が誤解を招きやすい箇所として、本書自身が明示的に注意を促している。(Source: ch.7 §7.5.1) ## 起動制御とプラットフォーム条件分岐 モジュールの起動順序・起動可否はコンテナ内の`supervisord.conf`(`dependent_startup`/`dependent_startup_wait_for`で依存関係を表現)に集約される。プラットフォーム構成(switch_type: fabric/dpu/chassis-packet/voqなど)によって必要なモジュールが変わるコンテナでは、ビルド時にJinjaテンプレート`supervisord.conf.j2`から`{% if is_fabric_asic == 0 %}`のような条件式で不要なモジュールの記述自体を出力しない形で`supervisord.conf`を生成する。これは「責務分離されたモジュール群のうち、どれを起動するか」をコンパイル時ではなくビルド時テンプレート展開で決定する設計であり、モジュール単位の責務分離とプラットフォーム非依存性を両立させる仕組みになっている。(Source: ch.7 §7.3.2) ## ステートがデータベースを介して非同期に伝播する仕組み 命名規約(`*orch`/`*syncd`/`*mgrd`)が示す「データの向き」は、実際には共通の1つのメカニズムの上で実現されている。各モジュールはDBConnector・Table・ProducerStateTableという共通のアクセスクラスでデータベースへ接続し、あるモジュールの書き込みは、対象のテーブル/キーをsubscribeしている別モジュールへのPub/Sub変更通知として伝わる。つまり`*orch`・`*syncd`・`*mgrd`という3分類は「誰が・どちらの方向に・どのデータベースへ書くか」という役割の違いにすぎず、モジュール同士が互いを直接呼び出すことはほぼない。この非同期な疎結合連携の一般的な仕組みは[[データベースを介した疎結合なモジュール連携]]で扱う。(Source: ch.8 §8.2, §8.4) この原則の唯一の例外は、orchagent内部の`xxxOrch`クラス間の直接メソッド呼び出しである(例: SRv6OrchがNeighOrch::getNextHopId()を呼ぶ)。`*orch`は命名規約上「APPL_DB→ASIC_DBの変換を担うモジュール」として一括りにされるが、実際にはorchagent内部で複数の`xxxOrch`クラスが互いを直接参照し合っており、命名規約が示す「1つの役割」の内部に、データベースを介さない密結合な連携が隠れている。(Source: ch.8 §8.4.1) ## orchagent/syncdの責務分離をSAI API視点から見る(第9章) 第7章はorchagent/syncdの責務をデータの向きと更新対象DB(APPL_DB→ASIC_DB / ホストNetlink→APPL_DB)という命名規約の観点から整理する。第9章はこれをSAI API呼び出しの実装という別の角度から補足する。orchagentは「いつどのSAI APIを呼び出すか」というアプリケーション制御を担い、その呼び出しはsonic-sairedis(`sai_redis_<機能名>.cpp`、`REDIS_*`マクロで生成)によってASIC_DBへの読み書きとして実装される——すなわちorchagentが実行する「SAI API呼び出し」は、実際にはASICを一切操作しない。syncdは同じくSAI APIを実装するが、こちらはSAI-v0.9.1仕様書が言う「アダプタホスト」であり、vendor-sai(`libsai.so`)に動的リンクしてASIC_DBの内容を実際のSwitch ASICへ反映する。orchagentとsyncdは同じSAI APIインターフェース形状(`sai_<機能名>_api_t`というメソッドテーブル構造体)を実装しながら、一方はRedisへの書き込み、他方はASICへの実際の設定という異なる実装を提供する。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 9 SAI詳細解説[API・オブジェクト・データプレーンパイプライン]]] ch.9 §9.5.1〜§9.5.2, 参照: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] ch.7 §7.5.1) ## 横断的知見 - **第7章のデータの向きによる命名規約は、第9章が示すSAI API実装の二重性という、より具体的なソフトウェア設計上の裏付けを持つ**: 同じSAI APIインターフェース(`sai_<機能名>_api_t`)を2つのモジュールがそれぞれ異なる実装(Redis書き込み対実ハードウェア制御)で満たしているという事実は、第7章の`*orch`/`*syncd`という命名規約が単なる表記上の分類ではなく、SAI APIという共通インターフェースの二重実装という具体的なソフトウェア設計に対応していることを示す。第7章単独では「orchagentはAPPL_DBの更新をASIC_DBへ変換する」という記述にとどまり、この変換が「orchagent自身もSAI APIを呼んでいるが、そのSAI API実装がASICを操作しない」という形を取ることまでは述べていない。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] ch.7 §7.5.1, [[@2025__Gihyo__実践SONiC入門 - Chapter 9 SAI詳細解説[API・オブジェクト・データプレーンパイプライン]]] ch.9 §9.5.1〜§9.5.2) - 第7章の命名規約(`*orch`/`*syncd`/`*mgrd`)は「モジュールがどちらの方向にデータを流すか」を名前だけで判別可能にする分類だが、第8章が示すアクセスクラス(DBConnector/Table)とPub/Sub通知の仕組みを重ねると、この3分類はいずれも同一の下部メカニズムの表層ラベルにすぎないことがわかる。命名規約そのものは「何が呼ばれるか」を教えるが、「どう呼ばれるか(データベース経由の非同期通知)」は命名規約とは独立した、章をまたいで初めて見える設計原則である。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] ch.7 §7.5.1, [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] ch.8 §8.2, §8.4) - `*orch`という単一の命名規約カテゴリの内部に、データベースを介さない直接呼び出し(`xxxOrch`間通信)が存在するという事実は、命名規約による責務分離が「モジュール間(プロセス間)」の粒度では機能しても、「クラス間(プロセス内)」の粒度では保証されないことを示す。第7章はorchagentを「swssコンテナ上で単一プロセスだが機能ごとの`*orch.cpp`に分割」と静的構造として説明し、第8章はその内部クラス間で密結合な直接呼び出しが起きることを動的な連携として補足する——両者を合わせて初めて、命名規約の適用範囲の限界が見える。(Source: ch.7 §7.5.5, ch.8 §8.4.1) - **第8章が挙げた`xxxOrch`間直接呼び出しの例(SRv6OrchがNeighOrchを呼ぶ)は抽象的な原則説明だったが、第10章はもう1組の具体的な呼び出し関係を示し、この例外パターンが単発ではなく複数箇所で使われる設計であることを裏付ける**: 第10章のH.Encaps.Red設定フロー(図10.18)では、ROUTE_TABLEのSRv6絡みエントリを処理するRouteOrchが、SRv6のTunnel/NH/NHG(ASIC_DBのSAI_OBJECT_TYPE_TUNNEL, SAI_OBJECT_TYPE_NEXT_HOP)の作成をSrv6Orchへ依頼し、そのハンドル(oid)を受け取ってから自身がRoute Entry(SAI_OBJECT_TYPE_ROUTE_ENTRY)を作成する、という2段階の連携を取る。これはRouteOrch→Srv6Orchという、第8章のSrv6Orch→NeighOrchとは別の向きの`xxxOrch`間直接呼び出しであり、`*orch`という命名規約1カテゴリの内部で複数のxxxOrchクラスが機能ごとに役割分担しながら互いを呼び合う構造が、SRv6機能という1つの具体例の中だけでも既に2方向存在することを示す。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] ch.8 §8.4.1, [[@2025__Gihyo__実践SONiC入門 - Chapter 10 高度な設定と利用法]] ch.10 §10.3.4) ## 未解決の問い - syncdコンテナ自体の`*syncd`(ASIC_DB⇔Switch ASIC)とswssコンテナ内の`*syncd`(ホスト⇔APPL_DB/STATE_DB)は名前こそ同じだが、第9章のSAI視点で見るとSAI APIの実装有無という点でも全く異なる——syncdコンテナはvendor SAIにリンクしSAI APIを実装するが、swssコンテナ内の`*syncd`(portsyncd等)はSAI APIを一切呼ばない。この違いは第7章の命名規約の説明だけでは見えず、第9章のSAI API視点があって初めて対比が明確になる。 - `*orch`/`*syncd`/`*mgrd`という3分類は、swssコンテナ以外の全コンテナのモジュール(snmpd, lldpd, teammgrdなど命名規約に従わないもの)にどこまで一般化できるか。本書は明示的な対応関係を与えていない。 - 同名接尾辞`*syncd`が指すデータベース対応(ASIC_DB⇔ASICのsyncdコンテナ vs. ホスト⇔APPL_DB/STATE_DBのswssコンテナ内*syncd)の混同は、実運用のトラブルシューティングでどの程度の誤りを招いているか。 - 責務分離の設計原則(名前で役割を判別できる)は、モジュール数が増加した場合(新機能追加のたびに新しい`*mgrd`/`*syncd`が増える)にスケールし続けるか。命名規約が破綻し始める兆候はあるか。 - switch_typeによるJinjaテンプレートの条件分岐は、DPU対応など新しいターゲット追加のたびに条件式が積み重なる。この条件分岐の複雑化に対するSONiCコミュニティ側の設計上の歯止め(リファクタリング方針など)は本書からは読み取れない。 - `*orch`内部の`xxxOrch`間直接呼び出しは、機能追加のたびにどの程度増えているか。データベース経由の疎結合と内部の密結合の比率はSONiCの成長とともにどう変化しているか。 ## 関連 - ソース: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] / [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] / [[@2025__Gihyo__実践SONiC入門 - Chapter 9 SAI詳細解説[API・オブジェクト・データプレーンパイプライン]]] / [[@2025__Gihyo__実践SONiC入門 - Chapter 10 高度な設定と利用法]] - 実体: [[SONiC]] / [[SAI (Switch Abstraction Interface)]] - 概念: [[コンテナ仮想化]] / [[レイヤリング]] / [[データベースを介した疎結合なモジュール連携]] / [[SRv6]] ## 出典 - 海老澤健太郎, 『実践SONiC入門』, 技術評論社, 2025, 第7章 §7.3.2, §7.5.1, §7.5.3, §7.5.4, 第8章 §8.2, §8.4, §8.4.1, 第9章 §9.5.1〜§9.5.2, 第10章 §10.3.4.