記事は写真を中心に展開され、物語を語ります。ただし、このトピックは非常に広範囲にわたるため、明確に説明するには複数の記事が必要になると思います。 代表的なクラウドネイティブ テクノロジーには、コンテナー、サービス メッシュ、マイクロサービス、不変インフラストラクチャ、宣言型 API などがあります。その中でも、K8s は不変のインフラストラクチャの重しとなります。典型的な K8s クラスターは、数十のノード、数百のポッド、数千のコンテナで構成されます。大規模なアプリケーションを完成させるには、分離されたコンテナが連携する必要があります。そしてコラボレーションにはネットワーク通信が必要です。 この記事では、主に次のパノラマ画像を使用して、K8s が VXLAN を使用して K8s コンテナ通信ソリューションを実装する方法を説明します。ネットワーク通信は量子もつれではありません。ネットワーク トラフィックは、実際にはさまざまな仮想および物理ネットワーク デバイスを通過します。各デバイス ノードを通過する際は、当然のことながら、デバイス上のルーティング、iptables、その他のポリシーによって制御されます。 図: VXLAN コンテナ ネットワーク ソリューションの概要 K8s には多くのコンテナ通信ソリューションがあります。たとえば、flannel によって実装された host-gw ソリューション、3 層転送に基づいて calico によって実装されたソリューション、およびこの記事で焦点を当てた flannel.1 VXLAN ソリューションなどです。 flannel.1 VXLAN ソリューションについて詳しく説明することにしたのはなぜでしょうか?複雑であり、多くの仮想ネットワーク デバイスとネットワーク テクノロジが関係するためです。 この図には次のネットワーク デバイスが関係しています。機会があれば、これらのデバイスについて説明する別の記事を書く予定です。
コンテナ間のネットワーク ソリューションはさまざまですが、コンテナ ネットワーク通信の問題はすべて、実際には次のシナリオに起因します。この記事では、コンテナ間の通信のシナリオに焦点を当てているため、他の通信主体がコンテナと通信する状況については省略しています。たとえば、ローカル ノード内のプロセスもコンテナーと通信します。イースターエッグを残しておいて、それについては後で話します。
ここで強調する必要がある点は、Pod は K8s オーケストレーションとスケジューリングの基本単位であるにもかかわらず、通信の必要性は Pod 内のコンテナから発生するということです。 環境説明この図では、ノード 1 とノード X は同じ LAN 17.168.0.0/24 にあります。ノード 1 の IP アドレスは 17.168.0.2 で、ノード X の IP アドレスは 17.168.0.3 です。 K8s クラスターが使用するサブネットは 10.244.0.0/16 です。ネットワーク 17.168.0.0/24 とその中のスイッチおよびルーターの場合、K8s クラスターによって使用されるサブネットは無効なネットワークです。スイッチとルーターは、送信元または宛先 IP が K8s サブネットであるデータ パケットを転送またはルーティングできません。 非常に明らかな矛盾が生じます。K8s クラスターはサブネット 10.244.0.0/16 を介して通信しますが、ホスト環境はこのサブネットをまったく認識しません。ここで再び「トロイの木馬」の物語が起こります。 私たちの目標は、この矛盾したネットワーク環境で、ポッド a のコンテナ 1 がポッド b のコンテナ 1 にアクセスした場合に何が起こるかを説明することです。図の青い線はデータフローの方向を示しています。 図中の緑色の線と緑色のボックスは、VXLAN に関連するデータ フローおよびネットワーク パケット図を表しています。 簡単にするために、ノード 1 には 1 つのポッド (ポッド a) のみが描画されています。すべてのポッドは、サブネット 10.244.0.1/24 のブリッジ cni0 に接続されています。ノード X には、Pod B と Pod C の 2 つの Pod のみが描画されます。すべての Pod は、サブネット 10.244.1.1/24 のブリッジ cni0 にも接続されています。 ノード上の各ブリッジには IP アドレスが割り当てられます。 Pod a の IP アドレスは 10.244.0.2 で、Pod b の IP アドレスは 10.244.1.3 です。 同じポッド内のコンテナ間の通信これは最も単純なケースです。カーネルには独自の機能があり、追加のネットワーク テクノロジは必要ありません。 強調する必要がある知識の 1 つのポイントは、Pod 内のすべてのコンテナは同じネットワーク名前空間に属しているため、同じネットワーク スタック、ルート、および iptables を共有するということです。 k8s クラスター内では、各ポッドに固有の IP アドレスがあり、ポッド内のすべてのコンテナはポッドに割り当てられたアドレスを共有します。 Pod 内のコンテナは Pod の IP アドレスを共有しますが、各コンテナのポートは競合できません。 Pod スケジューリングのアトミック性により、Pod 内のすべてのコンテナは 1 つのホストでのみ実行されるようにスケジュールされます。ローカルマシン上の 2 つのアプリケーションが localhost を介して相互に通信するのと同様に、同じ Pod 内のコンテナーは localhost を介して直接通信できます。このとき、トラフィックはループバック ネットワーク デバイスを介して 2 つのコンテナー間を直接流れます。図のブリッジはこのようなトラフィックを認識できず、ホスト上のネットワーク スタックやその他のネットワーク デバイスもそれを認識できません。 同じノード内のコンテナ間の通信図では、ノード X に複数のポッドが描かれています。このシナリオは、ポッド b のコンテナ 1 がポッド c のコンテナ 1 にアクセスする場合に発生します。 Pod b のルーティング テーブルは、Pod c へのトラフィックが独自のインターフェイス eth0 から送信される必要があることを決定しています。
図から、Pod b と Pod c の両方がブリッジに接続されていることがわかります。仮想レイヤー 2 スイッチとして、レイヤー 2 スイッチの動作に従ってデータ パケットを切り替えて転送します。 このシナリオでは、2 つのコンテナ間の通信はブリッジの範囲を超えません。これには、Pod b のコンテナ 1 が ARP を介して取得した宛先コンテナの MAC アドレスも含まれます。この MAC アドレスもブリッジ内で処理されます。 NAT などのアドレス変換操作は行われません。 ノード間のコンテナ間の通信これは最も一般的に使用される通信シナリオです。 API サーバーへのコンテナ アクセスが典型的な例です。 ここで、ノード 1 で実行される最も複雑な手順から始めます。イーサネット フレームを受信した後、ノード X の動作は逆のプロセスであるため、ここでは説明しません。 通過する各ネットワーク デバイス (仮想および物理) をセグメント ノードとして使用してトラフィックのフローを追跡し、各セグメントで何が発生するかを説明します。 コンテナからcni0へPod a のルーティング テーブルから、イーサネット フレームは NIC eth0 から送信される必要があることがわかります。 eth0 は veth の一方の端であり、もう一方の端はブリッジ cni0 に接続されているため、イーサネット フレームは cni0 に入ります。このイーサネット フレームの宛先 MAC アドレスはブリッジです。
cni0からflannel.1まで前述したように、ブリッジは IP アドレスで構成されます。ここで、独自の宛先 MAC アドレスを持つデータ パケットを受信し、Linux Bridge の特別な転送ルールがトリガーされます。ブリッジはこのデータ パケットをどのデバイスにも転送せず、処理のためにホストの 3 層プロトコル スタックに直接転送します。 ホスト プロトコル スタックは、ホストのルーティング テーブルから、IP パケットをローカル フランネルに渡す必要があることを認識します。1. このステップ以降はレイヤー 3 ルーティングとなり、ブリッジの範囲内ではなくなります。代わりに、Netfilter に依存して IP 転送 (IP 転送) を実行する Linux ホストによって実装されます。これは IP パケット転送であることに注意してください。受信側はレイヤー 3 パッケージを受信するため、レイヤー 2 データは含まれません。 flannel.1は内部データフレームを組み立てるこの時点で、数千マイルを移動した後、ローカル マシンの flannel.1 がようやく IP パケットを受信しました。 ここから、flannel.1 は錯覚を作り出す方法を見つける必要があります。つまり、ホスト間で仮想ネットワーク 10.244.0.0/16 を作成し、Pod a が Pod b のように見え、自由で妨げのない情報交換が行われる完全に合法的な環境になるようにします。単純なポッドは、このネットワークが仮想のプライベート ネットワークであるという事実をまったく認識しておらず、ホスト ネットワーク内のスイッチとルーターはそれをまったく認識しません。 前述のように、flannel.1 は IP パケットを受信します。 IP パケットなので MAC アドレスはありません。ただし、flannel.1 は、「元の IP パケット」に宛先 MAC アドレスを追加し (もちろん、flannel.1 の送信元 MAC アドレスも含める必要があります)、それを完全なレイヤー 2 データ フレームにカプセル化してから、ノード X の flannel.1 に送信する必要もあります。 ご存知のとおり、完全なレイヤー 2 データ フレームを組み立てるには、まずターゲット フランネルの MAC アドレスが何であるかという問題を解決する必要があります。1次のプロンプトが答えを示します。 ノード X 上の flannel.1 の MAC アドレスは何ですか?パケットの宛先であるノード X 上の flannel.1 の IP アドレスはすでにわかっています。レイヤー 3 IP アドレスに基づいて対応するレイヤー 2 MAC アドレスを照会することが、まさに ARP (アドレス解決プロトコル) テーブルの機能です。ここで使用される ARP レコードは、ノード 1 が起動されると、flanneld プロセスによってノード 1 に自動的に追加されます。次のように ip コマンドで確認できます。 # ノード1上 ARP を通じて、宛先 flannel.1 の MAC が 5e:f8:4f:00:e3:37 であることがわかります。この時点で、内部データ ペイロード、内部 IP ヘッダー 10.244.1.3、および内部イーサネット ヘッダー 5e:f8:4f:00:e3:37 が完全に生成されています。 ただし、上記の VTEP デバイスの MAC アドレスはホスト ネットワークにとって実用的な意味を持たないため、上記でカプセル化されたデータ フレームはホスト レイヤー 2 ネットワークでは送信できません。説明の便宜上、これを「内部データ フレーム」(Inner Ethernet Frame)、または「元のレイヤー 2 フレーム」(Original Layer 2 Frame) と呼びます。 カプセル化された内部データ フレームは、パノラマの青いボックスに表示されます。 次に、Linux カーネルは、「元のレイヤー 2 データ フレーム」をホスト ネットワーク内の共通の外部データ フレームにさらにカプセル化する必要があります。これにより、「元のレイヤー 2 データ フレーム」を運び、ホストの eth0 ネットワーク カードを介して送信できるようになります。 flannel.1はVXLANデータフレームを組み立てる次の図に示すように、元のレイヤー 2 データ フレームに VXLAN ヘッダーが追加され、これを「VXLAN データ フレーム」と呼びます。全体像では、VXLAN ヘッダーを表すために青いボックスの上に灰色のボックスを追加しました。灰色のボックス内の VNI=1 の部分に特に注意してください。 VNI(仮想ネットワーク識別子)の長さは24ビットです。ここで、flannel.1 はデフォルトで 1 に設定されています。このようにして、ノード X 上の flannel.1 は、このデータ フレームを処理する必要があることを認識します。
VXLAN データ フレームを使用すると、「トロイの木馬」と同じ状況が起こり始める可能性があります。 VXLAN データ フレームはギリシャの戦士のようなものですが、私たちの目的はトロイの街を攻撃することではなく、VXLAN データ フレームを無傷で気付かれずに街の flannel.1 に届けることです。この目標を達成するには、トロイの木馬も必要です。 図: VXLAN データフレーム flannel.1からUDP接続を開始します。さて、これで「ギリシャの戦士」が揃いました。あとはトロイの木馬だけです。次に行うことは、ギリシャの戦士をトロイの木馬の中に隠すのと同じように、Linux カーネルが VXLAN データ フレームを UDP パケットに詰め込んで送信することです。上のパノラマでは、外側の少し太い UDP パケットがトロイの木馬のように見えることがわかるように、意図的に VXLAN データ フレームを狭くしています。 ノード 1 の flannel.1 デバイスは、レイヤー 2 ネットワークで UDP パケットをカプセル化して転送する「ブリッジ」の役割を果たします。ノード 1 の観点からは、flannel.1 デバイスが別のホストの flannel.1 デバイスへの通常の UDP リンクを開始しているだけであると考えますが、トロイの木馬を送信していることにはまったく気づきません (心配しないでください。このトロイの木馬はトロイの木馬ウイルスではありません)。 しかし、待ってください。まず質問に答えましょう。今、内部データ フレームを組み立てたとき、flannel.1 デバイスは宛先 flannel.1 デバイスの MAC アドレスをすでに認識していますが、この UDP パケットはどのホストに送信すればよいのでしょうか。つまり、トロイの木馬はそこにあり、ギリシャの戦士たちもトロイの木馬の腹の中に隠れているのですが、トロイの街はどこにあるのでしょうか? 転送データベース (FDB) が助けになるときが来ました。この flannel.1「ブリッジ」に対応する FDB 情報も、flanneld プロセスによって維持されます。その内容は、次に示すように bridge fdb コマンドを使用して表示できます。 # ノード1では、宛先VTEPデバイスのMACアドレスを使用してクエリを実行します。 上記の FDB レコードでは、上記の「宛先 flannel.1」(MAC アドレスは 5e:f8:4f:00:e3:37) に送信されたレイヤー 2 データ フレームは、ローカル flannel.1 デバイスを介して IP アドレス 17.168.0.3 のホストに送信されるというルールが指定されています。明らかに、このホストはノード X であり、UDP パケットの宛先が見つかりました。 宛先 IP アドレスが取得されると、ノード X の MAC アドレスもわかります。次のプロセスは、ホスト ネットワーク上の通常のパケット カプセル化プロセスであり、最終的にはノード 1 の eth0 ネットワーク カードから送信されます。唯一の違いは、このプロセスが仮想デバイス flannel.1 で実行されることです。 |
<<: できるだけ少ない費用で、できるだけ多くのクラウドを楽しむにはどうすればよいでしょうか?
>>: 成功する GitOps モデルを開発するための 3 つのステップ
文/王静5月30日、広州オプティマスプライムネットワークテクノロジー株式会社(以下、「オプティマスプ...
[[394145]]この記事は、Qiao Ke 氏が執筆した WeChat パブリックアカウント「運...
Zap5 は、2005 年に設立されたカナダのインターネット企業です。主な事業は Web デザインと...
ファストフードチェーンの閉店であろうと、有名な小売店の倒産であろうと、人々はそれについて話すのが大好...
2018年には、工業情報化部による「企業のクラウド移行促進実施ガイドライン(2018~2020年)」...
日曜日から私のブログがダウンしているのはなぜかと誰かが尋ねるかもしれません。隠すことは何もありません...
今日、私はTitanium Mediaで「パンケーキのインターネットの夢」というタイトルの黄太極に関...
国内のオプティマイザーは基本的にBaiduの最適化を行います。また、Baidu が常に自社製品に対し...
Hostsolutions の社長が戻ってきました (体調不良だそうです)。プロモーション用に 50...
このミニゲームは4か月間オンラインになっているが、今月初めの清明節までサードパーティへのリリースは正...
Limewave は独自のネットワーク AS36369 と IP を持っています。現在はインターネッ...
プロモーションプロセス中にトラフィックを適切に誘導するにはどうすればよいでしょうか?今日は、Weib...
ウェブサイトのスペース要因がウェブサイトに大きな影響を与えることは誰もが知っているので、スペースを購...
起業家が独自に製品を作り、開発していくのはもちろん良いことですが、場合によっては「買収される」という...
A5 フォーラムで、SEO 最適化のためのコツがあるかどうか尋ねる初心者を見ました。私の答えは、はい...