サービス間通信の制御をどこで担保するか — ネットワークポリシー適用層の選定

サービス間通信の制御をどの層で担保するかは、設計フェーズで確定させなければ後の変更コストが著しく膨らむ判断のひとつです。ホスト側のiptables・KubernetesのNetworkPolicyリソース・クラウドSDNという3層はそれぞれ適用範囲と限界が異なり、後から担保層を変更すると既存ポリシーの整合性を全面的に見直す必要が生じます。どこで制御するかを初期に明確に決定することで、障害診断の経路を絞り込み、監査設計を一本化できます。

ホスト側・コンテナ側・クラウドSDNのどこで制御するかの選定

制御層の選定を左右する3つの判断軸

制御層を選ぶ際に整理すべき判断軸として、(1)ワークロードの移動性、(2)ポリシー管理インターフェースの運用性、(3)可視性と監査要件の3点が挙げられます。コンテナが複数ノードをまたいで動作するKubernetes環境では、ホスト側のiptablesだけに依存するとノード間でのルール同期の問題が起きやすくなります。一方でクラウドSDNに全権を委ねると、オンプレと並走するハイブリッド構成では制御の管理が分断されます。この3軸を先に整理しておくことで後続の技術選定に迷いが生じにくくなります。

ハイブリッド構成における責任境界の引き方

クラウドとオンプレが混在するハイブリッド構成では、3層がすべて稼働しているケースが現実には多くあります。20ノード規模のKubernetesクラスタを運用するある現場では、クラウドSDNのセキュリティグループとNetworkPolicyが重複して設定され、一方を変更しても他方が通信を遮断し続けるという状況が発生しました。「クラウドSDNは外部から境界内への粗粒度制御」「NetworkPolicyはPod間の細粒度制御」と責任範囲を明示的に分けることで、この種の重複による診断コストを大幅に削減できます。

選定フローと確認ポイント

選定は「ワークロードがKubernetesで管理されているか」→「CNIプラグインがNetworkPolicy APIを実装しているか」→「クラウドSDNが適用範囲内にあるか」という順に確認すると整理しやすくなります。CNIがNetworkPolicyに非対応であればホスト側制御が主体となり、クラウドSDNがあれば境界制御を委ねて内部を宣言的ポリシーで管理する役割分担が成立します。このフローを設計初期に踏んでおくことが、実装後の設計変更リスクを低下させる具体的な手段となります。

iptablesとネットワークポリシーリソースの責任範囲比較

iptablesが担うべき範囲とその限界

iptablesはノード単位の通信制御に適しており、Kubernetesを介さないホストプロセスやデーモン通信のカバーには依然として有効な手段です。ただし手続き的な記述が前提のため、数百のルールが積み重なると意図した動作を人間が追跡しにくくなります。特にKubernetesが自動生成するルールと手動設定のルールが混在すると追跡コストが数倍に跳ね上がります。手動管理するルール数の上限をあらかじめ取り決めておくことが、長期運用では有効に機能します。

Kubernetesネットワークポリシーの前提条件

KubernetesのNetworkPolicyはPodセレクターとnamespaceセレクターを組み合わせることで、宣言的かつGit管理しやすい形式で通信ルールを記述できます。ただしNetworkPolicy自体はAPIの仕様であり、実際に機能するかはCNIプラグインの実装に依存します。FlannelはデフォルトでNetworkPolicyをサポートせず、Calico・CiliumなどのCNIへの変更が前提となります。CNI選定がNetworkPolicyの実現可能性を左右するため、インフラ選定の段階で対応状況を確認しておくことが重要な設計判断となります。

制御手段 管理単位 宣言的管理 主な適用対象 変更コスト
iptables(手動) ノード単位 低い 非コンテナプロセス・ホストデーモン 高(ルール追跡困難)
Kubernetesネットワークポリシー Pod・namespace単位 高い Pod間通信・namespace間通信 中(CNI対応前提)
クラウドSDN(セキュリティグループ等) VPC・サブネット単位 中程度 外部〜境界の粗粒度制御 低〜中(API操作)
サービスメッシュ(Istio・Linkerd等) サービス単位(L7) 高い L7通信制御・mTLS 中〜高(サイドカー運用)

Deny-AllとAllow-Specificのどちらから始めるかの判断

デフォルト拒否の設計がもたらす初期コスト

Deny-Allを起点とする設計はセキュリティ強度として望ましい状態ですが、全サービスの通信要件を事前に洗い出す工数が初期に集中します。50サービス規模の本番環境にDeny-Allを一括適用した事例では、通信要件の洗い出し作業だけで2週間以上を要した現場があります。この初期コストを許容できる組織体制が整っているかどうかが、Deny-All採用の現実的な前提条件となります。体制が整っていない状態で適用すると、想定外の遮断が頻発して運用が追いつかなくなるリスクが高くなります。

段階的なAllow-Specificアプローチの選択基準

本番環境への段階的な適用を優先する場合、まず監視モードで通信フローを観測して実績ある通信パターンを確認してからポリシーを定義する順序が現場でよく採用されています。CiliumのHubbleのような観測ツールを活用すると、ポリシーを適用する前に通信の実態を記録できます。この方法では観測期間中は制御が効いていないため、本番移行前に観測フェーズを設ける計画が必要となります。手を動かして設定を進める段階は、実際の構築作業の中で確認するのが確実です。

本番移行時に見落とされやすい通信要件

どちらのアプローチを選んでも、本番移行時に特に確認すべきなのは「依存サービスの通信先がすべてポリシーに記載されているか」と「モニタリングやログ転送エージェントの通信が遮断されないか」という2点です。インフラ的な通信要件はアプリケーション開発者が意識しないことが多く、ネットワークポリシー適用後にログが届かなくなるという事態が各所で報告されています。これらをポリシー定義前に明文化しておくことが、移行を安定させる鍵となります。

マイクロセグメンテーションの粒度をどこまで細かくするか

粒度の設計指針とラベル設計の連動

マイクロセグメンテーションの粒度はラベル設計と不可分であり、Podに付与するラベルの体系が粒度の上限を規定します。app・tier・envという3軸のラベル体系で管理する環境では、namespace単位より細かいPod単位のポリシーを書けますが、ラベルの一貫性が崩れるとセレクターが意図しないPodにマッチする危険が生じます。ラベル命名規則をAdmission Webhookで強制する構成が、細粒度を保ちながら一貫性を担保する手段として有効とされています。

過剰な細分化が引き起こす問題とnamespace粒度の使い分け

粒度を細かくしすぎると、ポリシーの件数が急増してレビューコストと変更コストが比例して増大します。Podの種類が100を超える環境で全Pod間通信のポリシーを書き下ろした現場では、ファイル行数が数千行を超えて変更の影響範囲を人間が追跡できなくなったという話をよく聞きます。セグメンテーションの粒度は「侵害時の横展開を最小化できる範囲」と「変更コストが許容できる粒度」の交点で決めるという指針が実践的です。namespace単位でポリシーを管理すると、Pod数の増減に対してポリシーを書き直す必要がなくなる利点があり、「namespaceで分離できるものを先に分離してからPod粒度への降格を検討する」という設計順序がポリシー総数を抑えながら必要な細粒度を確保する現実的なアプローチとして知られています。

実装の変更コストと運用負荷のトレードオフ評価

初期実装コストより変更コストが重くなる理由

ネットワークポリシーは初期実装よりも変更コストの方が長期的に重くのしかかります。サービスの追加・削除・リネームのたびにポリシーを更新する必要があり、更新漏れは即座に障害につながります。GitOpsで管理する環境ではマニフェスト変更と同じパイプラインでポリシーを更新できるため変更漏れが起きにくくなりますが、GitOps基盤がない環境では手動更新が必要となり、インフラ変更とアプリケーション変更のタイミングを合わせる調整コストが別途発生します。

変更頻度と体制規模から見た選定の判断軸

ポリシーの変更頻度が高い環境(週1回以上のサービス変更が発生する開発寄りの構成)では、複数ファイルを書き換えるiptablesベースの管理よりも、HelmチャートやOPAなど抽象化された管理ツールの方が運用コストを下げやすくなります。変更頻度が低い安定した本番環境では、複雑なツール導入よりも手動管理のシンプルさを優先するという判断も合理的です。変更頻度と担当チームの体制規模を組み合わせて選定することが、導入後に設計を後悔しない判断材料となります。

監査のために何を記録に残すかの設計

記録すべき情報の優先順位と種別

通信制御の監査で最低限記録すべき情報は「誰がどのポリシーをいつ変更したか」という変更履歴と「どの通信が許可・拒否されたか」というフロー記録の2種類です。変更履歴はGitのコミット履歴とCI/CDのデプロイ記録で代替できることが多くあります。フロー記録はCNIが出力するログとiptablesのLOGターゲットを組み合わせることで取得できます。「何のために記録するか」という目的を先に明示しておかないと、ログが膨大になる割に監査時に使えない状態になりやすくなります。

フロー記録のコスト設計とポリシー変更履歴の管理

全通信フローを記録しようとするとストレージとCPUのコストが急増します。100ノード規模の環境でフルキャプチャを試みた際にログストレージが1日で数十GBに達したという報告があります。現実的な設計は「拒否された通信のみ記録する」か「サンプリングレートを設定して記録する」かであり、コンプライアンス要件と照らし合わせて判断します。緊急対応で行った一時的なポリシー変更が恒久的に残るリスクも高く、変更理由と有効期限を必ず記録する運用ルールを設けることがポリシー肥大化の抑制にもつながります。

落とし穴 — ポリシーの肥大化で壊した事例と収束条件

ポリシー肥大化の典型的な発生パターン

肥大化は「緊急対応のために一時的に追加したルールが削除されずに積み上がる」パターンで発生することが多くなります。障害対応のために特定Podへの全ポート開放を一時的に追加したところ、その設定が半年以上残り続けて監査で指摘されたという話は現場で珍しくありません。廃止されたサービスに対応するポリシーだけが残るケースも同様で、参照先のないセレクターを含む「ゾンビポリシー」は実害がなさそうに見えて変更時の影響範囲計算を複雑にします。

肥大化が引き起こす構成フリーズの実態

ポリシー数が増えるとAPI Serverの処理負荷も上がりますが、より現実的な問題は「変更時にどのポリシーが効いているか人間が判断できなくなる」点にあります。500を超えるNetworkPolicyが存在する環境では、新しいポリシーを追加する前に既存ポリシーとの競合確認だけで数時間を要するという状況が報告されています。そうなると誰もポリシーに触れなくなり、構成がフリーズするという問題に発展しやすくなります。

収束条件の設計とリファクタリングのタイミング

肥大化を防ぐには「ポリシーの総数の上限」と「定期レビューの周期」を設計段階で取り決めておくことが有効です。以下のチェックリストを収束管理の基準として活用できます。

  • 新しいNetworkPolicyを追加する際は、削除できる既存ポリシーがないか先に確認する
  • 四半期ごとに全ポリシーをレビューし、参照先のないセレクターを含むポリシーを特定する
  • サービス廃止時のチェックリストにネットワークポリシーの削除を明示的に含める
  • 緊急対応で追加したポリシーには有効期限コメントを付け、次のスプリントで削除判断を行う
  • namespace当たりのポリシー件数が一定の閾値(例:30件)を超えたらリファクタリングを検討する
  • サービス構成の変更タイミングに合わせてnamespaceへの集約やラベル設計の見直しを実施する

ポリシーのリファクタリングは一括で行おうとすると影響範囲が大きくなりすぎるため、サービスの追加・廃止・変更という通常の作業サイクルに組み込んで少量ずつ実施する方が安全です。収束条件をあらかじめ設計に含めておくことで、「気づいたときには手をつけられない状態」になることを防ぐ具体的な判断基準となります。

▶ 手を動かして本番まで到達する

その設計判断を、RHEL10の本番環境で手を動かして固めませんか

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。

ネットワーク制御設計を実装で確かめる上級Linuxハンズオンへ →

Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン