Kubernetes ネットワークの 4 つのシナリオの分析

Kubernetes ネットワークの 4 つのシナリオの分析

この記事では、コンテナ間、Pod 間、Pod からサービス、外部から内部の 4 つのシナリオにおけるさまざまな通信モードを含む、Kubernetes ネットワークのさまざまなシナリオを紹介します。 Kubernetes コンテナ プラットフォームを設計するときは、これらの通信モードに従い、特定のシナリオに基づいて適切なソリューションを選択することをお勧めします。その中でも、外部から内部へのアクセスには特に注意を払う必要があります。

[[331143]]

インターネット企業の金融業界アーキテクト、顧文軍氏。 2008年に南京郵電大学を卒業し、回路とシステムの修士号を取得。 12年以上のキャリアの中で、主にITインフラ、クラウドコンピューティング、コンテナ、ビッグデータ、AI、金融テクノロジー関連分野のソリューション業務に従事。

実際のビジネス シナリオでは、ビジネス コンポーネント間の関係は非常に複雑です。特にマイクロサービスの概念の導入により、アプリケーションの展開の粒度がより細かくなり、より柔軟になりました。ビジネス アプリケーション コンポーネント間の通信をサポートするために、Kubernetes ネットワークの設計は主に次のシナリオの解決に重点を置いています。

(1)コンテナ間の密結合された直接通信

(2)抽象的なポッド間通信

(3)ポッドとサービス間の通信

(4)クラスターの外部コンポーネントと内部コンポーネント間の通信。

1. コンテナ間通信

同じ Pod 内のコンテナ (Pod 内のコンテナはホストを越えません) は、同じネットワーク名前空間と同じ Linux プロトコル スタックを共有します。したがって、あらゆる種類のネットワーク操作は、同じマシン上にある場合と同じになり、localhost アドレスを使用して互いのポートにアクセスすることもできます。その結果、シンプルさ、セキュリティ、効率性が高まり、既存のプログラムを物理マシンまたは仮想マシンからコンテナに移植する際の難しさも軽減されます。

次の図の網掛け部分は、ノード上で実行されている Pod インスタンスです。コンテナ 1 とコンテナ 2 はネットワーク名前空間を共有します。名前空間を共有した結果、同じマシン上で実行されているように見えます。開くポートに競合は発生せず、Linux のローカル IPC を使用して直接通信できます。相互にアクセスするには、localhost を使用するだけで済みます。

コンテナ間通信

2. ポッド間の通信

各ポッドには実際のグローバル IP アドレスがあります。同じノード内の異なるポッドは、DNS、Consul、etcd などの他の検出メカニズムを使用せずに、ポッドの IP アドレスを使用して直接通信できます。ポッドは同じノード上で実行される場合もあれば、異なるノード上で実行される場合もあるため、通信は、同じノード内のポッド間の通信と、異なるノード上のポッド間の通信の 2 つのカテゴリに分けられます。

1) 同じノード内のポッド間の通信

図に示すように、Pod1とPod2はVethを介して同じDocker0ブリッジに接続されていることがわかります。 IP アドレス IP1 と IP2 は、Docker0 のネットワーク セグメントから自動的に取得されます。これらはブリッジ自体の IP3 と同じネットワーク セグメント内にあります。また、Pod1 と Pod2 の Linux プロトコル スタックでは、デフォルトのルートが Docker0 のアドレスになっているため、ローカル以外のネットワーク データはすべてデフォルトで Docker0 ブリッジに送信され、Docker0 ブリッジによって直接転送されるため、直接通信できます。

同じノード内のポッド関係

2) 異なるノード上のポッド間の通信

Pod のアドレスは Docker0 と同じネットワーク セグメント内にあります。 Docker0 ネットワーク セグメントとホスト ネットワーク カードは 2 つの完全に異なる IP ネットワーク セグメントであり、異なるノード間の通信はホストの物理ネットワーク カードを介してのみ実行できることがわかっています。したがって、異なるノードにある Pod コンテナ間の通信を実現するには、ホストの IP アドレスを介してアドレス指定して通信する方法を見つける必要があります。一方、動的に割り当てられ、Docker0 の背後に隠されている、いわゆる「プライベート」 IP アドレスも見つかります。 Kubernetes は、実行中のすべての Pod の IP 割り当て情報を記録し、この情報を etcd (サービスのエンドポイントとして) に保存します。このプライベート IP 情報は、Pod 間通信にとっても非常に重要です。これは、ネットワーク モデルでは、Pod 間でプライベート IP を使用して通信する必要があるためです。前述したように、Pod の Kubernetes ネットワーク アドレスはフラットかつ直接的であるため、これらの Pod の IP 計画も非常に重要であり、競合があってはなりません。要約すると、異なるノード上の Pod 間の通信をサポートするには、次の 2 つの条件を満たす必要があります。

(1)競合を避けるためにKubernetesクラスタ全体でPodの割り当てを計画する。

(2)ポッドが相互にアクセスできるように、ポッドのIPアドレスをノードのIPアドレスに関連付ける方法を見つけます。

条件 1 の要件に従って、Kubernetes をデプロイするときに、各ノード上の Docker0 アドレスが競合しないように Docker0 の IP アドレスを計画する必要があります。計画後に各ノードに手動で割り当てることも、割り当てルールを作成してインストールされたプログラムに占有率を割り当てさせることもできます。たとえば、Kubernetes 用のオープンソース ネットワーク拡張ソフトウェアである Flannel は、リソース プールの割り当てを管理できます。

条件 2 の要件によれば、Pod 内のデータが送信されるときに、他の Pod の IP アドレスがどの特定のノードに接続されているかを知るためのメカニズムが必要です。つまり、まずノードに対応するホストマシンの IP アドレスを見つけ、そのデータをホストマシンのネットワーク カードに送信し、対応するデータをホストマシン上の特定の Docker0 に転送する必要があります。データがホスト ノードに到着すると、そのノード内の Docker0 はデータをポッドに送信する方法を知ります。

具体的な状況は以下の図の通りです。

ノード間のポッド通信

図 6 では、IP1 は Pod1 に対応し、IP2 は Pod2 に対応します。 Pod1 が Pod2 にアクセスすると、まずソース ノードの eth0 からデータを送信し、Node2 の eth0 を見つけてそこに到達します。つまり、データはまず IP3 から IP4 に配信され、次に IP4 から IP2 に配信される必要があります。

3. ポッドからサービスへの通信

クラスターの水平拡張と高可用性をサポートするために、Kubernetes はサービスの概念を抽象化します。サービスは、アクセス ポリシー (LB) に基づいてこの Pod グループにアクセスする Pod グループの抽象化です。

サービスを作成すると、Kubernetes はサービスに仮想 IP アドレスを割り当てます。クライアントはこの仮想 IP アドレスにアクセスしてサービスにアクセスし、サービスはリクエストをバックエンド Pod に転送する役割を担います。これはリバース プロキシに似ていますが、通常のリバース プロキシとは多少異なります。まず、IP アドレスが仮想であり、外部からアクセスするにはある程度のスキルが必要です。 2 つ目は、Kubernetes によってデプロイメントと起動および停止が統一的に自動的に管理されることです。

多くの場合、サービスは単なる概念であり、実際にサービスの役割を実装するのは、その背後にある kube-proxy サービス プロセスです。 kube-proxy サービス プロセスは、Kubernetes クラスター内の各ノードで実行されます。このプロセスは、サービスの透過プロキシおよびロード バランサとして考えることができます。その主な機能は、サービスへのアクセス要求をバックエンドの複数の Pod インスタンスに転送することです。 TCP タイプの Kubernetes サービスごとに、kube-proxy はローカル ノード上に SocketServer を確立してリクエストを受信し、バックエンドの Pod のポートに均等に送信します。このプロセスでは、デフォルトで RoundRobin 負荷分散アルゴリズムが使用されます。 Kube-proxy とバックエンド Pod 間の通信は、標準の Pod 間通信とまったく同じです。さらに、Kubernetes は、サービスの service.spec.-sessionAffinity パラメータの値を変更することで、セッション永続性機能の方向転送も提供します。値が「ClientIP」に設定されている場合、同じ ClientIP からのすべてのリクエストは同じバックエンド Pod に転送されます。さらに、Service の ClusterIP と NodePort の概念は、Iptables と NAT 変換を通じて kube-proxy によって実装されます。 Kube-proxy は、操作中にサービスに関連する Iptables ルールを動的に作成します。これらのルールは、ClusterIP および NodePort のリクエスト トラフィックを kube-proxy プロセス上の対応するサービスのプロキシ ポートにリダイレクトする機能を実装します。 Iptables メカニズムはローカル kube-proxy ポートをターゲットにするため、Pod がサービスにアクセスする必要がある場合、kube-proxy はそれが配置されているノード上で実行されている必要があり、kube-proxy コンポーネントは各 Kubernetes ノード上で実行されます。 Kubernetes クラスター内では、各ノードの kube-proxy がサービスに対して同じ転送ルールを設定するため、どのノードでもサービス クラスター IP とポートにアクセスできます。

要約すると、kube-proxy の役割により、クライアントはサービス呼び出しプロセス中にバックエンドにいくつの Pod があるかを気にする必要がありません。次の図に示すように、中間プロセスでの通信、負荷分散、障害回復はすべて透過的です。

サービス負荷分散転送

クラスター IP + ターゲット ポート方式を使用する場合でも、ノード IP + ノード ポート方式を使用する場合でも、サービスへのアクセス要求は、ノードの Iptables ルールによって、サービス プロキシの kube-proxy リスニング ポートにリダイレクトされます。 Kube-proxy は、サービスからアクセス要求を受信した後、どのようにバックエンド Pod を選択しますか?

まず、現在、kube-proxy の負荷分散はラウンドロビン アルゴリズムのみをサポートしています。アルゴリズムはメンバーリストに従ってメンバーを 1 つずつ選択します。 1 サイクルが完了すると、次のラウンドが最初から開始され、サイクルが繰り返されます。 Kube-proxy のロード バランサは、ラウンド ロビン アルゴリズムに基づくセッションの永続性もサポートします。サービスが定義でセッション永続性を指定している場合、kube-proxy はリクエストを受信すると、ローカル メモリを調べて、リクエスト IP からの AffinityState オブジェクトがあるかどうかを確認します。オブジェクトが存在し、セッションがタイムアウトしていない場合、kube-proxy はリクエストを、affinityState が指すバックエンド Pod にリダイレクトします。要求 IP からの affinityState オブジェクトがローカルにない場合は、要求された IP とそれが指すエンドポイントを記録します。後続のリクエストは作成されたaffinityStateオブジェクトに添付され、クライアントIPセッションの永続化機能が実現されます。

次に、kube-proxy の実装の詳細を詳しく分析します。 kube-proxy プロセスは、各サービスに対して「サービス プロキシ オブジェクト」を作成します。サービス プロキシ オブジェクトは、kube-proxy プログラム内のデータ構造です。サービス要求をリッスンするためのソケット サーバーが含まれています。 SocketServer のポートはランダムに選択されたローカルの空きポートです。さらに、SocketServer で受信した接続とバックエンドの複数の Pod 接続間の負荷分散とセッションの永続性を実現するために、kube-proxy 内に「ロード バランサ コンポーネント」も確立されます。

kube-proxy は、API サーバーでサービスとエンドポイントの変更を照会および監視することで主な機能を実装します。これには、新しく作成されたサービスのローカル プロキシ オブジェクトを開くこと (プロキシ オブジェクトは kube-proxy プログラム内のデータ構造です。サービス ポートはプロキシ オブジェクトであり、サービス要求を監視するための SocketServer が含まれます)、要求を受信すること、変更されたサービス リストを 1 つずつ処理することが含まれます。具体的な処理フローは以下のとおりです。

(1)サービスにクラスタIP(ClusterIP)が設定されていない場合は、処理は行われません。それ以外の場合は、サービスのすべてのポート定義のリストを取得します(spec.portsフィールド)

(2)サービスポート定義リスト内のポート情報を1つずつ読み取り、ポート名、サービス名、名前空間に基づいて、対応するサービスプロキシオブジェクトがローカルに既に存在するかどうかを判断します。存在しない場合は、新しいものを作成してください。存在し、サービス ポートが変更されている場合は、まず Iptables 内のサービスに関連するルールを削除し、サービス プロキシ オブジェクトを閉じてから、新規作成プロセスを実行します。つまり、サービス ポートにサービス プロキシ オブジェクトを割り当て、サービスに関連する Iptables ルールを作成します。

(3)ロードバランサコンポーネント内の対応するサービスの転送アドレステーブルを更新し、新しく作成されたサービスに対して、転送中のセッション持続戦略を決定します。

(4)削除されたサービスをクリーンアップします。

Kube-proxyとAPIServer間の相互作用プロセス

4. 外部から内部へのアクセス

基本的なリソース オブジェクトとして、Pod はクラスター内の Pod によってアクセスされ、外部からも使用できます。サービスは、同じ機能を持つ Pod のグループを抽象化したものです。サービスを単位として使用して外部にサービスを提供するのが最も適切な粒度です。

クラスター IP 範囲プール内のサービス オブジェクトに割り当てられた IP は内部的にのみアクセス可能であるため、他のポッドは障害なくアクセスできます。ただし、このサービスがフロントエンド サービスとして使用され、クラスター外部のクライアントにサービスを提供する準備ができている場合は、外部から見えるようにする必要があります。

Kubernetes は、外部サービスに対して NodePort と LoadBalancer という 2 種類のサービス タイプ定義をサポートしています。

(1)ノードポート

サービスを定義するときは、spec.type=NodePort を指定し、spec.ports.nodePort の値を指定します。システムは、Kubernetes クラスター内の各ノードのホスト上で実際のポート番号を開きます。このようにして、ノードにアクセスできるクライアントは、このポート番号を介して内部サービスにアクセスできます。

(2)ロードバランサー

クラウド サービス プロバイダーが外部ロード バランサーをサポートしている場合は、spec.type=LoadBalancer を使用してサービスを定義し、ロード バランサーの IP アドレスを指定できます。このタイプを使用するには、サービスの NodePort と ClusterIP を指定する必要があります。

このサービスへのアクセス要求は、LoadBalancer を介してバックエンド Pod に転送されます。負荷分散の実装方法は、クラウドサービスプロバイダーが提供する LoadBalancer の実装機構に依存します。

(3)内部サービスへの外部アクセスの原則

クラスターの外部からクラスターの内部にアクセスすると、最終的には特定の Pod にアクセスします。 NodePort メソッドは、kube-proxy を外部に公開し、Iptables を使用してサービスの NodePort のルールを設定し、サービスへのアクセスを kube-proxy に転送します。このようにして、kube-proxy は、内部 Pod がサービスにアクセスするのと同じ方法で、バックエンドの Pod グループにアクセスできます。このモードでは、kube-proxy をロードバランサーとして使用して、サービス、さらには Pod への外部アクセスを処理します。より一般的に使用されるのは外部イコライザー モードです。一般的な実装は、クラスター内のすべてのノードを対象とする外部ロード バランサーを使用することです。ネットワーク トラフィックが LoadBalancer アドレスに送信されると、それがサービスの一部であることが認識され、適切なバックエンド Pod にルーティングされます。

したがって、外部から内部 Pod リソースにアクセスするためのさまざまな組み合わせが存在します。

  • 外部にロードバランサはなく、内部ポッドに直接アクセスする
  • 外部にロードバランサはなく、内部ロードバランサにアクセスすることでポッドに直接アクセスする
  • 外部にロードバランサがあり、内部ポッドは外部ロードバランサを介して直接アクセスされます。
  • 外部にロードバランサがあり、内部ロードバランサにアクセスすることで内部Podにアクセスします

最初の状況は非常にまれであり、特別な状況でのみ必要になります。実際の運用プロジェクトでは、開始された Pod に 1 つずつアクセスし、更新コマンドを送信する必要があります。この場合のみこの方法を使用してください。これには、サービス下のエンドポイント リストを読み取り、これらのポッドと 1 つずつ通信するための追加プログラムの開発が必要です。このタイプの通信は通常、たとえば各ポッドがコマンドをプッシュするのではなく、集中データ ソースからコマンドをプルすることによって回避されます。各 Pod の開始と停止は動的であるため、特定の Pod に依存すると、Kubernetes Service メカニズムをバイパスするのと同じことになります。実装することは可能ですが、理想的ではありません。

2 番目のケースは NodePort メソッドで、外部アプリケーションがサービスの NodePort に直接アクセスし、Kube プロキシ ロード バランサーを介して内部 Pod にアクセスします。

3 番目のケースは LoadBalancer モードです。外部 LoadBalancer は Kubernetes の知識を持つロードバランサーであるため、サービスの作成をリッスンし、バックエンド Pod の開始と停止の変更を認識し、バックエンド Pod と通信することができます。しかし、ここで注意すべき問題があります。それは、ロードバランサーが Pod と直接通信する方法が必要であるということです。つまり、外部ロードバランサーは Pod 間と同じ通信メカニズムを使用する必要があります。

4 番目のケースは、2 段階の負荷分散装置を通過する必要があり、ランダムに 2 回負荷分散された後はネットワーク呼び出しを追跡するのが難しくなるため、ほとんど使用されません。実際の運用環境で問題をトラブルシューティングする場合、ネットワーク データの流れを追跡することは困難です。

(4)外部ハードウェアロードバランサモード

実際の運用環境の多くでは、Kubernetes クラスターはプライベート クラウド環境にデプロイされるため、従来のロード バランサーはサービスを認識しません。実際、これをサービス対応ロードバランサーに変えるには 2 つの問題を解決するだけで済みます。これは、実際のシステムで Kubernetes クラスターへの外部アクセスに最適なモードでもあります。

  • サービスの変更を監視するプログラムを作成し、ロード バランサーの通信インターフェイスに従って、変更をルールとしてロード バランサーに書き込みます。
  • ロードバランサーが Pod に直接アクセスするための通信方法を提供します。

次の図はこのプロセスを示しています。

サービスにアクセスするためのカスタム外部ロードバランサー

ここでは、サービスの変更を認識するためにサービス エージェントが提供されます。エージェントは、etcd から直接、またはインターフェースを介して API サーバーを呼び出すことによって、サービスとエンドポイントの変更を監視し、変更を外部ハードウェア ロード バランサーに書き込むことができます。

同時に、各ノードはルーティング検出プロトコルを備えたソフトウェアを実行し、ハードウェア ロード バランサーを含むルーティング検出プロトコルを介して、ノード上のすべてのアドレスをネットワーク内の他のホストにマルチキャストする役割を担います。このようにして、ハードウェア ロード バランサーは、各 Pod インスタンスの IP アドレスがどのノード上にあるかを知ることができます。上記の 2 つの手順により、ハードウェア ベースの外部対応サービス ロード バランサーが確立されます。

具体的なケースについては、第 5 章の実践部分を参照してください。

5. 結論

この章では、コンテナ間、ポッド間、ポッドからサービス、外部から内部の 4 つのシナリオにおけるさまざまな通信モードを含む、Kubernetes ネットワークのさまざまなシナリオに焦点を当てています。 Kubernetes コンテナ プラットフォームを設計するときは、これらの通信モードに従い、特定のシナリオに基づいて適切なソリューションを選択することをお勧めします。その中で、外部から内部へのアクセスは NodePort、LoadBalancer、または Ingress モードを通じて実現できることに注意することが重要であり、これは特定のシナリオに応じて分析する必要があります。

NodePort サービスは、サービスを公開する最も原始的な方法です。すべてのノードで特定のポートを開き、このポートに送信されたトラフィックはすべてサービスに転送されます。この方法には多くの欠点があります。各ポートには 1 つのサービスしか設定できません。デフォルトでは、ポート 30000 ~ 32767 のみを使用できます。ノードの IP アドレスが変更されると、問題が発生します。これらの理由から、このアプローチを本番環境で使用することは推奨されません。このソリューションは、サービスの可用性が特に問題にならない場合、またはコストが特に問題になる場合に適しています。

LoadBalancer はサービスを公開するための標準的な方法です。ネットワーク ロード バランサーを起動し、すべてのトラフィックをサービスに転送する IP アドレスを提供します。これは、サービスを直接公開する場合のデフォルトの方法です。指定されたポート上のすべてのトラフィックは、フィルタリングやルーティングなどを行わずにこのサービスに転送されます。つまり、HTTP、TCP、UDP、Websocket、gRPC など、ほぼすべてのタイプのトラフィックを送信できます。このアプローチの最大の欠点は、LoadBalancer を使用して公開される各サービスが独自の IP アドレスを取得し、各サービスに対して LoadBalancer を使用する必要があるため、コストがかかることです。

Ingress は実際にはサービスではありません。代わりに、複数のサービスの前に配置され、「スマート ルーター」またはクラスターへのエントリ ポイントとして機能します。デフォルトの Ingress コントローラは HTTP(s) ロードバランサを起動します。これにより、バックエンド サービスへのパスベースおよびサブドメインベースのルーティングが可能になります。 Ingress はおそらくサービスを公開する最も強力な方法ですが、最も複雑になる可能性もあります。 Ingress は、複数のサービスを同じ IP アドレスで公開し、それらのサービスがすべて同じ L7 プロトコルを使用する場合に最も役立ちます。

<<:  クラウド コンピューティング: 金融市場の未来がクラウドにある理由

>>:  エッジコンピューティングがトレンドである理由

推薦する

地域求人サイト運営:ユーザー・顧客に「無形の美」を体感してもらう

地方求人サイトは地方ウェブサイトの重要な部分として、過去2年間でますます大衆の注目と企業の支持を集め...

Douno ブログ: 正確なトラフィックを獲得する方法

オンラインマーケティングの過程でよく言及されるのは、正確なトラフィックです。正確なトラフィックがオン...

Baidu の重量 ≠ ウェブサイトの重量

今日、厦門SEOはA5ウェブマスターのウェブサイトで記事を見ました。タイトルは「ウェブマスターはウェ...

入札アカウントで重複キーワードを処理する方法

入札アカウントでのキーワードの重複は、すべての入札担当者が遭遇する一般的な問題です。この問題に対する...

Ancestry.com が売却を検討中:情報筋

北京時間6月6日、外国メディアの報道によると、事情に詳しい情報筋は、米国の系図ウェブサイト「Ance...

主流のプロモーションチャネルのインベントリと分析、1000万のプロモーション費用の使い方を教える

どのプロモーション チャネルがより効果的かとよく聞かれます。現在、複数のチャネルで同時にプロモーショ...

Kubernetes マイクロサービス自動リリース システム

[[340132]]この記事はWeChatの公開アカウント「Invincible Coder」から転...

米国/英国/ドイツ/カナダのネイティブ住宅用 IP: tryrdp、最低 25 ドル、1Gbps の帯域幅、無制限のトラフィック

tryrdp。ざっと調べてみたところ、2006年に設立された会社であることがわかりました。名前から、...

Robin Li: 人口ボーナスは消え、モバイルインターネットはボトルネックになり、未来は人工知能に依存するようになるでしょう!

昨日、百度連合サミットが雲南省大理市で開催されました。百度の創業者で会長兼CEOのロビン・リー氏はス...

ギフトウェブサイトがホリデーマーケティングにドリフトボトルをどのように活用しているかについて簡単に説明します

QQドリフトボトルは、QQメールボックス内のこの小さなゲームがしばらくの間人気を博しました。最初は誰...

最適化はどこにでもある

私が SEO に携わっているからかもしれませんが、多くの場合、SEO は、国の最適化、会社の最適化、...

独立系ブログが徐々に消滅しつつある根本的な理由について簡単に議論する

個人ブログが流行り出してから6年以上が経ちました。新しい有名ブロガーが台頭してきた一方で、**だらけ...

コンテンツ マーケティングの 4 つの波: テキスト、画像、パーソナライゼーション、次のステップはマーケティング アプリケーションでしょうか?

コンテンツ マーケティングは、最初はシンプルなテキスト、その後は画像、そしてパーソナライズされたカス...

盲目にならないでください: Baidu 製品の外部リンクは単なる伝説かもしれません (原文)

SEO を行うほとんどの人はリンク構築プロセスに接することになりますが、もう少し経験を積んだ人は、高...

テンセントクラウドTStackが「次世代クラウドコンピューティング技術革新賞」を受賞、クラウドエコ情報の革新的発展を促進

12月16日〜17日、中国電子技術標準化協会主催の「第9回中国クラウドコンピューティング標準および応...