この記事は、「Illustrated VPC & K8s Network Model」という書籍の一部です。原稿はまだ執筆中ですが、私の次兄は心配も焦りもしていないので、進捗は早くもなく遅くもありません。良い肉はゆっくり調理する必要があり、良い本は長い時間をかけて磨く必要があります。 なぜこのトピックを個別に議論する必要があるのでしょうか?なぜなら、同僚と K8s ネットワーク、特にネットワーク データのフローについて話し合うとき、私は物理か仮想かを問わず、ネットワーク デバイスについて繰り返し言及するからです。これまでに説明したデータ フローのシナリオでは、ネットワーク デバイスはデータを受信することもあれば、データを送信することもあります。つまり、Ingress と Egress という 2 つの役割を果たします。 また、eBPF 関連のコンテンツ、特に tc eBPF を整理していたところ、データフローにおいてネットワークデバイスが Ingress なのか Egress なのかを正確に識別できなければ、tc eBPF を理解するどころか、コードロジックと実際の実行結果を一致させることもできないということが改めて分かりました。 こうした二重の役割を演じることは、複雑なネットワークの中で常にマスクをかぶって自由に隠れて遊ぶいたずらっ子のようなものです。そして、ついにそれを捕まえると、その瞬間に彼が誰であるかを推測するように求められます。 簡単に言うと、ネットワーク カードの場合、それが物理か仮想かに関係なく、Ingress ロールではデータに最初に触れるユーザーであり、Egress ロールではデータに最後に触れるユーザーです。 この記事では、まず単純な物理ネットワーク カードから始めて、次に veth、bridge、tc eBPF についてそれぞれ説明します。
1. 単一の物理ネットワークカード図1 これは物理ネットワーク カードを使用した簡単な図です。デスクトップ コンピューターは通常、このように構成されています。オレンジ色の線は入力フローを表し、青色の線は出力フローを表します。 (1)入力プロセスイングレスこのネットワーク カードの場合、入力プロセスには次の重要なことが伴います: 物理ネットワーク カードが最初に物理信号を受信 -> 物理ネットワーク カードが DMA メカニズムを介してデータを専用の RingBuffer に保存 -> CPU への割り込みを開始 -> OS カーネル スレッド ksoftirqd/x が RingBuffer 内のデータを継続的に消費します。
ksoftirqd/x は、skb を処理粒度として、リンク層、ネットワーク層、TCP/UDP トランスポート層を順番に通過してデータを渡します。ただし、skb はリンク層およびネットワーク層で他のネットワーク カードに直接転送される場合があります。この場合、トランスポート層は skb を受信しません。 全体のプロセスは図 2 に示されており、概要を把握することができます。ラベル 1 と 1.x は、この記事の焦点となるデータ入力と生成のプロセスです。 3 はデータ消費プロセスであり、入口の net_rx_action() からの skb をプロトコル スタックの下から上へ運びます。このプロセスは、この記事で説明するすべての Ingress シナリオに共通であるため、以降のテキストでは繰り返されません。 図2 概要:物理ネットワーク カードが Ingress の役割を果たす場合、ホスト外部からデータを受信し、そのデータをリング キューに送信し、その後 ksoftirqd/x が後続の処理を実行します。この処理プロセスは、ネットワーク スタックの下部とも呼ばれます。 (2)出力プロセス出力図 1 から、出力プロセスには、ip_forward() プロセスを介して送信されるデータと ip_local_out() プロセスを介して送信されるデータの 2 つのデータ ソースがあることが大まかにわかります。また、データを送信する経路では、2 つのプロセスは開始点がわずかに異なるだけで、残りの経路は同じであることがわかります。 ip_forward() プロセスは、IP 層での skb のルーティング結果に大きく関係します。図 3 に示すように、具体的には、ルーティングの決定後、skb をローカル ネットワーク デバイスまたはネットワーク内の他のホストに転送して処理する必要がある場合があります。ただし、どちらの場合でも、skb をローカル ネットワーク デバイスに送信する必要があります。 図3 ip_local_out() プロセスは、図 4 に示すように、ローカル プロセスがソケットを介してデータを送信するシナリオに対応します。この図の最後にある「NET_RX タイプのソフト割り込みがトリガーされました」は、ネットワーク カードによってデータが送信された後に発生するものです。割り込みの目的は skb をクリーンアップすることですが、ここでは省略します。 図4、出典:「内部力育成の推進」公開アカウント 概要:物理ネットワーク カードが出力の役割を果たす場合、ローカル TCP/IP プロトコル スタックからデータを受信し、ドライバーを介してローカル マシンからデータを送信します。 2. ベスペア単一のネットワーク カードのシナリオで Ingress と Egress を区別するのは簡単だと思いますか? 満足しないで、もっと難しくしましょう。 K8s のデフォルトの CNI フランネルは veth を使用することがわかっています。 veth とは何か、その機能については詳しく説明しません。トピックについて話しましょう: 図 5 で、左側のプロセスが右側のプロセスにデータを送信するとき、左端の veth_left は Ingress ですか、それとも Egress ですか?右端の veth_right はどうでしょうか? 図5 図 5 の矢印と組み合わせると、答えを推測するのは難しくないはずです。 veth_left の場合、プロセスはそれを介してデータを送信する必要があるため、出力の役割を果たします。 veth_right の場合は、データを受信して右側のプロセスに送信する役割を担うため、Ingress になります。 次の質問: veth_left は出力の役割を果たすので、ネットワーク名前空間 1 を離れた後、トラフィックはどこに行くのでしょうか? veth_right は Ingress なので、どこからトラフィックを受信するのでしょうか? 答えはすべて図 6 にあります。図では、データ転送は 2 と 2.x によって実行されており、どちらも veth_left の Egress プロセスの一部です。このプロセスはネットワーク名前空間 1 で発生し、関数呼び出しスタックは図 4 と同じです。ラベル 3 はデータ消費であり、veth_right の Ingress プロセスです。このプロセスは、物理ネットワーク カードの場合とまったく同じです。 図6 要約: veth は仮想ネットワーク カードのペアなので、この 2 つを要約してみましょう。 veth ネットワーク カードが出力の役割を果たす場合 (図 7 の veth_left など)、ネットワーク名前空間の TCP/IP プロトコル スタックからデータを受信し、そのデータを CPU ごとの input_pkt_queue キューに配信し、ソフトウェア割り込みをトリガーします。 図 7 の veth_right のように、veth NIC が Ingress の役割を果たす場合、物理 NIC のような循環キューはありません。代わりに、ksoftirqd/x は、CPU ごとの input_pkt_queue キューから veth_left によってプラグインされたデータを直接読み取ります。 veth_left と veth_right は同じキューを共有します。これは典型的なプロデューサー/コンシューマー設計パターンを思い出させますか? 図7 3. ブリッジ前のセクションでは、2 番目の兄弟が、全員が見られるように、veth ペアを別々に取り出しました。しかし、それらはあくまでも花瓶ではなく、実用的価値を持つように作られたものです。 veth の一般的な使用シナリオは、図 8 に示すように、一方の端をブリッジに挿入することです。 veth の特性により、下の図ではトラフィックが veth1-left から流出した後、veth1-right に入り、つまりトラフィックがブリッジに入ることになります。 この時点で、veth1-left が Egress であり、veth1-right が Ingress であることが確実だと思います。ブリッジのポート 1 とポート 2 はどうですか?さらに一歩進んで、veth2-left と veth2-right はどうでしょうか? 図8 実際、ブリッジのような仮想ブリッジの場合、そのポートも仮想概念です。もっと簡単に言えば、カーネル内では struct net_bridge_port というデータ構造になります。この構造体には、br / port_no / dev という 3 つの重要なメンバーがあります。次のコードは、ネットワーク デバイスをブリッジに挿入するために使用されます。これら 3 つのメンバーの機能は明らかです。 //ファイル: net/bridge/br_if.c 図 8 では、ポート 1 (net_bridge_port) が接着剤であり、左側がブリッジ、右側が veth1-right です。この点を理解すると、ブリッジ ポートには入力と出力の概念がないことも明らかになります。 veth1-right が Ingress にあるため、ポート 1 はデータを受信します。ブリッジがトラフィックを veth2-right に転送する場合、veth2-right は実際には出力の役割を果たします。 veth2-right から veth2-left にトラフィックを転送するプロセスは、veth1-left から veth1-right にデータを送信するプロセスとまったく同じです。 概要: veth などの仮想ネットワーク カードをブリッジに挿入すると、次のようになります。 図 8 では、veth1-left が Egress の役割を果たします。ネットワーク名前空間の TCP/IP プロトコル スタックからデータを受信し、そのデータを CPU ごとの input_pkt_queue キューに配信し、ソフトウェア割り込みをトリガーします。 veth1-right は Ingress の役割を果たします。物理ネットワーク カードのような循環キューはありません。代わりに、ksoftirqd/x は、veth1-left によってプラグインされたデータを CPU ごとの input_pkt_queue キューから直接読み取ります。 ksoftirqd/x がリンク層にトラフィックを送信すると、br_forward() から始まる転送プロセスに入ります。このプロセスの効果は、トラフィックが veth1-right から veth2-right に転送され、送信されることです。 当然、この時点では veth2-right が Egress の役割を果たし、 veth2-left が Ingress の役割を果たします。 4. ベスペアプラスめまいがない場合は、気分をリフレッシュして、veth-pair の上級バージョンを始めましょう。 前のセクションでは、veth と bridge を一緒に使用するシナリオを見てきました。 veth のもう一方の端をブリッジに接続する必要がありますか?図 9 からわかるように、答えは「必ずしもそうではない」です。 図9 図 9 では、container-1 から送信されたトラフィックが veth を介して送信された後、veth-p が Ingress ロールとしてそれを受信し始めることがわかります。上記の説明によれば、ネットワーク カードがイングレスを実行すると、トラフィックは ksoftirqd/x によってプロトコル スタックに送信され、さらに処理されます。もちろん、この処理プロセスには、図 9 のルーティング プロセスも含まれます。 図 9 ここで巧妙なのは、トラフィックはコンテナ内で生成されるものの、このトラフィックのルーティングはホスト ルート (デフォルト) ネットワーク ネームスペースで行われ、ホストのルーティング テーブルも使用されることです。ルーティングの結果、トラフィックを他のホストに送信する必要があることが判明した場合、トラフィックは当然、ホストの eth0 ネットワーク カード デバイスから送信されます。このプロセスでは、ホストは実際にゲートウェイの役割を果たします。 そうは言っても、図 10 の動作プロセスを理解できますか?これは K8s ホストゲートウェイ ネットワーク モデルです。名前が示すように、このネットワーク モデルではホストをゲートウェイとして使用します。より具体的には、ホストのルート ネットワーク名前空間がルーティングの役割を果たします。 図10 5. tc eBPFtc と eBPF についてあまり知らない場合、または興味がない場合は、この部分をスキップできます。 Cilium に代表される K8s CNI プロバイダーは、サービス メッシュ データ プレーンのパフォーマンスを最適化するために、iptables の代わりに eBPF を使用しようとしてきました。 bpf_redicrect() 関数は最適化出力の 1 つです。 bpf_redicrect() 関数の特性は、1 文で説明できます。veth イングレスを使用すると、トラフィックは bpf_redirect() を介して別の veth イングレスに直接リダイレクトされます。図11に示すように。 ただし、veth ペアのどちら側がいつ Ingress の役割を果たすのか明確にわかっていないと、上記の文は混乱を招きます。 図11 しかし、この記事を読んだ後は、もうめまいを感じなくなることを願っています。図 11 では、右下の Pod からのトラフィックがホスト ネットワーク ns エンドの veth に流れます。この veth は Ingress ロールとして機能します。 これに eBPF の蜂のアイコンが添付されており、eBPF プログラムが実行に介入することを示しています。実行の結果、トラフィックは dev_forward_skb() を介して、ホスト ネットワーク ns エンドにある別の veth (図 11 の矢印で示されている veth) に直接転送されます。もちろん、この veth の場合、出口の役割を果たします。 このプロセスは、以下の関数呼び出し階層図でも表すことができます。 pkt -> NIC -> TCイングレス-> handle_ing () 以下はNetEase Qingzhouの記事に添付された写真です。これは、ノード間の Pod 間の通信、同じノード上の Pod 間の通信、外部ネットワークへの Pod アクセスなど、さまざまな一般的なシナリオを含む、Cilium ネットワーク ソリューションに基づく NetEase Qingzhou の調査と実践の詳細を概説します。 図中の cilium_net/cilium_host は veth ペアであり、カーネル 4.19 + Cilium 1.8 のデプロイメントでは効果がありません (実際、コミュニティではこれらを削除することを検討しています)。 以上の準備と知識があれば、少なくとも数字①②で示したプロセスは理解できると思います。 図12 6. まとめ記事の最後で、私の次兄が短い要約をします。
|
<<: クラウドネイティブの不変インフラストラクチャ - CoreOS
>>: プラットフォーム エンジニアリングが流行しており、開発エクスペリエンスの向上を求める声が高まっています。
Kata/リモート ハイパーバイザー (ピア ポッドとも呼ばれる) シナリオを開発しているときに、ワ...
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeiboマーケティング...
NetEase Huoke は、NetEase Smart Enterprise (以下、NetEa...
月収10万元の起業の夢を実現するミニプログラム起業支援プランインターネット時代の急速な発展に伴い、ネ...
ルーマニアのホスティングプロバイダー HostSolutions は、ハロウィーンの前に大規模なプロ...
質疑応答コミュニティとして、 Zhihu はかつてその高品質なコンテンツで知られていました。しかし、...
多くのウェブマスターが私と同じだと思います。彼らのウェブサイトには多かれ少なかれトラフィックがありま...
ウェブサイトの制作に携わっている方や SEO に携わっている方なら、外部リンクの重要性をご存知でしょ...
消費者が膨大な商品の中から商品を選ぶのを支援することが、ショッピングガイドウェブサイトの急速な発展の...
ハイブリッド クラウド アーキテクチャを構築および作成すると、クラウド コンピューティング サービス...
9月24日、第5回HUAWEI CONNECTで、HUAWEI CloudはAI開発プラットフォーム...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています諺にもある...
2018 年 5 月 8 日 - デジタル変革、クラウド コンピューティング、新しい働き方の出現によ...
米国コンテンツマーケティング協会が発表した「2019年北米B2Bコンテンツマーケティング業界のベンチ...
アリババの戦略は、常に一種の経営の知恵として評価されてきました。独自のプラットフォームの構築、ソーシ...