開発者ドキュメント

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

序章

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

Kubernetesクラスタネットワークのドキュメントには、Kubernetesネットワークの基本的な要件は次のとおりです。

  • すべてのコンテナは、NATなしで他のすべてのコンテナと通信できます
  • すべてのノードは、NATなしですべてのコンテナと通信できます(その逆も可能です)。
  • コンテナが自分自身を認識しているIPは、他の人が認識しているIPと同じです。

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

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

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

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

ポッドネットワーキング

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

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

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

ポッドからポッドへのネットワーキング

ほとんどのKubernetesクラスタは、ノードごとに複数のポッドをデプロイする必要があります。 ポッド間の通信は、同じノード上の2つのポッド間、または2つの異なるノード間で発生する可能性があります。

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

1つのノードで、相互に直接通信する必要のある複数のポッドを持つことができます。 ポッド間のパケットのルートを追跡する前に、ノードのネットワーク設定を調べてみましょう。 次の図は概要を示しており、詳細を説明します。

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

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

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

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

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

ノード内のポッドからポッドへのパケットをトレースしたので、ポッドトラフィックがノード間をどのように移動するかを見てみましょう。

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

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

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

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

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

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

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

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

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

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

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

結論

この記事では、Kubernetesクラスターの内部ネットワークインフラストラクチャについて説明しました。 ネットワークを構成するビルディングブロックについて説明し、さまざまなシナリオでのパケットのホップバイホップジャーニーについて詳しく説明しました。

Kubernetesの詳細については、KubernetesチュートリアルタグおよびKubernetesの公式ドキュメントをご覧ください。

モバイルバージョンを終了