ネットワーク全体で最も詳細な - Istio Ambient Mesh トラフィック パスの詳細な分析

著者: 石則環

序文

Istio Ambient Mesh は、Istio コミュニティによって立ち上げられた新しいアーキテクチャで、サイドカー機能を ztunnel とウェイポイントに抽出します。また、iptables とポリシー ルーティングに基づいて、このアーキテクチャの下でトラフィック ルールを実装します。現在、ネットワーク上に、実装について議論する資料がいくつかあります。ある程度の分析はありますが (Solo.io によって開始された 3 つのシリーズ記事など)、どの記事でも言及されていない詳細がまだ多くあります。この記事は、Istio Ambient Mesh のトラフィック パスの詳細な説明を提供することを目的としており、読者が Istio Ambient Mesh の最も重要な部分を完全に理解できるように詳細をできるだけ明確に示すよう努めています。この記事を読むには、基本的な TCP/IP プロトコルの知識と、iptables やルーティングなどのオペレーティング システムのネットワーク知識が必要です。紙面の都合上、この記事ではこれらの基本概念については詳しく紹介しませんが、興味のある方は、関連情報を参照してより深く理解することをお勧めします。

環境

最も単純化したシナリオを使用して、アンビエント メッシュ トラフィック パスを示します。HTTP リクエストは、Node-A で実行されているスリープ ポッドから、curl を介して開始され、リクエストのオブジェクトは、クラスタ内の httpbin という名前のサービスです。このサービスの下には、ノード B に httpbin ポッドがあります。サービス (ClusterIP) は K8s の単なる仮想 IP であるため (実際のネットワーク デバイスのアドレスではありません)、このシナリオでは、リクエストは直接送信されます。 httpbin アプリケーション ポッドへの場合、このシナリオのネットワーク パスは次のようになります。

ただし、アンビエント メッシュ トラフィック ルールの影響により、スリープ ポッドから送信されるデータ パケットは、実際には、反対側の httpbin アプリケーションに到達する前に、一連の iptables およびポリシー ルーティングを通過し、ztunnel またはウェイポイントに転送される必要があります。次のページでの説明を容易にするために、最初にこのプロセスの参加者全員を紹介する必要があります。読者はこれらのデバイスのアドレスと名前を覚える必要はありません。ここでは、参照の便宜のためにリストされています:

完全なトラフィックパス

sleep -> httpbin のリクエスト パスは非常に単純に見えますが、アンビエント メッシュでは、ztunnel がすべての受信接続と送信接続を引き継ぎ、スリープ ポッドから送信された IP パケットは ztunnel の 15001 ポートにハイジャックされ、ztunnel によって暗号化されて送信されます。したがって、実際には、スリープ ポッドで実行されるカールによって開始された接続は、実際には ztunnel ポッドのプロトコル スタックに接続されます。同様に、httpbin ポッドによって受信される接続は、実際には、それが配置されているノード上で実行されている ztunnel からのものです。実際の接続が確立されました。 TCP 接続は 3 つあります。

  • スリープ -> NodeA ztunnel
  • ノードA zトンネル -> ノードB zトンネル
  • NodeB ztunnel -> httpbin

アンビエント メッシュは 4 層の透明な設計であるため、ztunnel またはウェイポイント プロキシによって転送されますが、スリープ ポッドの Curl アプリケーションも httpbin ポッドの httpbin アプリケーションも中間プロキシの存在を認識できません。この目標を達成するために、DNAT および SNAT アクションはデータ パケットの送信元/宛先情報を変更するため、多くの点でデータ パケットを DNAT および SNAT 経由で直接転送することはできません。アンビエント メッシュによって設計されたこれらのルールは、主に透明性を確保するように設計されています。伝送路の各部分を 1 つずつ説明するには、上の図をさらに改良する必要があります。

この図を解釈してみましょう。著者はパス全体を 3 つの部分に分割しています。最初の部分は、赤い線で表される、curl から ztunnelA への部分です。2 番目の部分は、青の線で表される、ztunnelA から ztunnelB への部分です。3 番目の部分は、ztunnelB から ztunnelB への部分です。 httpbin。黄色の線で表されます。また、線には 2 種類あり、両端に矢印のない線は、これらの機器が直接接続されていること、つまりデータパケットが一方から入ったらもう一方から出てくることを示しています。 Pod とホスト間の接続方法とは異なりますが、これはこの記事の焦点では​​ありません。直接接続と考えることもできます。この記事の焦点は、矢印の付いた接続を作成し、上記で分離されたパスの 3 つの部分を 1 つずつ分析し、パスのこの部分でデータ パケットがどのように転送されるかを明らかにします。

パート 1: ztunnel-A へのカール

curl を実行してリクエストを送信すると、curl は httpbin サービスへの接続を開始します。DNS 解決後、接続ターゲットは httpbin サービスの ClusterIP (Pod ではありません) です。K8s クラスタでは、データ パケットは Cluster IP に送信されます。一連の iptables ルールは、ターゲット アドレスを PodIP に変換し、ホスト経由で送信します。ただし、アンビエント メッシュでは、送信する前に ztunnel によって暗号化する必要があります。このセクションでは、最初に、データ パケットが ztunnel プロセスの ztunnel ポッドにどのようにルーティングされるかを見てください。

1)スリープ NS -> ノード A NS

スリープ ポッドにはネットワーク デバイス eth0 が 1 つだけあるため、これはポッド ネットワーク名前空間内のポッドの veth ペアの一端であり、反対側はホスト ネットワーク名前空間内の vethbda3de4b デバイスです。ポッドはすべての外部ネットワークと通信します。上りでも下りでも、すべての回線はこのチャネルを通じて送受信されます。Sidecar モードでは、トラフィックを Sidecar にリダイレクトするために、ポッド ネットワーク名前空間に一連の iptables ルールがありますが、アンビエント モードでは、Sidecar がポッドに注入されなくなるため、ポッド ネットワークの名前空間なので、この段階のトラフィック パスは一般的な K8s ポッドのトラフィック パスと同じです。ポッド ネットワーク プロトコル スタックから送信されたデータ パケットは、ポッドの唯一のネットワーク デバイス eth0 を介して送信され、そこからホストのネットワーク名前空間に到達します。ホスト側の veth デバイス。

2)ノードA NS -> ztunnelA NS

最初のアップリンク データ パケット

データ パケットがホストに到着したら、ztunnel にリダイレクトする必要があります。ただし、このパス上の最初のデータ パケット (TCP ハンドシェイク パケット) は、後続のデータ パケットとは異なるパスを介して ztunnel に転送されます。最初のデータ パケット パッケージが始まります。スリープ ポッドのカールによって開始される接続オブジェクトは httpbin サービスであるため、DNS 解決後の実際の接続ターゲットは httpbin サービスの ClusterIP です。 sleep pod のプロトコル スタックは次のようになります。

K8s は、サービス アドレス DNAT を特定のエンドポイント アドレスに設定するために、サービス ルーティングの iptables ルールを構成します。このロジックをスキップしてデータ パケットを ztunnel にリダイレクトするために、アンビエント メッシュ CNI は、K8s ルールの前にホストの iptables ルールをいくつか追加します。 。データ パケットがスリープ ポッドの veth からホストに到着すると、PREROUTING チェーンの実行が開始されます。PREROUTING チェーンの内容を見てみましょう。

=== PREROUTING ===
    --- raw ---
    --- mangle ---
        -A PREROUTING -j ztunnel-PREROUTING
    --- nat ---
        -A PREROUTING -j ztunnel-PREROUTING
        -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
        -A PREROUTING -d 172.18.0.1/32 -j DOCKER_OUTPUT

Istio Ambient Mesh は、処理のために ztunnel-PREROUTING チェーンへのジャンプを強制するルールを mangle テーブルと nat テーブルに追加していることがわかります。無条件で ztunnel-PREROUTING チェーンにジャンプするため、非アンビエント メッシュ ポッドも処理されます。このチェーンにジャンプして処理されます。グリッド外のポッドのトラフィックが誤って ztunnel にリダイレクトされるのを避けるため、ポッドの起動時にアンビエント メッシュの CNI が判断します。結果はアンビエントが有効になり、ポッドの IP がホスト ネットワーク名前空間の ztunnel-pods-ips という名前の ipset に追加されます。この記事のシナリオでは、スリープ ポッドはノード A の ztunnel-pods-ips という名前の IP セットに追加されるため、スリープ ポッドからのパケットは ztunnel-PREROUTING チェーン内の次のルールにヒットします。(ルールは省略されています)現在のステージに関連するルールは無関係なコンテンツ):

=== ztunnel-PREROUTING ===
    --- raw ---
    --- mangle ---
        ......
        -A ztunnel-PREROUTING -p tcp -m set --match-set ztunnel-pods-ips src -j MARK --set-xmark 0x100/0x100
    --- nat ---
        -A ztunnel-PREROUTING -m mark --mark 0x100/0x100 -j ACCEPT
    --- filter ---

マングル テーブルの実行段階では、データ パケットの送信元アドレス (スリープ ポッド アドレス) が ztunnel-pods-ips 内にあるため、このルールは正常に一致し、データ パケットは 0x100 でマークされます。0x100 でマークされたデータ パケットは、その後、nat テーブル ステージが直接受け入れられ、データ パケットが K8s iptables ルールの処理をスキップできるようになります。これまでのところ、ルールはデータ パケットにマークを付けるだけであり、データ パケットの宛先アドレスは変更されていません。データ パケットのルーティングを変更するには、ルーティング テーブルを使用する必要があります。PREROUTING が終了すると、データ パケットはルーティング ステージに入りますが、データ パケットには 0x100 がマークされているため、ポリシー ルーティング ステージでは次のルールがヒットします (無関係なルールは省略しています)。

......
101:    from all fwmark 0x100/0x100 lookup 101
......

このポリシー ルーティング ルールに一致すると、このパケットにはルーティング テーブル 101 が使用されます。ルーティング テーブル 101 の内容を見てみましょう。

default via 192.168.127.2 dev istioout 
10.244.2.3 dev veth51e3b96d scope link

データ パケットの宛先アドレスは httpbin サービスのクラスター IP であるため、この記事で使用するデモ環境では、httpbin サービスのクラスター IP は 10.96.0.105 であるため、このルーティング テーブルのデフォルト ルールがヒットします。このルールの意味は次のとおりです。 through istioout デバイスはゲートウェイ 192.168.127.2 に送信します。istioout デバイスはブリッジ デバイスであり、もう一方の端は ztunnel ポッドの pistioout デバイスであり、そのアドレスは 192.168.127.2 です。データ パケットはこのルーティング ルールを適用した後、istioout デバイスを経由してホストから出ていきます。 pistioout ネットワーク名前空間から ztunnel ポッドに到達します。

データ パケットが pistioout を通じて ztunnel Pod ネットワーク名前空間に到達すると、データ パケットの宛先アドレスが ztunnel Pod 内のネットワーク デバイスではないため、データ パケットは介入なしに ztunnel Pod のプロトコル スタックによって破棄されます。ztunnel プロセスのアウトバウンド エージェントはポート 15001 でリッスンします。データ パケットをこのポートに正しく配信するために、いくつかの iptables ルールとルーティング ルールも ztunnel Pod に設定されます。データ パケットが ztunnel Pod ネットワーク名前空間に到達した後、それは次のルールに当てはまります。

=== PREROUTING ===
    --- raw ---
    --- mangle ---
        ......
        -A PREROUTING -i pistioout -p tcp -j TPROXY --on-port 15001 --on-ip 127.0.0.1 --tproxy-mark 0x400/0xfff
        ......
    --- nat ---
    --- filter ---

このルールは、pistioout デバイスから入ってくるデータ パケットの宛先アドレスを 127.0.0.1 の 15001 ポートにリダイレクトし、データ パケットに 0x400 のラベルを付けます。宛先アドレスはここでリダイレクトされますが、tproxy はそれを保持することに注意してください。データ パケットの元の宛先アドレス。アプリケーションは、getsockopt の SO_ORIGINAL_DST オプションを通じてデータ パケットの元の宛先アドレスを取得できます。iptables ルールが実行されると、ポリシー ルーティングが実行され、データ パケットは次のポリシー ルーティング ルールにヒットします。

20000:  from all fwmark 0x400/0xfff lookup 100

このポリシー ルーティングは、ルーティングに 100 ルーティング テーブルの使用を指定します。100 ルーティング テーブルの内容を見てみましょう。

local default dev lo scope host

100 ルーティング テーブルには、lo デバイスを介してローカル プロトコル スタックに送信されるルールが 1 つだけあります。この時点で、データ パケットは ztunnel ポッドのローカル プロトコル スタックに入ります。データ パケットは 127.0.0.1:15001 にリダイレクトされるため、 iptables、データ パケットが最終的に到着します。ztunnel プロセスによって監視されている 15001 ポート、curl から ztunnel プロセスの最初のパケットまでのパスが整理されました。

ダウンリンクデータパケット

この段階での戻りパケットの処理には、いくつかの特別なルールもあります。戻りパケットがホスト上の ztunnel の veth を介してホストに入るとき、次のルールに該当します。

-A ztunnel-PREROUTING ! -s 10.244.2.3/32 -i veth51e3b96d -j MARK --set-xmark 0x210/0x210
-A ztunnel-PREROUTING -m mark --mark 0x200/0x200 -j RETURN

このルールの意味は、データ パケットが ztunnel Pod IP からではなく、ztunnel Pod の veth からホストに入る場合、0x210 のマークが付けられるということです。

なぜこの状態なのでしょうか?ztunnel は実際には透過プロキシであるため、つまり、ztunnel はデータ パケットに応答する反対側のターゲット サービスとして機能するため、データ パケット内の送信元アドレスは、反対側のサービスのアドレスではなく、反対側のサービスのアドレスになります。 ztunnel ポッドのアドレス。

その後、データ パケットは 0x210 でマークされるため、ルーティング フェーズ中にホスト上の次のポリシー ルーティング ルールにヒットします。

100:    from all fwmark 0x200/0x200 goto 32766
......
32766:  from all lookup main

このルーティング ルールは、メイン ルーティング テーブルを介したルーティングを示します。返信パケットのアドレスは、スリープ ポッド アドレス (10.244.2.8) です。これは、K8s ネットワークによってメイン ルーティング テーブルに追加されたルールにヒットします。

10.244.2.8 dev vethbda3de4b scope host

このルールは、データ パケットを vethbda3de4b デバイスにルーティングします。vethbda3de4b は、ホスト側のスリープ ポッドの veth デバイスです。このデバイスに入るデータ パケットは、スリープ ポッドの eth0 デバイスを介してスリープ ポッドに入ります。

まだ終わっていない. 経路が決定された後, パケットの宛先アドレスがローカルマシンではないため, iptables FORWARD チェーンが再度実行されます. FOWARD チェーンのマングルテーブルには以下のルールがあります:

-A FORWARD -j ztunnel-FORWARD

また、無条件に ztunnel-FORWARD チェーンにジャンプします。ztunnel-FORWARD チェーンでは、データ パケットが 0x210 識別子を運ぶため、次のルールが適用されます。

-A ztunnel-FORWARD -m mark --mark 0x210/0x210 -j CONNMARK --save-mark --nfmask 0x210 --ctmask 0x210

このルールは、データ パケットのタグを接続に保存します。これまでのところ、この接続は 0x210 タグも保存しています。この接続に属するデータ パケットがホストを通過するとき、接続タグ 0x210 は、ホスト上の後続のパケットと一致するために使用されます。この接続、すべてのパケット。

後続のアップリンク データ パケット

最初の応答パケットは接続に 0x210 をマークするため、スリープ ポッドからホストに入る後続のアップストリーム パケットは、PREROUTING フェーズで次のルールにヒットします。

-A ztunnel-PREROUTING ! -i veth51e3b96d -m connmark --mark 0x210/0x210 -j MARK --set-xmark 0x40/0x40

ご覧のとおり、接続マークは iptables の connmark モジュールによって照合され、パケットは 0x40 でマークされます。0x40 でマークされたパケットは、後続のルーティング ステージで次のルールにヒットします。

102:    from all fwmark 0x40/0x40 lookup 102

次に、ルーティングに 102 ルーティング テーブルを使用します。

default via 10.244.2.3 dev veth51e3b96d onlink
10.244.2.3 dev veth51e3b96d scope link

このルーティング テーブルは、ztunnel ポッドにルーティングするためにアンビエント メッシュによって作成されたルールです。データ パケットの宛先アドレスは httpbin サービスの ClusterIP であるため、この段階では 102 ルーティング テーブルのデフォルトのルーティング ルールにヒットし、それを 102 に送信します。 veth51e3b96d デバイスを介した ztunnel ポッド。データ パケットが veth51e3b96d デバイスに入ると、ztunnel Pod の eth0 デバイスから ztunnel Pod ネットワーク名前空間に入り、次の iptables ルールにヒットします。

-A PREROUTING ! -d 10.244.2.3/32 -i eth0 -p tcp -j MARK --set-xmark 0x4d3/0xfff

このルールの条件は、データ パケットの宛先アドレスが ztunnel Pod アドレスではなく、eth0 デバイスから入り、プロトコルが TCP である場合、データ パケットには 0x4d3 マークが付けられることです。の場合、データ パケットはルーティング フェーズで次のルールに一致します。

20003:  from all fwmark 0x4d3/0xfff lookup 100

このポリシー ルートに到達すると、100 ルーティング テーブルが使用されます。

local default dev lo scope host

このルーティング テーブルはパケットを lo デバイスにルーティングし、パケットをネイティブ プロトコル スタックに強制的に送り込みます。

要約する

簡単に要約しましょう。ノード A から ztunnel までのこの段階では、最初のデータ パケットは istioout インターフェイスを介してホストから出て、pistioout インターフェイスは ztunnel ポッドに入ります。ただし、接続がマークされているため、後続のデータ パケットは 0x210 としてマークされます。 ztunnel Pod の veth デバイスを介してホストを離れ、ztunnel Pod の eth0 デバイスを介して ztunnel Pod に入ります。

パート 2: ztunnel-A から ztunnel-B へ

データパケットがztunnelに到着した後、レイヤー4のロードバランシングが実行されます。この部分については、私の記事[ 1]を参照してください。レイヤー 4 のロード バランシングの後、ztunnel はターゲット サービス IP をポッド IP に変換します。ゼロトラスト セキュリティ設計のため、ztunnel はターゲット ポッドではなく、最初にポッド IP が配置されているノードの ztunnel にデータを転送する必要があります。この点におけるアンビエント メッシュの設計では、ztunnel によって送信されるデータ パケットの宛先アドレスがターゲット Pod (つまり、httpbin Pod) のアドレスになるように設計されており、K****8 のルーティング ルールは次のようになります。データ パケットをターゲットに到達させるために使用されます。ポッドが配置されているホストは反対側のホスト上にあり、一連のルールを通じてデータ パケットを ztunnel ポッドにルーティングします。次のセクションで見ていきます。このパスがどのように実装されるかについて説明します。

1)ztunnel-A ネットワーク名前空間 -> Node-A ネットワーク名前空間

レイヤー 4 のロード バランシングの後、ztunnel はピア ポッドのポート 15008 への接続を開始します。ポート 15008 (サービス ポートやバックエンド ポッド ポートではなく) が使用される理由は、ピアの iptables ルールが適用されるときにこのポートが使用されるためです。 ztunnel の一致: 一致条件が作成されます。詳細についてはパート 3 で説明します。ztunnel によって送信されたデータ パケットは、ホスト経由でピアノードに転送されるために、まず ztunnel ポッドからホストに到達する必要があります。ztunnel ポッドには、スリープ ポッドと同様に、ホストに接続された veth ペアのペアもあります。デバイスztunnel Pod ネットワーク名前空間の下の名前が eth0 である場合、デバイスに入るデータ パケットは、ホスト側の veth デバイスからホスト ネットワーク名前空間に入ります。ztunnel によって送信されるデータ パケットの宛先アドレスは、httpbin Pod のアドレスです。 ztunnel ポッドの iptables ルールにはヒットしません。ルーティング段階では、データ パケットはデフォルトのルーティング ルールにヒットし、データ パケットは eth0 経由でホストに送信されます。

2)ノードA -> ノードB

データ パケットが NodeA に到達すると、その宛先アドレスは httpbin ポッドの IP アドレス (10.244.1.17) であるため、メイン ルーティング テーブルの K8s によって追加されたポッド ネットワーク セグメントのルーティング ルールにヒットします。

......
10.244.1.0/24 via 172.18.0.4 dev eth0
......

このルールは、10.244.1.0/24 ネットワーク セグメント宛てのデータ パケットが eth0 デバイスを介してゲートウェイ 172.18.0.4 (ノード B アドレス) に送信されることを示します。ztunnel ポッドによって送信されるデータ パケットは、httpbin ポッド アドレス 10.244 です。 1.7 では、このルールが適用されます。ルールでは、eth0 デバイスを介してノード A を離れ、ノード B に移動し、最後にノード B の eth0 デバイスを介して NodeB ネットワーク名前空間に入ります。

3)Node-B ネットワーク名前空間 -> ztunnel-B ネットワーク名前空間

最初のアップリンク データ パケット

インバウンドフェーズのノードから ztunnel へのパスでは、アウトバウンドフェーズと同様に、最初のデータパケット (TCP ハンドシェイクパケット) は、後続のデータパケットとは異なるパスを介して ztunnel に転送されます。また、最初のパケットの分析から始めます。ノード B のポリシー ルーティング ルールを見てみましょう。このデータ パケットにはタグが含まれていないため、ノード B の ztunnel-pod-ips ipset には含まれません。データ パケットの宛先アドレスは Pod です。IP は K8s ネットワークの iptables ルールにヒットしないため、ポリシー ルーティングの段階を直接見てみましょう。

0:      from all lookup local
100:    from all fwmark 0x200/0x200 goto 32766
101:    from all fwmark 0x100/0x100 lookup 101
102:    from all fwmark 0x40/0x40 lookup 102
103:    from all lookup 100
32766:  from all lookup main
32767:  from all lookup default

ローカル ルーティング テーブルにはすべてのローカル ルーティング ルールが含まれているため、ヒットすることはありません。データ パケットにはタグがないため、100、101、または 102 にはヒットしません。したがって、データ パケットは 103 ルールにヒットし、100 ルーティングが使用されます。テーブル. 次に、このルートを見てみましょう. テーブルの内容:

10.244.1.3 dev vethbcda8cd4 scope link 
10.244.1.5 via 192.168.126.2 dev istioin src 10.244.1.1 
10.244.1.6 via 192.168.126.2 dev istioin src 10.244.1.1
10.244.1.7 via 192.168.126.2 dev istioin src 10.244.1.1

100 ルーティング ルールは、このノードで実行されている各ポッドの IP アドレスのルーティング テーブルに設定されています。各ルールは、ノード上の istioin デバイスを指します。つまり、このルーティング テーブルをルーティングに使用する場合、データ パケット 宛先アドレスがこのマシン上の Pod である場合、そのアドレスは istioin デバイスにルーティングされます。このデータ パケットのターゲット アドレスは、httpbin ポッド アドレス 10.244.1.7 です。これは 4 行目のルーティング ルール、10.244.1.7 via 192.168.126.2 dev istioin src 10.244.1.1 にヒットし、istioin デバイスに入ります。前の説明で istioout デバイスについて言及しましたが、同様に、istioin デバイスは受信トラフィックの処理に使用され、もう一方の端は ztunnel B ポッドの pistioin デバイスです。

データ パケットが pistioin デバイスを介して ztunnel-B に入った後、宛先アドレスが httpbin Pod であるため、ztunnel Pod によって破棄されないように、iptables ルールによってリダイレクトされる必要もあります。データ パケットのデータが 15008 である場合、パッケージは次のルールに一致します。

-A PREROUTING -i pistioin -p tcp -m tcp --dport 15008 -j TPROXY --on-port 15008 --on-ip 127.0.0.1 --tproxy-mark 0x400/0xfff

このルールは、pisioin デバイスからのデータ パケットと一致し、プロトコルは tcp、宛先ポートは 15008 で、TPROXY を通じてパケットを 127.0.0.1 の 15008 ポートにリダイレクトし、データ パケットに 0x400 のマークを付けます。マークが付いている場合、ポリシー ルーティング フェーズ中に次のルールがヒットします。

20000:  from all fwmark 0x400/0xfff lookup 100

このポリシー ルーティング ルールは、100 ルーティング テーブルを使用してパケットをルーティングするように指示します。

local default dev lo scope host

ztunnel-A と同様に、100 ルーティング テーブルにはルーティング ルールが 1 つだけあり、データ パケットを LO デバイスにルーティングし、データ パケットを強制的にローカル プロトコル スタックに入れるというものです。 TPROXY を 15008 に設定すると、データ パケットは最終的に、ztunnel プロセスがポート 15008 でリッスンしているソケットに到達します。この時点で、ztunnel-A からのデータ パケットは ztunnel プロセスに正常に到達します。

ダウンリンクデータパケット

ztunnel ポッド プロトコル スタックがダウンリンク データ パケットを送信すると、データ パケットは eth0 デバイスを介してホストに入り、ホスト上で次の iptables ルールがヒットします。

-A ztunnel-PREROUTING ! -s 10.244.2.3/32 -i veth51e3b96d -j MARK --set-xmark 0x210/0x210

このルールの一致条件は、データ パケットの送信元アドレスが ztunnel Pod IP ではなく、ztunnel Pod veth デバイスからのものである場合、0x210 でマークされることです。アウトバウンド フェーズと同様に、データ パケットは 0x210 でマークされます。メイン ルーティング テーブルを使用してルーティングされます。

100:    from all fwmark 0x200/0x200 goto 32766
......
32766:  from all lookup main

ダウンリンク データ パケットの宛先アドレスはスリープ ポッド アドレス (10.244.2.8) であるため、メイン ルーティング テーブルの K8s ネットワークのルーティング ルールを使用すると、10.244.2.0/24 アドレス セグメントに送信されたデータ パケットは通過します。ホストの eth0 デバイスは、ホスト ネットワーク内のルーターによってピア ポッドが配置されているホストにルーティングされます。

10.244.2.0/24 via 172.18.0.3 dev eth0

ルートを決定したら、ztunnel-FORWARD チェーンで次のルールをヒットします。

-A ztunnel-FORWARD -m mark --mark 0x210/0x210 -j CONNMARK --save-mark --nfmask 0x210 --ctmask 0x210

ノード A のアウトバウンド フェーズと同様に、接続には応答パケットを通じて 0x210 マークが付けられ、接続上のマークにより、後続のデータ パケットが他のルールにヒットします。

後続のアップリンク データ パケット

接続には 0x210 のマークが付けられているため、後続のデータ パケットはノード B に入った後、次の iptables ルールにヒットします。

-A ztunnel-PREROUTING ! -i vethbcda8cd4 -m connmark --mark 0x210/0x210 -j MARK --set-xmark 0x40/0x40
-A ztunnel-PREROUTING -m mark --mark 0x200/0x200 -j RETURN

ノード A と同様に、データ パケットが ztunnel veth から来ておらず、接続タグが 0x210 である場合、データ パケットには 0x40 のマークが付けられます。その目的は、データ パケットが次の 102 ルーティング テーブルを使用してルーティングされるようにすることです。ルーティングステージ:

102:    from all fwmark 0x40/0x40 lookup 102

102 ルーティング テーブルは、ztunnel-B につながるルーティング テーブルです。データ パケットはデフォルトのルーティング ルールにヒットし、vethbcda8cd4 (つまり、ホスト上の ztunnel-B のネットワーク デバイス) にルーティングされ、それによって ztunnel ポッドに入ります。

default via 10.244.1.3 dev vethbcda8cd4 onlink 
10.244.1.3 dev vethbcda8cd4 scope link

ztunnel Pod に入った後のプロセスは、Inbound ステージと同じであるため、ここでは再度説明しません。

要約する

ノード B のインバウンド フェーズは、ノード A のアウトバウンド フェーズと似ています。ノード B から ztunnel へのこのフェーズでは、最初のデータ パケットが istioin インターフェイスからホストを離れ、pistioin インターフェイスが ztunnel ポッドに入ります。後続のデータ 接続は 0x210 でマークされているため、パケットは ztunnel ポッドの veth デバイスを介してホストから出て、ztunnel ポッドの eth0 デバイスを介して ztunnel ポッドに入ります。

パート 3: ztunnel-B から httpbin へ

ztunnel-B がピア ztunnel から接続を受信すると、ターゲット Pod への TCP 接続をすぐに確立し、復号化されたデータをこの接続を通じてターゲット Pod に送信できるようにします。ztunnel-B は、getsockopt を呼び出して接続からデータを取得します。 SO_ORIGINAL_DST オプションを使用して、元の宛先アドレスにアクセスし、ztunnel-A によって送信される HTTP CONNECT ハンドシェイク メッセージを通じて実際の宛先ポートを学習します。同時に、httpbin Pod がデータ パケットがスリープ Pod から来たものであると認識するために、 ztunnel は httpbin への接続に使用されるソケットで IP_TRANSPARENT オプションを渡す必要があります。接続のソース アドレスは強制的にスリープ ポッドのアドレスになります (ztunnel は接続のソース アドレスを通じてスリープ ポッドのアドレスを学習できます) 。このように、データ パケットが実際にスリープ ポッドから送信されるのと同様に、ztunnelB から送信されるデータ パケットの送信元アドレスはスリープ ポッド アドレス、宛先アドレスは httpbin ポッド アドレスになります。次に、このパケットがどのように ztunnel ポッドを出て、最終的に httpbin ポッドに到達するかを見ていきます。

1)ztunnel-B ネットワーク名前空間 -> Node-B ネットワーク名前空間

httpbin ポッドに送信されたパケットは、ztunnel B ポッドの iptables ルールにヒットしないため、ポッドにはラベルが送信されず、メイン ルーティング テーブルを使用して、パケットは ztunnel ポッド内の次のポリシー ルーティングにヒットします。

0:      from all lookup local
20000:  from all fwmark 0x400/0xfff lookup 100
20003:  from all fwmark 0x4d3/0xfff lookup 100
32766:  from all lookup main
32767:  from all lookup default

メインルーティングテーブルの内容は次のとおりです。

default via 10.244.1.1 dev eth0 
10.244.1.0/24 via 10.244.1.1 dev eth0 src 10.244.1.3 
10.244.1.1 dev eth0 scope link src 10.244.1.3 
192.168.126.0/30 dev pistioin proto kernel scope link src 192.168.126.2 
192.168.127.0/30 dev pistioout proto kernel scope link src 192.168.127.2

httpbin ポッドのアドレスは 10.244.1.7 であるため、ルーティング テーブルの 10.244.1.1 dev eth0 を介したデフォルト ルールがルーティングに使用され、データ パケットは eth0 ネットワーク インターフェイスに送信されて ztunnel ポッドから出て、ホストに入ります。

2)Node-B ネットワーク名前空間 -> httpbin ネットワーク名前空間

データ パケットがホストに到着した後、その宛先アドレスはローカル マシン上のポッドのアドレスであるため、前の段階でヒットした ztunnel ポッドにデータ パケットをリダイレクトするルーティング ルールにヒットしないようにする必要があります。 ztunnel を使用します。次のルールが PREROUTING チェーンに追加されました (ztunnel-PREROUTING チェーンにジャンプする方法については、前の記事を参照してください。ここでは繰り返しません)。

......
-A ztunnel-PREROUTING ! -s 10.244.1.3/32 -i vethbcda8cd4 -j MARK --set-xmark 0x210/0x210
......

vethbcda8cd4 は、ztunnel B Pod の veth ペアのホスト側のデバイスです。データ パケットが ztunnel Pod の eth0 デバイスに入った後、このデバイスを介してホストに到達します。このルールは、ztunnel Pod veth からのデータ パケットと一致します。データこのルールにヒットしたパケットには 0x210 のマークが付けられます。2 番目の部分では、ztunnel-A からのデータ パケットは 103 番のポリシー ルーティング ルールにヒットし、100 ルーティング テーブルを使用して ztunnel ポッドにルーティングされました。ただし、現在、 0x210 マーク以降、データ パケットは最初に 100 番のポリシー ルーティング ルールにヒットし、最後にメイン ルーティング テーブルをルーティングに使用します。

0:      from all lookup local
100:    from all fwmark 0x200/0x200 goto 32766
101:    from all fwmark 0x100/0x100 lookup 101
102:    from all fwmark 0x40/0x40 lookup 102
103:    from all lookup 100
32766:  from all lookup main
32767:  from all lookup default

メインのルーティング テーブルの内容を見てみましょう。

default via 172.18.0.1 dev eth0 
10.244.0.0/24 via 172.18.0.2 dev eth0 
10.244.1.2 dev veth1eb71e57 scope host 
10.244.1.3 dev vethbcda8cd4 scope host 
10.244.1.5 dev veth6cba8664 scope host 
10.244.1.6 dev vetheee0622e scope host
10.244.1.7 dev vethfc1b555e scope host
10.244.2.0/24 via 172.18.0.3 dev eth0 
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.4 
192.168.126.0/30 dev istioin proto kernel scope link src 192.168.126.1

K8s ネットワークは、現在のノード上のすべてのポッド ルーティング エントリをメイン ルーティング テーブルに挿入します。ポッド IP に送信されたデータ パケットは、ポッド ネットワーク名前空間に接続されている veth デバイスにルーティングされます。httpbin ポッドに送信されたデータ パケットは、したがって、行 7 のルーティング ルールは vethfc1b555e デバイスにルーティングされ、パケットはデバイスのもう一方の端 (httpbin ポッド内にある eth0 デバイス) から httpbin ポッドに入ります。この時点で、データ パケットの完全なパスが完成しました。

結論

この記事では、著者はアンビエント メッシュ内のソース Pod からターゲット Pod までの完全なパスを分析します。ただし、紙面の制限により、実際にはこの記事では触れられていない詳細がいくつかあります。著者はパケット ルーティングについて説明します。将来の非ポッド通信の実現に向けて、これらの内容を段階的に共有していきます。Alibaba Cloud Service Grid ASM [ 2]も、リリースされたばかりのバージョン 1.18 でアンビエント モードを正式にサポートしています。アンビエント モードをサポートする業界初のフルマネージド サービス グリッドとして、ASM はいくつかの一般的なネットワーク プラグインを適応させ、対応するサポート ドキュメントを提供しています。ルーティングルールやアンビエントモードでのセキュリティルールなど、読者の皆様もぜひ体験してみてください。

関連リンク:

[1] この記事

https://developer.aliyun.com/article/1290950

[2] Alibaba Cloud Service Grid ASM

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fservicemesh.console.aliyun.com%2F&lang=zh

オープンソース フレームワーク NanUI の作者がスチールの販売に切り替えたため、プロジェクトは中断されました。Apple App Store の無料リストのナンバー 1 はポルノ ソフトウェア TypeScript です。人気が出てきたばかりなのに、なぜ大手はそれを放棄し始めるのでしょうか。 ? TIOBE 10月リスト:Javaが最大の下落、C#はJavaに迫る Rust 1.73.0リリース AIガールフレンドにイギリス女王暗殺を勧められた男性に懲役9年の実刑判決 Qt 6.6正式リリース ロイター:RISC-Vテクノロジーが中米テクノロジー戦争の鍵となる 新たな戦場 RISC-V: 単一の企業や国に支配されない レノボ、Android PC の発売を計画
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/3874284/blog/10117325