Kubernetes でのパケットのトレース

Kubernetes でのパケットのトレース

ネットワークとオペレーティング システム カーネルは、私にとっては馴染みのないものですが、魅力的でもあります。私はそれらの背後にある真実を明らかにしたいと思っています。

前回の投稿では、Kubernetes ネットワーク モデルについて詳しく説明しました。今回はもう少し深く掘り下げて、Kubernetes でパケットがどのように送信されるかを理解し、Kubernetes の eBPF ネットワーク アクセラレーションを学習する準備をし、ネットワークとオペレーティング システム カーネルについての理解を深めたいと思います。記事に漏れがあるかも知れませんので、アドバイスを頂ければ幸いです。

始める前に、私の学習成果を一文でまとめます。データ パケットのフローは、実際にはネットワーク ソケット記述子 (ソケット ファイル記述子、中国語は少し長いので、以下ではソケット fd と呼びます) のアドレス指定プロセスです。これは単にソケット fd のメモリ アドレスを参照するだけでなく、そのネットワーク アドレスも含まれます。

Unix および Unix ライクなシステムでは、すべてがファイルであり、ソケットもファイル記述子を通じて操作できます。

基礎

データパック

データ パケットの流れについて説明するので、まずはデータ パケットとは何かを見てみましょう。

ネットワーク パケットは、ネットワーク データグラムまたはネットワーク フレームとも呼ばれ、コンピュータ ネットワークを介して送信されるデータの単位です。最も一般的な TCP データ パケットを例にとると、次の部分が含まれます。

  • イーサネット ヘッダー: リンク層情報。主に宛先 MAC アドレスと送信元 MAC アドレス、およびメッセージの形式を含み、IP パケットとなります。
  • IP ヘッダー: ネットワーク層の情報。主に長さ、送信元 IP アドレス、宛先 IP アドレス、メッセージ形式が含まれます。もちろん、これは TCP パケットである必要があります。
  • TCP ヘッダー: 送信元ポートと宛先ポートを含むトランスポート層情報。
  • データ: 通常は HTTP などのレイヤー 7 データ。

ここでは紹介されていないチェックサムと FCS は、通常、データ パケットが改ざんされていないか、または送信中にエラーが発生していないかをチェックするために使用されます。

アプリケーションがソケットを使用してデータをネットワークに送信するプロセスは、TCP パケット、IP パケット、イーサネット パケットなどのヘッダー情報を使用してデータをカプセル化するプロセスとして簡単に理解できます。逆に、ネットワークからイーサネット パケットを受信して​​、アプリケーションが処理できるデータに変換するのが、アンパックのプロセスです。パケットのカプセル化とカプセル化解除のプロセスは、カーネル ネットワーク プロトコル スタックによって完了します。

以下では、ソケットとカーネル ネットワーク プロトコル スタックの処理についてそれぞれ説明します。

ソケット

ソケットは、コンピュータ ネットワークで使用されるプログラミング インターフェイスであり、ユーザー スペース (ユーザー アプリケーションが実行されるスペース) とカーネル ネットワーク プロトコル スタック (データをカプセル化して解凍するカーネル内のコンポーネント) の間にあります。

プログラミング インターフェイスとして、ソケットは次の操作を提供します (一部のみをリストします)。

  • ソケット
  • 接続する
  • バインド
  • 聞く
  • 受け入れる
  • データ転送
  • 送信
  • 送信先
  • メッセージを送る
  • 受信
  • 受信元
  • 受信メッセージ
  • 取得する
  • ピア名を取得する
  • getsockopt​、setsockopt ソケット層またはプロトコル層のオプションを取得または設定します
  • 近い

次の図から、各操作の役割を直感的に感じることができます。

カーネルネットワークプロトコルスタックの説明を始める前に、まずメモリ内のデータパケットのデータ構造であるsk_buff[1]について説明します。

sk_バフ

sk_buff は、Linux カーネルでネットワーク パケットを管理するために使用されるデータ構造です。パケットのプロトコル、データ長、送信元アドレスと宛先アドレスなど、受信および送信されたネットワーク パケットのさまざまな情報とプロパティが含まれます。sk_buff は、ネットワーク層とデータ リンク層の間で渡すことができるデータ構造であり、TCP/IP、UDP、ICMP など、すべてのタイプのネットワーク プロトコル スタックで使用できます。

sk_buff は、データリンク層、ネットワーク層、トランスポート層など、ネットワーク プロトコル スタックのさまざまな層の Linux カーネルで広く使用されています。 sk_buff データ構造には、4 つの重要なフィールドを含む多くのフィールドがあり、それらはすべてポインター型です。さまざまなレイヤーでの sk_buff の使用は、これらのポインターを変更して、ヘッダーを追加 (パッケージ化) したり、ヘッダーを削除 (アンパック) したりすることによって実現されます。

このプロセスはポインターに対して動作し、データはゼロコピーされるため、効率が大幅に向上します。

カーネルネットワークプロトコルスタック

パケット

アプリケーションは、ソケットの sendmsg 操作を使用してデータを送信します (netfilter、トラフィック制御、およびキュー規律についてはここでは詳しく説明しません)。

  1. 最初にsk_buffを割り当てる
  2. 次に、ネットワーク プロトコル スタックの処理を開始します。
  3. トランスポート層情報(ここではTCPヘッダーの送信元ポートと宛先ポート)を設定します。
  4. ターゲットIPに基づいてルートを見つける
  5. ネットワーク層情報(送信元および宛先 IP アドレスなど)を設定する
  6. netfilter の呼び出し (LOCAL_OUT)
  7. インターフェースとプロトコルを設定する
  8. netfilter の呼び出し (POST_ROUTING)
  9. パケットが長すぎる場合はセグメントで送信されます
  10. L2アドレス指定は、ターゲットIPアドレスを持つことができるデバイスのMACアドレスを見つけることです。
  11. リンク層情報を設定する、
  12. この時点でカーネルネットワークプロトコルスタックの動作は完了する。
  13. tc(トラフィック制御)出口を呼び出す(パケットをリダイレクトできる)
  14. キュー規律 (qdisc) を入力します
  15. NIC(ネットワークインターフェースコントローラ)への書き込み
  16. ネットワークに送信

開梱

NIC はネットワークからデータ パケットを受信します (ダイレクト メモリ アクセス、ネットフィルタ、トラフィック制御についてはここでは詳しく説明しません)。

  1. データパケットをDMA(ダイレクトメモリアクセス、CPUに依存せず、NICによってメモリに直接書き込まれる)に書き込みます。
  2. sk_buff を割り当て、プロトコル タイプ イーサネット、データ パケットを受信するネットワーク インターフェイスなどのメタデータを入力します。
  3. リンク層情報をsk_buffのmac_headerフィールドに保存し、パケット内のリンク層情報を「削除」します(ポインタを移動します)
  4. 次に、ネットワーク プロトコル スタックの処理を開始します。
  5. ネットワーク層情報をnetwork_headerフィールドに保存する
  6. コールtc入力
  7. ネットワーク層情報を「削除」する
  8. トランスポート層情報をtransport_headerフィールドに格納する
  9. netfilter の呼び出し (PRE_ROUTING)
  10. ルートの検索
  11. 複数のサブパッケージをマージする
  12. netfilter の呼び出し (LOCAL_IN)
  13. トランスポート層情報の「削除」
  14. ターゲットポートで待機しているソケットを見つけるか、リセットを送信する
  15. ソケットの受信キューにデータを書き込む
  16. データがキューに書き込まれたことを通知する
  17. この時点でカーネルネットワークプロトコルスタックの動作は完了する。
  18. sk_buffはソケット受信キューから取り出される
  19. アプリケーションのバッファにデータを書き込む
  20. sk_buffをリリース

Kubernetes ネットワーク モデル

基本的な知識のもう 1 つの部分は、Kubernetes ネットワーク モデルです。前の記事「Kubernetes ネットワーク モデルとネットワーク通信の詳細な調査」を参照してください。

Kubernetes におけるパケットフロー

ここでは、前回の記事で説明した 3 つの通信シナリオについて引き続き説明します。ポッド間の通信にはポッドの IP アドレスが使用されます。サービス経由のアクセスについて議論する場合、netfilter が含まれると議論の長さが大幅に長くなります。

同じポッド内のコンテナ間の通信

ポッド内の 2 つのコンテナ間の方法では、通常、ループバック アドレス 127.0.0.1​ が使用されます。パケットルーティングプロセス#4では、ループバックネットワークカードloを使用して送信することが決定されます。

同じノード上のポッド間の通信

curl によって送信された要求は、パケット #4 で eth0 インターフェイスを使用しているものとして識別されます。次に、eth0​に接続されたトンネル veth1 を介してノードのルート ネットワーク空間に到達します。

veth1​ は、ブリッジ cni0​ と仮想イーサネット インターフェイス vethX​ を介して他のポッドに接続されます。パケット #10 L2 アドレス指定では、ARP 要求がブリッジを介してすべての接続されたインターフェイスに送信され、元の要求の宛先 IP アドレス (ここでは 10.42.1.9) があるかどうかが確認されます。

veth0​のMACアドレスを取得した後、パケット#11のデータパケットのリンク層情報を設定します。データ パケットが送信されると、veth0​ トンネルを介してポッド httpbin の eth0 インターフェイスに入り、解凍プロセスが開始されます。

解凍プロセスは特別なものではなく、httpbin によって使用されるソケットが決定されます。

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

ここでの状況は少し異なります。 cni0​ を介して ARP 要求を送信した後、応答が受信されない場合は、ホストのルーティング テーブルであるルート名前空間を使用して、ターゲット ホストの IP アドレスが決定されます。次に、ARP 要求がホストの eth0 を介して送信され、ターゲット ホストから応答が受信されます。パケット#11にMACアドレスを書き込みます。

データ パケットがターゲット ホストに送信された後、解凍プロセスが開始され、最終的にターゲット ポッドに入ります。

クラスター レベルでは、各ノードの Pod IP ネットワーク セグメントを格納するルーティング テーブルがあります (Pod ネットワーク セグメント (Pod CIDR) は、ノードがクラスターに参加するときに割り当てられます。たとえば、k3s のデフォルトの Pod CIDR は 10.42.0.0/16​ で、ノードによって取得されるネットワーク セグメントは 10.42.0.0/24、10.42.1.0/24、10.42.2.0/24 などです)。 IP アドレスを要求しているノードは、ノードの Pod IP セグメントによって判別され、そのノードに要求が送信されます。

要約する

統計によると、3 つのシナリオすべてにおいて、カーネル ネットワーク プロトコル スタックは、同じポッドまたはノード内であっても、パケットを 2 回処理します (netfilter プロセスを含む)。これら両方の状況は実際には同じカーネル空間で発生します。

同じカーネル空間内の 2 つのソケットがデータを直接送信できる場合、カーネル ネットワーク プロトコル スタックの処理によって発生する遅延を回避できますか?

次の記事に続きます。

参考文献

[1] sk_buff: https://elixir.bootlin.com/linux/latest/source/include/linux/skbuff.h#L843

<<:  エッジコンピューティングは長い間私たちの身近に存在してきました

>>:  【クラウドネイティブ】Grafana入門と実践運用

推薦する

speedypage: 米国の高性能 VPS、4.83 ドルから、AMD Ryzen 7950X+DDR5+Gen4 NVMe

Speedypage は、米国東海岸の Ashburn データセンターの VPS で、AMD Ryz...

どのようなコンテンツが人々を驚かせるのでしょうか?

コンテンツのないマーケティングは空砲を発射するようなものです。大きな音はしますが、栄養価はなく、内臓...

デルテクノロジーズのグローバルCTOが2021年のテクノロジートレンドを解説

2021年初頭、主要機関は今後の技術発展の動向分析と展望を発表しました。クラウドネイティブ、ビッグデ...

メガレイヤー:米国CN2専用サーバー99元/月、香港CN2専用サーバー399元/月

4月12日から5月31日まで、Megalayerは、中国香港と米国サンノゼの2つのデータセンターの独...

エッジでのコンピュータビジョンの 7 つの主要アプリケーション

エッジ コンピューティングは、コンピューター ビジョンをインテリジェント システム、スマート デバイ...

Discuz!社長チェン・リャン:マイクロコミュニティをうまく運営する鍵は、適切なポジショニングを見つけることです

成都ビジネスデイリーのマイクロコミュニティ「紅星制作チーム」は、立ち上げ以来、数万回の訪問と多くのア...

pumpcloud: 香港 HGC データセンター VPS の簡単なレビュー

pumpcloud は設立されてから数年が経ち、主に香港のダイナミック IP VPS、香港の固定 I...

見逃せない人気の継続的インテグレーションツール 8 選

「継続的インテグレーション」に精通している方であれば、「継続的インテグレーションの使用は必須となって...

外部リンクによってサポートされているウェブサイトのランキングが大幅に低下していることが観察されています。

百度が23日に正式に発表した「ハイパーリンク不正アルゴリズムアップグレード」が発効したとみられる。百...

優れたUXデザイナーがすべき5つのこと

[編集者注] この記事は、ブログ「Usability Counts」から @C7210 によって翻訳...

Kサイトにつながる可能性のある4つの不安定要因について簡単に説明します。

著者は2008年末にウェブマスター業界で働き始め、あっという間にウェブマスターとして4年目を迎えまし...

BandwagonHostの返金に関する問題の説明とBandwagonHostの返金のスムーズな解決

BandwagonHost VPS は、低価格、高速、使いやすさで常に知られています。ただし、Ban...

Didi の成長の秘密: 最も効果的なチャネルと成長方法を見つけるには?

この記事の著者は、 Didiと Uxin で勤務し、多数の成長事業を担当してきました。製品の成長ロジ...

SpringbootはKafka Streamのリアルタイム統計を統合します

[[417927]]環境: springboot2.3.12.RELEASE + kafka_2.1...

hosteons: 20% 割引/メモリ 2 倍 + ハードディスク 2 倍 + トラフィック 2 倍 (200M 無制限)

Hosteons のお買い得な VPS が話題になっています。これから、Hosteons のロサンゼ...