前置き
前回、ポリモーフィズムをした際、各種具体のモジュールは
インフラレベルまで一貫した非機能であるべき
という話を以下の記事でしました。
では今回は、そんなポリモーフィズムで抽象化で来た際に、
各モジュールをどのようにネットワークセグメントに配置したらいいのか?
非機能要件の一貫性のために、どのような仕組みを使ったらいいのか?
といった話に触れていきます。
同じネットワークセグメントにした場合のメリット・デメリット
まず、前提として、今回は、モジュールA・B・Cが、
機能的側面だけでなく、複数の品質特性軸で判断してみた結果でも、
ポリモーフィズムをしてもOKという結論になった という前提条件の下での話です。
では、このように、
商品A注文モジュール・商品B注文モジュール・商品C注文モジュールを抽象化できる場合、
インフラレベルでのネットワークセグメントは、
3つのモジュール共に物理的に同じネットワークセグメントに配置すべきでしょうか?
それとも物理的には分けた方が良いのでしょうか?
この考察をしていきましょう。
必ずしも物理的に同じネットワークセグメントに配置する必要はありません。
「同じセグメントに配置する」場合の論理的根拠とメリット
抽象化するということは、これら3つのモジュールが同じインターフェースを持ち、同じような非機能要件(スケーラビリティ、可用性など)を持つ、いわば「仲間」のような存在だと見なすことです。
この考え方に基づくと、同じセグメントに配置することには以下のメリットがあります。
① セキュリティポリシーの一貫性と簡素化
これらのモジュールは論理的に同等であるため、必要とするファイアウォールルールや外部からのアクセス制御(例: AWSのセキュリティグループ)も同じになる可能性が高いです。
そのため、同じセグメントに配置すれば、セグメント全体に対して単一のセキュリティポリシーを適用でき、管理が非常にシンプルになります。
② 運用管理の容易さ
監視、ロギング、ルーティング設定などを、個別のモジュールごとではなく、セグメント単位で一括して管理できます。
そのためネットワークトラフィックの分析やトラブルシューティングも容易になります。
③. コストとパフォーマンス
モジュール間の通信が同一セグメント内で完結するため、ネットワークレイテンシーが低く、クラウド環境でのデータ転送コストも最小限に抑えられます。
「同じセグメントに配置する」場合のデメリット ⚠️
一方でデメリットも当然あります。
セキュリティリスクの増大(爆発半径の拡大)
これが最大のデメリットです。
もし商品Aのモジュールが侵害された場合、同じセグメント内にいる商品B、Cのモジュールへ攻撃が広がる(水平展開される)リスクが高まります。
脆弱性が一つ見つかると、被害がグループ全体に及ぶ可能性があります。
「うるさい隣人」問題のリスク
もし商品Aのモジュールが突発的な高負荷やネットワーク帯域の専有を起こした場合、同じセグメントを共有する商品B、Cのパフォーマンスに悪影響を与える可能性があります。
「あえて別のセグメントに配置する」場合のメリット・デメリット
一方で、たとえ抽象化できたとしても、以下のような理由から、
各モジュールを独立した存在と捉え、セキュリティと分離を最優先するアプローチとして、
物理的にセグメントを分離する(マイクロセグメンテーション)という高度な設計も考えられます。
ゼロトラストとかは、この設計思想です。
メリット ✅
高度なセキュリティ(ゼロトラストの実現)
もし、3つのモジュールが共有するライブラリに脆弱性が発見され、商品Aのモジュールが侵害されたとします。同じセグメントにいれば、その侵害が商品B、Cのモジュールに広がる(水平展開される)リスクが高まります。
各モジュールを個別のセグメントに配置し、デフォルトで相互の通信をすべて拒否しておけば、仮に商品Aが侵害されても、ファイアウォールによって被害をAのセグメント内に
封じ込める(爆発半径を限定する) ことができます。
これは「何も信頼しない」というゼロトラストの思想に沿った、非常に堅牢な設計です。
障害からの分離
あるモジュールの障害(例: 大量のエラーログによるネットワーク逼迫など)が、他のモジュールに影響を与えることを防ぎます。
これにより、
Aの買い物はできないが、商品BやCの買い物は引き続き行える
といった具合に可用性と信頼性が向上します。
コンプライアンス要件への柔軟な対応
例えば、商品Bだけが個人情報や決済情報(PCI DSS準拠が必要)を扱う場合、
コンプライアンス要件として
「当該データを扱うシステムは、他のシステムから物理的・論理的に分離されたネットワークに配置すること」
が求められる場合があります。
この場合、アプリケーションのロジックは抽象化できても、インフラは分離せざるを得ません。
こういった時に、特定のモジュール(例: 決済データを扱う商品B)だけを、より厳格なセキュリティ要件が求められる専用セグメントに隔離するといった、柔軟な構成が可能です。
デメリット ⚠️
運用管理コストの増大
これが最大のデメリットです。
モジュールが3つあれば、少なくとも3つのセグメントと、それらの間の通信を制御する多数のファイアウォールルールを個別に管理する必要があります。
管理対象が増えるほど、設定ミスや意図しない通信断絶のリスクも高まります。
ネットワーク設定の複雑化
サービス間の通信を許可するためのルーティング設定や、全体を横断した監視・トレーシング環境の構築が、単一セグメントの場合に比べて格段に複雑になります。
結論と推奨
どちらを選択するかは、結局はシステムの要件次第です。
シンプルさを優先する場合
抽象化されたモジュール群を論理的なグループと捉え、
同一のセキュリティポリシーを適用できる単位(例:同じVPC内の専用サブネットや、共通のセキュリティグループ) に配置する
これによって、運用コストを抑えるのが現実的です。
セキュリティ・信頼性を最優先する場合
特定のモジュールにだけゼロトラストの観点やコンプライアンス要件があるなら、「別のセグメント」に分離し、その代わりにかかる運用コストを許容する、という判断になります。
このように、物理的な配置は、最終的に
「運用管理のシンプルさ」と「セキュリティ上の分離レベル」
をどうバランスさせるかによって決まります。
サービスメッシュの必要性
さて、上記で別々のネットワークセグメントに配置する場合のめんどくささについて触れましたね。
この問題を解消してくれるのが、サービスメッシュです。
サービスメッシュは物理的には異なるセグメントに配置するものの、
複数のコンポーネントに対して一貫した非機能要件を満たしたいとき
の支援をしてくれるものです。
なぜ管理コストがかさむのか? (問題)
物理的に異なるセグメントにモジュールを配置し、手動で一貫性を保とうとすると、以下のような管理コストが急増します。
セキュリティポリシーの複雑化
モジュールAからBへの通信、AからCへの通信、BからCへの通信...といった具合に、各セグメント間のファイアウォールルールを個別に、かつ網羅的に設定・管理する必要があり、組み合わせ爆発を起こします。
これ、多数のマイクロサービスとかってなったら、最早絶望です、、、
観測可能性(Observability)の分断
監視、ロギング、トレーシングの設定をセグメントごとに行い、それらの情報を手動で集約して全体像を把握する必要があるため、手間がかかり、一貫した監視が難しくなります。
トラフィック管理の不在
リトライ、タイムアウト、サーキットブレーカーといった、信頼性を高めるための非機能要件を、ネットワークレベルで一貫して適用することができません。
サービスメッシュはどのように支援するのか? (解決策)
サービスメッシュ(IstioやLinkerdなど)は、物理的なネットワークの上に論理的なアプリケーションネットワーク層を構築することで、この問題を解決します。
仕組みは、
各モジュールの隣に「サイドカー」を配置し、それらプロキシ全体を中央の「コントロールプレーン」から集中管理する
というものです。
これにより、物理的なネットワークセグメントがどうであれ、以下のような支援を受けられます。
① 宣言的なセキュリティポリシー
物理的なIPアドレスやポートベースのファイアウォールルールを管理する代わりに、
「サービスAはサービスBとのみ通信を許可する」といったサービス名ベースのポリシーをコントロールプレーンで一度定義するだけで済みます。
あとは各サイドカープロキシがそのポリシーを自動で強制し、通信は自動的に暗号化(mTLS)されます。
よって、物理的な配置場所は関係ありません。
② 統一された観測可能性
全てのサービス間の通信はサイドカープロキシを経由するため、自動的に詳細なメトリクス(成功率、レイテンシー等)、ログ、分散トレーシング情報が収集されます。
これにより、物理的にバラバラに配置されていても、サービスメッシュのダッシュボードを見れば全体の通信状況が一目瞭然になります。
③ 高度なトラフィック管理
「サービスBへのリクエストが失敗したら3回まで自動でリトライする」
「新バージョンのモジュールAにだけ10%のトラフィックを流す(カナリアリリース)」
といったインフラ上のルールを、アプリケーションコードを一切変更することなく、コントロールプレーンで設定できます。
これはインフラとアプリのコードが混ざらない、関心分離としてもうれしいです。
まとめ
サービスメッシュは、
「物理的には分離してセキュリティや可用性を高めつつ(ブラスト半径を限定しつつ)、論理的には一貫した非機能要件(セキュリティ、信頼性、観測可能性)を楽に適用したい」
という、まさにそのニーズを満たすための強力なソリューションです。
手動でのネットワーク管理の複雑さを抽象化し、インフラ担当者ではなく開発者がアプリケーションの挙動として非機能要件をコントロールできるようにしてくれます。

