|
Kubernetes (k8s) を初めて使う人の多くは、ネットワークの概念にすっかり混乱してしまいます。ノードIPやクラスターIPなど、様々なIPが混乱を招きます。ノードIPとは一体何でしょうか?インターネットはどのようにKubernetesにアクセスするのでしょうか?Kubernetes内の様々なポッドはどのように相互通信するのでしょうか?この記事では、これらの疑問にお答えします。 Kubernetes のコアネットワーク概念の紹介ノードIPノードの IP アドレスは、その物理ネットワーク インターフェイス カード (NIC) の IP アドレスです。 NodePort は物理マシンの IP アドレス(または仮想マシンの IP アドレス)です。各 Service は Node ノード上でポートを開き、Service 内の Pod への外部アクセスは NodeIP:NodePort を介して行われます。これは、サーバー上にデプロイされたプロジェクトに IP:port/プロジェクト名 を使用してアクセスするのと同じです。 クラスターIPサービスのIPアドレスは仮想IPアドレスです。外部ネットワークからpingすることはできず、Kubernetesクラスター内の内部アクセスにのみ使用されます。クラスターIPは仮想IPですが、以下の理由から、偽造IPネットワークに近いと言えます。 1. クラスター IP は k8s サービス オブジェクトにのみ適用され、k8s によって管理および割り当てられます。 2. クラスター IP に ping できません。応答する「物理ネットワーク オブジェクト」がありません。 3. クラスターIPはサービスポートと組み合わせてのみ、特定の通信ポートを形成できます。スタンドアロンのクラスターIPには通信基盤がなく、Kubernetesクラスターの閉じた空間に属します。 4. 異なるサービスに属するポッド ノードは、クラスター IP を介してクラスター全体で相互にアクセスできます。 ポッドIPPod IPは各PodのIPアドレスで、DockerブリッジのIPアドレス範囲に基づいてDocker Engineによって割り当てられます。通常は仮想レイヤー2ネットワークです。
つまり、外部からアクセスする場合、リクエストは最初にノード ネットワークに送信され、次にサービス ネットワークに送信され、最後にポッド ネットワークにプロキシされます。 Kubernetes はネットワーク通信をどのように実装しますか?3つの基本原則
コンテナ間ネットワーク通信ポッド内の各Dockerコンテナは、ポッド自体とネットワーク名前空間を共有します。そのため、IPアドレスやポートなどのネットワーク設定は、ポッドと同一になります。これは主に、「コンテナ」と呼ばれるDockerネットワークモードによって実現されます。新規に作成されたDockerコンテナは、独自のネットワークインターフェースを作成したり、独自のIPアドレスを設定したりするのではなく、指定されたコンテナとIPアドレスとポート範囲を共有します。 ポッド間のネットワーク通信Pod の観点から見ると、Pod は自身のネットワーク名前空間内の同じノード上の別のネットワーク名前空間のプロセスと通信します。Linux では、異なるネットワーク名前空間は、仮想イーサネット デバイス (新しいウィンドウが開きます) または veth ペア (複数の名前空間にまたがる 2 つの仮想ネットワーク インターフェイス カード) を使用して通信できます。Pod のネットワーク名前空間に接続するには、veth ペアの一方の端をルート ネットワーク名前空間に割り当て、もう一方の端を Pod のネットワーク名前空間に割り当てます。各 veth ペアはネットワーク ケーブルに似ており、2 つの端を接続してトラフィックを通過させます。veth ペアの数は、ノード上の Pod の数と等しくなります。次の図は、Pod をルート名前空間に接続する veth ペアを示しています。 ポッドがルートネットワーク名前空間を介して相互に通信できるようにするには、ネットワークブリッジを使用します。Linux Ethernet ブリッジは、2つ以上のネットワークセグメントを接続するために使用できる仮想レイヤー2ネットワークデバイスです。ブリッジは、送信元と宛先間の転送テーブルを維持することで機能します。ブリッジを通過するパケットの宛先アドレスとこの転送テーブルをチェックすることで、ブリッジに接続された別のネットワークセグメントにパケットを転送するかどうかを決定します。ブリッジコードは、ネットワークインターフェースカード (NIC) の固有の MAC アドレスを使用して、データをブリッジするかドロップするかを決定します。ブリッジは ARP プロトコルを実装し、リンク層で IP アドレスにバインドされた MAC アドレスを検出します。ブリッジはデータフレームを受信すると、接続されているすべてのデバイス (送信元を除く) にフレームをブロードキャストし、対応するデバイスをルックアップテーブルに記録します。その後、ブリッジは同じ IP アドレス宛てのトラフィックを受信すると、ルックアップテーブルを使用して対応する MAC アドレスを見つけ、パケットを転送します。下の図では、cbr0 がブリッジです。 異なるノード間の通信原理通常、クラスタ内の各ノードにはCIDRネットワークセグメント(簡単に言うと、CIDRは複数の標準ネットワークを1つの大きなネットワークに統合します)が割り当てられ、そのノード上のPodが利用できるIPアドレスの範囲が指定されます。そのCIDRネットワークセグメント宛てのトラフィックがノードに到達すると、そのノードは対応するPodにトラフィックを転送する役割を担います。次の図は、2つのノード間のデータパケット転送プロセスを示しています。 ポッドとサービス間のネットワーク通信Pod の IP アドレスは静的ではありません。Pod の再スケジュール (例: 水平スケーリング、アプリケーションのクラッシュ、ノードの再起動) により、Pod の IP アドレスは現れたり消えたりします。この間、Pod のクライアントはどの IP アドレスにアクセスすればよいかわかりません。Kubernetes では、この問題を解決するために Service の概念が使用されます。Service は複数の Pod を管理し、各 Service は仮想 IP アドレスを持ちます。Service によって管理される Pod 上のサービスにアクセスするには、この仮想 IP アドレスにアクセスするだけで済みます。この仮想 IP アドレスは固定です。Service 下の Pod のサイズが変更されたり、Pod に障害が発生して再起動したり、ノードが再起動したりしても、サービスのユーザーにはわかりません。これは、使用しているサービスの IP アドレスが変更されないからです。データ パケットが Service の仮想 IP アドレスに到着すると、Kubernetes によってそのサービス用に自動的に作成されたロード バランサーによって、パケットは基盤となる Pod コンテナにルーティングされます。 Service は Kubernetes におけるサービス検出メカニズムであり、そのコア機能は次のように要約できます。
サービスIP割り当て戦略Kubernetes の設計理念の一つは、人為的ミスの可能性を最小限に抑えることです。サービスを設計する際には、Kubernetes はユーザーが選択したポート番号を他のユーザーが選択したポート番号から分離する必要があります。そのために、Kubernetes は各サービスに一意の IP アドレスを割り当てます。各サービスが一意の IP アドレスを持つようにするために、Kubernetes はサービスを作成する前に etcd のグローバル割り当てテーブルを更新します。更新が失敗した場合(例:IP アドレスが既に別のサービスで使用されている場合)、サービスは正常に作成されません。Kubernetes はバックグラウンド コントローラーを使用して、このグローバル割り当てテーブル内の IP アドレス割り当てが有効かどうかを確認し、サービスで使用されなくなった IP アドレスを自動的にクリーンアップします。 サービスDNS解決Kubernetes クラスターでは、対応するサービスが設定された DNS Pod のセットが実行されます。Kubernetes は、DNS 名を解決するために、各ノード上のコンテナに DNS Service の IP アドレスを割り当てます。クラスター内の各 Service(DNS Service 自体を含む)には DNS 名が割り当てられます。デフォルトでは、クライアント Pod の DNS ルックアップリストには、Pod が存在する名前空間とクラスターのデフォルトドメインが含まれます。例: 名前空間 A に foo という名前のサービスがあるとします。
インターネットとKubernetesネットワーク通信Kubernetes クラスターへのインターネット トラフィックの許可は、ネットワーク構成に固有であり、ネットワーク スタックのさまざまなレイヤーで実現できます。
NodePortサービスは、外部トラフィックをサービスにルーティングする最も基本的な方法です。名前の通り、NodePortはすべてのノード(仮想マシン)で特定のポートを開き、そのポートに送信されたトラフィックは対応するサービスに転送されます。
これは、サービスを直接公開する場合のデフォルトの方法です。指定したポート宛てのすべてのトラフィックは、対応するサービスに転送されます。フィルタリングとルーティング機能を備えています。Kubernetesをローカルの開発/テスト環境にセットアップする場合、通常はロードバランサーをサポートしていないため、NodePort経由のテストで十分なため、ロードバランサーは不要です。ただし、本番環境やパブリッククラウド上のKubernetesでは、ほとんどの場合、ロードバランサーの自動作成がサポートされています。
これは複数のサービスのフロントエンドに位置し、「スマートルーター」またはクラスタのエントリポイントとして機能します。本質的には、Kubernetesクラスタ内の特別なサービス(公開種類:Ingress)です。このサービスは、Nginxと同様に、主にレイヤー7リバースプロキシ機能を提供します(セキュリティ認証、監視、レート制限、SSL証明書などの高度な機能も提供できます)。IngressはHostPort(80/443)を介して外部に公開され、前述のロードバランサーとのインターフェースを可能にします。このIngressサービスを使用すると、1つのLB+IPアドレスのみを購入し、複数(またはすべて)の内部サービスをIngress経由で公開することで、プロキシと転送を処理できます。 |