KubernetesのPodのネットワークについてメモ

Kubernetes

はじめに

今回はKubernetesのPodのネットワークについてのメモです。いつも業務ではあまり深入りせずに使っていたので基本を学んでメモしようという趣旨となります。

  • なぜ VM と違うネットワークモデルになるのか
  • Pod が外部(インターネットなど)と通信する仕組み
  • Pod 間通信がどのように実現されているのか

といったポイントを中心に見ていき、CNI プラグインは Calico を使用していきます。

Calicoについては以下も参考になると思います

CalicoによるKubernetesピュアL3ネットワーキング
本エントリーでは、先日の「OpenStackとKubernetesを利用したマルチプラットフォームへのCI環境」 エントリーから続くヤフーのOpenStackデプロイ環境におけるKubernetes利用連載の第2弾として、 我々のKubernetesネットワーク環境について基盤となるProject Calicoの紹介と...

VM と k8s のネットワークモデルの違い

まずVMとk8sのネットワークの違いから見ていきます。

VM の場合

VM では、通常ホストの NIC(物理ネットワークインターフェース)から仮想 NIC へブリッジしたり、仮想スイッチを用意したりして、VM ごとに IP アドレスが割り当てられます。VM は独立した OS を持ち、ネットワーク的にもほぼ「1 台の物理マシン」と同じ感覚で扱われます。

k8s(コンテナ) の場合

一方、k8s が管理するコンテナは「Pod」という単位で動作します。k8s では(通常)各 Pod に固有の IP アドレスが割り当てられるという点が特徴的です。これにより、以下のようなメリットがあります。

  • ネットワーク上でコンテナ(Pod)を VM と同様に扱える
  • Pod は自分の IP を直接使用できるため、複雑なポートマッピングが不要

ただし、この「各 Pod に IP を与える」というのはどのように実現しているのでしょうか。そこには CNI(Container Network Interface)プラグイン などの仕組みが関わってきます。

Pod がどのようにして外部につながるか

Pod への IP 割り当て(Calico の例)

k8s クラスタでは、Pod 生成時に CNI プラグインを通じて Pod ネットワークが構成されます。CNI プラグインは、Pod に割り当てる IP アドレスの管理や、ノード間をまたぐパケットのルーティングを担います。
Calico はその代表的なプラグインの一つで、以下のような特徴があります。

  • BGP を使用したルーティング: Calico はデフォルトで BGP(Border Gateway Protocol)を用いて各ノード間をルーティングすることができます。
  • Overlay / 非 Overlay を選択可能: 環境によっては IP in IP や VXLAN を使用し、Overlay ネットワークを作ることも可能です。
  • 強力な NetworkPolicy 機能: k8s の NetworkPolicy に加え、Calico 独自の拡張機能も利用可能です。

Calico を利用する場合の大まかな流れは以下のとおりです。

  1. Cluster CIDR: k8s の各ノード(ワーカーノード)に「Pod 用 CIDR ブロック」が割り当てられる(例: 10.244.0.0/16 全体をクラスタ用に確保し、ノードごとに /24 などを分割)。
  2. Pod 起動と IP 割り当て: Pod が起動すると、Calico がノードの CIDR の中から空き IP を割り当てる。
  3. ノード間のルーティング: BGP または IP in IP、VXLAN などを用いて、他ノードの Pod CIDR へのルートを構築し、Pod 間の通信を実現する。

外部と通信する場合

  • NAT によるインターネットへのアクセス: k8s ではデフォルトで、Pod から外部に向けた通信(アウトバウンド)は k8s ノードの IP で NAT (IP Masquerade) されます。
    • 例: Pod が www.example.com を引くと、最終的には k8s ノードの IP としてインターネットへ出ていく。
  • 外部から Pod へアクセスする仕組み: 外部から直接 Pod の IP にアクセスできるわけではなく、k8s の Service オブジェクトがよく使われます。たとえば:
    • NodePort: 各ノードに固定ポートを開けて、そこから Pod に転送する仕組み
    • LoadBalancer: クラウドのロードバランサ(AWS ELBなど)を使い、外部 IP + ポート を用意して Pod へルーティングする仕組み
    • Ingress: HTTP/HTTPS など Layer7 負荷分散を行い、ホスト名やパスによって転送ルールを振り分ける仕組み

このように、Pod が持つ「プライベートな IP」そのものを外部にさらすのではなく、Service や Ingress などの仕組みを使って間接的にアクセスするのが k8s の一般的な運用パターンです。

Pod 間通信の仕組み

Pod間を通信するには単一のノードであればイメージしやすいですが、複数のノードだとどうしてもノード経由での通信をしなければならないので、どのように通信しているのでしょうか。

“全ての Pod はフラットなネットワーク空間を共有” の概念

k8s の基本的なネットワーク要件として、「任意の Pod が、(NAT なしで) 他の Pod の IP に直接通信できる」という前提があります。これは VM の場合のようにブリッジを意識したり、ポートフォワーディングの設定を個別にしなくても、Pod が互いの IP で直接やり取りできるという仕組みを理想としています。

ただし実際には、それを実現するために Calico のような CNI プラグインが裏側で BGP や VXLAN を利用したりと、複数の技術を組み合わせて「フラットなネットワーク」を仮想的に作り上げています。ユーザとしては「Pod の IP で直接通信ができる」という点を把握しておけば十分です。

以下参考リンク

異なるホスト上でのPod間通信|Kubernetesネットワーク 徹底解説

Service を通した Pod 間通信

Pod はスケールアウトやローリングアップデートによって IP が頻繁に変わるため、「Service」による安定した名前解決とロードバランシングも重要です。Service は ClusterIP という仮想 IP を持ち、その IP 経由で裏にある複数の Pod へ負荷分散する仕組みです。

  • ClusterIP: Kubernetes 内の仮想的な IP で、同じクラスタ内の Pod からのみアクセスできる
  • DNS との連携: k8s では my-service.my-namespace.svc.cluster.local のような独自の DNS 名が割り当てられ、Service 名でアクセスできるようになっている
  • Endpoints: Service から実際の Pod を参照するためのリソース。Pod の IP とポートのペアが登録されている

ネットワークポリシー(NetworkPolicy)

k8s のネットワークは「デフォルトでフラット」であるため、Pod 間の通信を制限したいときは「NetworkPolicy」を使ってルールを設定する必要があります。
Calico を使うと、標準の NetworkPolicy に加えて、Calico 独自のポリシー(GlobalNetworkPolicy など)も利用でき、より細かい制御が可能になります

具体的なイメージ例(Calico 編)

結構難しいので具体的なイメージをしてみましょう。

Scenario: Web アプリケーションのクラスタ

  1. 3 台のノード(Node1, Node2, Node3)からなる k8s クラスタを用意。
  2. Web アプリ用の Pod (replica=3) をデプロイする。
    • Node1, Node2, Node3 のそれぞれに 1 個ずつ Pod がスケジュールされるケースを想定
    • 各 Pod は Calico が割り当てた IP (例: 10.244.1.10, 10.244.2.12, 10.244.3.15 など) を持つ
  3. Service (type=ClusterIP) を作成し、名前を web-service とする。
    • ClusterIP 例: 10.96.0.15
    • web-service という名前で DNS エントリ (web-service.default.svc.cluster.local) も自動作成
  4. 外部公開:
    • NodePort や LoadBalancer を設定し、外部から web-service にアクセスできるようにする。
    • これによりクラスタ外部ユーザは LoadBalancer または各ノードの NodePort を通じてサービスへアクセスし、内部では 10.244.x.x の Pod へトラフィックがルーティングされる。

ここで重要なのは、Calico がノード間のルーティングを適切に設定してくれている点です。BGP や VXLAN、IP in IP などの方式を選ぶことで、Pod がユニークな IP を持ちつつ、ノードを超えてシームレスに通信ができるようになっています。

まとめ

  • VM と k8s Pod の大きな違い:
    • VM は OS レベルで独立し、ほぼ物理マシンに近いネットワークモデル
    • Pod は軽量コンテナであり、k8s のネットワーク設計により各 Pod に IP が割り当てられ、フラットに通信できる
  • Pod から外部への通信: k8s ノードを経由した NAT や Service/Ingress を用いて実現
  • Pod 間通信: CNI プラグイン(例:Calico)が裏側で BGP や VXLAN などを用いてネットワークを構成し、Pod の IP 同士で直接やり取りできる
  • セキュリティ/フィルタリング: NetworkPolicy(+ Calico 独自ポリシー)を利用してきめ細かく制御可能

また、今度AWS EKSを用いてネットワークについて調べてみて記事などを書いてみたいと思います。

タイトルとURLをコピーしました