# ネットワーク依存性発見(Network Service Dependency Discovery)
分散アプリケーションを構成するネットワークサービス間の依存関係を**自動的に**発見する取り組み。「どのサービスが誰に依存しているか」を実行時の実際の通信から抽出し、[[サービストポロジ]](依存グラフ)を構築することを目的とする。変更の影響範囲(ブラスト半径)把握・[[Fault Localization]]・[[リアルタイム依存性マップ]]構築の基盤技術。
## 依存性の定義
Zand et al. の定義が広く採用される: **サービス $S_2$ は $S_1$ の遅延/劣化/障害が $S_2$ の遅延/劣化/障害を直接または間接的に引き起こすとき $S_1$ に依存する**([[@2022__IPSJ JIP__Low Overhead TCP-UDP Socket-based Tracing for Discovering Network Services Dependencies]])。TCP/UDP の範囲では listening 側 $S_1$ がサーバ、接続側 $S_2$ がクライアント。
## 手法の分類
### 1. パケットベース手法
ネットワークデバイスまたは OS カーネルからパケットを収集し、送受信元情報で依存を推定。コード改変不要で計装コストが低いが、通信量が大きいとパケット収集の CPU コストが問題になる。
代表例:
- **Sherlock** (Bahl+, SIGCOMM 2007): パッシブ観測 + Inference Graph(3 状態モデル)で 90.66% の障害箇所特定精度 [[@2007__SIGCOMM__Towards Highly Reliable Enterprise Network Services via Inference of Multi-level Dependencies]]
- **Orion** (Chen+, OSDI 2008): 遅延スパイクベース分析で偽陽性を大幅削減 [[@2008__OSDI__Automating Network Application Dependency Discovery - Experiences, Limitations, and New Solutions]]
- **NSDMiner** (Peddycord+, LISA 2012): 対数ベースランキングで候補 25-50% 削減 [[@2012__LISA__On the Accurate Identification of Network Service Dependencies in Distributed Systems]]
### 2. ソケットベース手法(カーネル TCP/UDP 観測)
Linux カーネルの TCP/UDP ソケットからフローをトレース。アプリ改変不要で、Kprobes/eBPF によりカーネルレベルで計装。
**サブ分類**:
| サブ手法 | 原理 | CPU 特性 | 欠点 |
|---|---|---|---|
| **スナップショットポーリング** | procfs から定期スナップショット | < 1%(低) | 短命 TCP を見逃す、UDP 非対応 |
| **ストリーミング** | kprobe でフローを即時ユーザ空間へ | RTT/s に線形増加 | 高負荷で不適 |
| **カーネル内フロー集約** | eBPF で同一フローをカーネル内集約 | コネクション数に比例 | 短命接続多いと増加 |
| **カーネル内フローバンドリング** | 同一宛先サービスのフローを 1 フローに束ねる | **サービス数に抑制(2.2% 以下)** | 1k+ サービスで利点縮小 |
**カーネル内フローバンドリング** は [[@2022__IPSJ JIP__Low Overhead TCP-UDP Socket-based Tracing for Discovering Network Services Dependencies]] (Tsubouchi+, JIP 2022)の主要貢献。エフェメラルポートをハッシュテーブルキーから除外することで、短命接続が増えても転送フロー数をサービス数に抑える。実装: [[go-conntracer-bpf]](eBPF + Kprobes、Linux 5.6+)。
Neves+2020 [[@2020__SAC__Black-box inter-application traffic monitoring for adaptive container placement]] はカーネル内フロー集約の先行実装(9% 未満のオーバーヘッド)で、[[コンテナ配置最適化]]に応用した。
### 3. トランザクションベース手法
HTTP リクエスト/DB クエリ等のアプリ層プロトコルをトレース。リクエスト単位の詳細が得られるがアプリ改変が必要。[[分散トレーシング]](Dapper・OpenTelemetry 等)に対応する系統。
## 横断的知見
- **観測レイヤーとカバレッジのトレードオフが一貫したパターンを示す**: パケット → ソケット → トランザクションの順に、必要な計装コストが増えるがアプリ層の詳細は豊かになる。Sherlock/Orion はパケット観測で依存を「推定」するのに対し、ソケット手法は「直接観測」する。いずれも相補的であり [[Netflix]] の 3 層設計([[@2026__Netflix TechBlog__From Silos to Service Topology - Why Netflix Built a Real-Time Service Map]])が 3 つを統合した設計として合流点を体現する。
- **「フローをどこで集約するか」が CPU オーバーヘッドの支配変数**: ストリーミング手法はユーザ空間で集約するためカーネル/ユーザ空間の文脈切り替えが RTT/s に比例してコストになる。カーネル内集約・バンドリングはその転送量を削減することでオーバーヘッドを抑制する。この「最上流(カーネル)で削減する」設計指針は [[eBPF]] の横断的知見とも一致し、[[テレメトリ]] 博士論文(Tsubouchi 2025)の「計装層でデータを削減する」テーゼの具体例でもある。
- **依存性グラフはサービス依存性のパッシブ観測と能動的推論の 2 系統が並走する**: Sherlock は統計的推論(サービス間の遅延相関・障害伝搬)でグラフのエッジの重みを付ける。ソケット手法は実際の通信を直接観測してエッジを確定する。能動探索(ping/traceroute 系)は依存のある/なしを探索的に確認する第三の手法。3 系統は相補的。
- **NAT/パケット転送リレーがソケットベース手法の共通の死角**: TCP/UDP セッション終端型リレー(ロードバランサ)は対応できるが、NAT によるパケット転送は対応できない。この限界は Orion も NSDMiner も Tsubouchi+ も共通に認識しており、ネットワーク経路情報との組み合わせが解決策として指摘される。
## 未解決の問い
- eBPF によるカーネル内フローバンドリングはコンテナ化・Kubernetes 環境での適用で追加の課題(network namespace・CNI の多様性)がある。go-conntracer-bpf のコンテナ対応状況は?
- 1k を超えるサービス数でバンドリング率が低下する問題の解決策として、階層的バンドリング(サービス群単位での集約)は有効か?
- Netflix の 3 層設計([[サービストポロジ]])はソケットベース(eBPF)・IPC メトリクス・分散トレースを統合した。三者の統合実装で相補性が定量的に示された事例が他にあるか?
- ネットワーク依存性発見の精度評価において「正解の依存グラフ」を何を根拠に作るか(Orion も NSDMiner も悩んだ問題)。LLM を使って設計書・IaC・コードから依存性グラフを事前構築し ground truth とする可能性は?
## 実装
- [[go-conntracer-bpf]]: Tsubouchi+ JIP 2022 の実装。カーネル内フローバンドリング(Linux 5.6+、eBPF + Kprobes)
- Neves+2020 の手法: カーネル内フロー集約(9% 未満オーバーヘッド、Kafka + Neo4j でコンテナ配置最適化に接続)
## 関連概念
- [[サービストポロジ]] — 本手法の出力である依存グラフの活用形態
- [[リアルタイム依存性マップ]] — 本手法で継続更新されるグラフ
- [[eBPF]] — ソケットベース手法の実装基盤
- [[分散トレーシング]] — トランザクションベース手法との接点
- [[コンテナ配置最適化]] — 依存グラフのコンテナスケジューリング応用
- [[Fault Localization]] — 依存グラフを障害箇所特定に使うユースケース