フードの下でのKubernetesネットワーキング

前書き

Kubernetesは、サーバーのクラスター全体でコンテナー化されたアプリケーションの展開と操作を管理できる強力なコンテナーオーケストレーションシステムです。 Kubernetesは、コンテナワークロードの調整に加えて、アプリケーションとサービス間の信頼性の高いネットワーク接続を維持するために必要なインフラストラクチャとツールを提供します。

Kubernetes cluster networking documentationは、Kubernetesネットワークの基本的な要件は次のとおりであることを示しています。

  • すべてのコンテナは、NATなしで他のすべてのコンテナと通信できます。

  • すべてのノードは、NATなしですべてのコンテナと通信できます(逆も同様です)。

  • コンテナがそれ自体を見るIPは、他の人がそれを見ると同じIP

この記事では、Kubernetesがクラスター内のこれらのネットワーク要件をどのように満たすかについて説明します。ポッド内、ポッド間、ノード間でのデータの移動方法です。

また、KubernetesServiceがアプリケーションに単一の静的IPアドレスとDNSエントリを提供し、絶えずスケーリングおよびシフトする複数のポッドに分散される可能性のあるサービスとの通信を容易にする方法についても説明します。

Kubernetespodsnodesの用語やその他の基本事項に慣れていない場合は、記事An Introduction to Kubernetesで一般的なアーキテクチャと関連するコンポーネントについて説明します。

まず、1つのポッド内のネットワークの状況を見てみましょう。

ポッドネットワーキング

Kubernetesでは、podが組織の最も基本的な単位です。つまり、すべてが密接に関連し、単一の機能またはサービスを実行する、密結合されたコンテナのグループです。

ネットワークに関しては、Kubernetesはポッドを従来の仮想マシンまたは単一のベアメタルホストと同様に扱います。各ポッドは単一の一意のIPアドレスを受け取り、ポッド内のすべてのコンテナはそのアドレスを共有し、loを介して相互に通信します。 ■localhostホスト名を使用するループバックインターフェイス。 これは、ポッドのすべてのコンテナーを同じネットワークスタックに割り当てることで実現されます。

この状況は、コンテナ化の数日前に単一のホストに複数のサービスを展開した人なら誰でも知っているはずです。 すべてのサービスは、リッスンするために一意のポートを使用する必要がありますが、それ以外の場合、通信は単純でオーバーヘッドが低くなります。

ポッドツーポッドネットワーキング

ほとんどのKubernetesクラスターでは、ノードごとに複数のポッドを展開する必要があります。 ポッドからポッドへの通信は、同じノード上の2つのポッド間、または2つの異なるノード間で発生する場合があります。

1つのノードでのポッド間通信

単一のノードで、互いに直接通信する必要がある複数のポッドを使用できます。 ポッド間のパケットのルートをトレースする前に、ノードのネットワーク設定を調べてみましょう。 次の図は概要を示しており、詳細に説明します。

Networking overview of a single Kubernetes node

各ノードには、Kubernetesクラスターネットワークに接続されたネットワークインターフェイス(この例ではeth0)があります。 このインターフェースは、ノードのrootネットワーク名前空間内にあります。 これは、Linux上のネットワークデバイスのデフォルトのネームスペースです。

プロセス名前空間によってコンテナが実行中のアプリケーションを相互に分離できるように、ネットワーク名前空間はインターフェイスやブリッジなどのネットワークデバイスを分離します。 ノード上の各ポッドには、独自の分離されたネットワーク名前空間が割り当てられます。

ポッド名前空間は、virtual ethernet pairを使用してroot名前空間に接続されます。これは、基本的に、両端にインターフェイスがある2つの名前空間間のパイプです(ここでは、rootveth1を使用しています。 )s名前空間、およびポッド内のeth0)。

最後に、ポッドは相互に接続され、ブリッジbr0を介してノードのeth0インターフェースに接続されます(ノードはcbr0docker0などを使用できます)。 ブリッジは基本的に物理的なイーサネットスイッチのように機能し、ARP(アドレス解決プロトコル)またはIPベースのルーティングを使用して、トラフィックを転送する他のローカルインターフェイスを検索します。

ここで、pod1からpod2までのパケットをトレースしてみましょう。

  • pod1は、宛先としてpod2のIPを使用してパケットを作成します

  • パケットは、仮想イーサネットペアを介してルートネットワーク名前空間に移動します。

  • パケットはブリッジbr0に続きます

  • 宛先ポッドは同じノード上にあるため、ブリッジはパケットをpod2の仮想イーサネットペアに送信します

  • パケットは仮想イーサネットペアを経由して、pod2のネットワーク名前空間とポッドのeth0ネットワークインターフェイスに移動します

ノード内のポッドからポッドへのパケットをトレースしたので、ノード間のポッドトラフィックの流れを見てみましょう。

2つのノード間のポッド間通信

クラスター内の各ポッドには固有のIPがあり、すべてのポッドは他のすべてのポッドと直接通信できるため、2つの異なるノード上のポッド間を移動するパケットは前のシナリオと非常に似ています。

別のノードにあるpod1からpod3までのパケットをトレースしてみましょう。

Networking diagram between two Kubernetes nodes

  • pod1は、宛先としてpod3のIPを使用してパケットを作成します

  • パケットは、仮想イーサネットペアを介してルートネットワーク名前空間に移動します。

  • パケットはブリッジbr0に続きます

  • ブリッジはルーティング先のローカルインターフェイスを検出しないため、パケットはデフォルトルートからeth0に送信されます。

  • Optional:クラスターがパケットをノードに適切にルーティングするためにネットワークオーバーレイを必要とする場合、パケットはネットワークに向かう前にVXLANパケット(または他のネットワーク仮想化技術)にカプセル化される場合があります。 または、ネットワーク自体に適切な静的ルートを設定することもできます。その場合、パケットはeth0に移動し、ネットワークから変更されません。

  • パケットはクラスターネットワークに入り、正しいノードにルーティングされます。

  • パケットはeth0で宛先ノードに入ります

  • Optional:パケットがカプセル化されている場合、この時点でカプセル化が解除されます

  • パケットはブリッジbr0に続きます

  • ブリッジはパケットを宛先ポッドの仮想イーサネットペアにルーティングします

  • パケットは仮想イーサネットペアを通過してポッドのeth0インターフェイスに到達します

パケットがポッドIPアドレスを介してルーティングされる方法について理解したところで、Kubernetesservicesと、このインフラストラクチャ上にパケットがどのように構築されるかを見てみましょう。

サービスネットワーキングへのポッド

Kubernetesクラスターの動的な性質により、ポッドを移動、再起動、アップグレード、またはスケールイン/スケールアウトできるため、ポッドIPのみを使用して特定のアプリケーションにトラフィックを送信することは困難です。 さらに、一部のサービスには多数のレプリカがあるため、それらの間で負荷を分散する方法が必要です。

Kubernetesはこの問題をServicesで解決します。 サービスは、単一の仮想IP(VIP)をポッドIPのセットにマッピングするAPIオブジェクトです。 さらに、Kubernetesは各サービスの名前と仮想IPのDNSエントリを提供するため、サービスは名前で簡単にアドレス指定できます。

クラスター内のポッドIPへの仮想IPのマッピングは、各ノードのkube-proxyプロセスによって調整されます。 このプロセスは、iptablesまたはIPVSのいずれかをセットアップして、パケットをクラスターネットワークに送信する前にVIPをポッドIPに自動的に変換します。 個々の接続が追跡されるため、パケットが戻ったときに適切に変換解除できます。 IPVSとiptablesはどちらも、単一のサービス仮想IPを複数のポッドIPにロードバランシングできますが、IPVSには使用できるロードバランシングアルゴリズムの柔軟性がはるかにあります。

[.note]#Note:この変換および接続追跡プロセスは、完全にLinuxカーネルで行われます。 kube-proxyはKubernetesAPIから読み取り、iptables ip IPVSを更新しますが、個々のパケットのデータパスにはありません。 これは、ユーザーランドプロキシとして機能していた以前のバージョンのkube-proxyよりも効率的で、パフォーマンスが高くなります。

パケットがポッドpod1からサービスservice1までたどるルートをたどってみましょう。

Networking diagram between two Kubernetes nodes

  • pod1は、宛先としてservice1のIPを使用してパケットを作成します

  • パケットは、仮想イーサネットペアを介してルートネットワーク名前空間に移動します。

  • パケットはブリッジbr0に続きます

  • ブリッジはパケットをルーティングするローカルインターフェイスを検出しないため、パケットはデフォルトルートからeth0に送信されます。

  • kube-proxyで設定されたIptablesまたはIPVSは、パケットの宛先IPと一致し、使用可能なまたは指定された負荷分散アルゴリズムを使用して、仮想IPからサービスのポッドIPの1つに変換します。

  • Optional:前のセクションで説明したように、この時点でパケットがカプセル化される可能性があります

  • パケットはクラスターネットワークに入り、正しいノードにルーティングされます。

  • パケットはeth0で宛先ノードに入ります

  • Optional:パケットがカプセル化されている場合、この時点でカプセル化が解除されます

  • パケットはブリッジbr0に続きます

  • パケットはveth1を介して仮想イーサネットペアに送信されます

  • パケットは仮想イーサネットペアを通過し、eth0ネットワークインターフェイスを介してポッドネットワーク名前空間に入ります。

パケットがnode1に戻ると、VIPからポッドへのIP変換が逆になり、パケットはブリッジと仮想インターフェイスを介して正しいポッドに戻ります。

結論

この記事では、Kubernetesクラスターの内部ネットワークインフラストラクチャを確認しました。 ネットワークを構成する構成要素について説明し、さまざまなシナリオでのホップごとのパケットの旅を詳しく説明しました。

Kubernetesの詳細については、our Kubernetes tutorials tagthe official Kubernetes documentationをご覧ください。