Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Contrail エンドツーエンドのパケットフロー

 

ここまでは、’floating IP、サービス、および受信の詳細について検討し、これらのオブジェクトが相互にどのように関連しているかを確認してきました。Contrail では、サービスと受信の両方がロードバランサーに基づいて実装されます (ただし、loadbalancer_provider タイプは異なります)。概念的には、入口はサービスに基づいて設計されています。両方のタイプのロードバランサーの VIP は、floating IP に基づいて実装されています。

パケットフロー

この Contrail Kubernetes 環境でのパケットフローを詳細に示すために、’受信ラボのセットアップで、外部のインターネットホストから宛先ポッドへのエンドツーエンドの HTTP 要求を検証します。転送’の状態について順を追って説明します。まず、インターネットホストからゲートウェイルーターを経由して、アクティブな haproxy、バックエンドサービス、最終宛先ポッドまで、順に実行します。

Note

パケットフローを理解することで、将来の転送プレーンの問題のトラブルシューティングが可能になります。

セットアップ、ユーティリティ、ツール

前’のFigure 1は、第6章の入口セクションから見てきました。

Figure 1: 受信トラフィックフロー: 外部からのアクセス
受信トラフィックフロー: 外部からのアクセス

その前に、外部ゲートウェイルーター’の VRF ルーティングテーブルを見て、プロトコルのネクストホップ情報を使用して、クライアントからパケットを取得するノードを探していました。実際には、クラスターとノード自体から同じものを確認する必要があります。通常、Contrail クラスターには、パケットフローと転送の状態を確認するために使用できるビルトインユーティリティのグループが用意されています。本サービスの例では、フロー、nh、vif などの使用状況を確認しまし’た。この章では、これらのユーティリティについて詳しく説明し、さらに、パケットフローに関する追加情報を示すことができることを紹介します。

使用可能なユーティリティ/ツールの一部を以下に示します。

  • 任意の Linux マシンで:

    • curl (デバッグオプション付き)、HTTP クライアントツールとしての telnet

    • パケット・キャプチャ・ツールとしての tcpdump と wireshark

    • シェルスクリプトを使用してコマンドラインのタスクを自動化することができます。

  • VRouter では、以下を実行します。フロー/rt/nh/vif など

めくり

Curl ツールの実装では、シェル端末での実行時に HTTP 応答が返された直後に TCP セッションを終了させるという動作があります。これは、実際には安全でクリーンな動作ですが、テストに問題が発生する可能性があります。そのため、このラボでは実際に TCP 接続を維持して詳細を確認していました。しかし、Contrail vRouter の TCP フローエントリは TCP 接続にバインドされ、tcp セッションがフローを閉じるとクリアされます。問題は、curl が仕事を速く完了させたことです。TCP 接続を確立し、HTTP リクエストを送信し、応答を取得して、セッションを閉じます。そのプロセスは速すぎて、vRouter ユーティリティ (flow コマンドなど) を使用して何かをいつでもキャプチャすることはできません。Enter を押して curl コマンドを開始すると、コマンドは1秒または2時間以内に戻ります。

次のような回避策があります。

  • 大規模なファイル転送: 1つ目の方法は、ウェブサーバに大規模なファイルをインストールして、ファイル転送プロセスに TCP セッションが保持されるようにすることです。この’方法については、第3章の「サービス」セクションをご覧ください。

  • テルまた、telnet プロトコルを使用することもできます。URL’に対応する IP およびポートへの TCP 接続を確立し、いくつかの http コマンドとヘッダーを手動で入力して、http 要求をトリガーします。これにより、haproxy がタイムアウトになり、クライアントへの TCP 接続が切断されるまでの時間が長くなります。

ただし、haproxy がバックエンドのセッションを直ちに破棄する場合があることに注意してください。Haproxy の動作は、その実装と構成によって異なります。

インターネットホストから、入口パブリック FIP 101.101.101.1 および port 80:

TCP 接続が確立されます’(しばらくすると、もう一端が確認されます)。次に、HTTP GET コマンドと host ヘッダーを送信します。

GET / HTTP/1.1
Host: www.juniper.net

これは基本的に、HTTP GET 要求を送信してデータを取得し、ホストは要求の URL を提供します。もう1つのリターンは、要求の終わりを示しています。これにより、サーバーからすぐに応答がトリガーされます。

ここからは、アクティブな haproxy compute ノードでフローテーブルを収集して、後で分析することができます。

シェルスクリプト

3つ目の役に立つツールは、テストプロセスを自動化し、curl とフローコマンドを同時に繰り返し実行できるスクリプトです。フローテーブルを定期的に収集するための計算ノードの小さなシェルスクリプトと、インターネットホストの別のスクリプトで、curl による要求の送信を維持するために、時間の経過とともに計算ノードにフローテーブルをキャプチャする機会を得られるでしょう。

たとえば、インターネットホスト側スクリプトは以下のようになります。

さらに、次のような compute side スクリプトが表示されるかもしれません。

まず、シェルでは3秒ごとに新しいテストを開始し、2つ目は0.2 秒ごとに特定のフローエントリをキャプチャします。20個のテストを2分で完了すると、短時間で有益な情報を収集できます。

このセクション’では、スクリプトメソッドを使用して、計算ノードから必要な情報を取得します。

パケットフロー分析

その前に、curl ツールを使用して、テストに対する HTTP リクエストをトリガーしました。さまざまな機能の幅広いオプションをサポートしています。’HTTP 要求のホストフィールドを指定する-H オプションがあります。ここでは、デバッグを目的とした別の便利なオプションとして、curl コマンドで-v を使用しています。

このオプションを選択すると、HTTP インタラクションに関する詳細な情報が表示されます。

  • > のラインは、curl が送信したメッセージの内容を示しています。

  • < の明細行は、受信したメッセージの内容です。

リモートから相互作用から見ることができます。

  • Curl は、path/FIP 101.101.101.1 に HTTP GET を送信し、ホストがジュニパーネットワークスの URL でいっぱいになったことを確認しました。

  • このプログラムは、要求が成功したことを示すコード 200 OK を使用して応答を取得します。

  • 応答には、その他のヘッダーが含まれているため、テストをスキップすることはできません。

  • 応答の残りは、返された web ページの HTML ソースコードです。

  • その後、すぐに接続が閉じられます。

’ここまでは、内部で curl によって実行された冗長なやり取りを見てきました。また、telnet テストで送信した GET コマンドと host ヘッダーを理解することもできます。そのテストでは、curl が何を実行するのかをエミュレートしていましたが、今すぐ手動で行っていました。

インターネットホストとゲートウェイルーター

まず、’クライアント–からインターネットホストを起動しましょう。

Figure 2: インターネットホスト: HTTP リクエストを送信します。
インターネットホスト: HTTP リクエストを送信します。

他のホストと同様に、ルーティングテーブルは非常にシンプルです。通常、次のような静的ルート (ゲートウェイルートに向かうデフォルトルート) が必要です。

最後のエントリは、手動で構成し’た静的ルートで、ゲートウェイルーターを指しています。

Note

この設定では、VRF テーブルをゲートウェイルーターに設定し、ホストマシンを同じ MPLS/VPN に接続して、Contrail クラスターのオーバーレイネットワークと通信できるようにしました。実際には、同じ目標を達成する他の方法もあります。たとえば、ゲートウェイルーターは、Vpn とインターネットルーティングテーブルとの間のポリシーを使用してルートをリークすることもできます。 Vpn の一部ではないインターネットホストは、Contrail のオーバーレイネットワークにアクセスすることもできます。

パブリック浮動 IP を受信するゲートウェイルーター: MPLS オーバー GRE

ゲートウェイ’ルーター’のルーティングテーブルを見ていました。プロトコルの次回ホップから、パケットが MPLSoGRE トンネルを介してアクティブな haproxy ノードに送信されることを確認できます。

Figure 3: ゲートウェイルーター: 受信パブリック浮動 IP への転送
ゲートウェイルーター: 受信パブリック浮動 IP への転送

この両方の計算でフローテーブルが収集されたので、同じ情報を知ることができます。次’に、アクティブなプロキシコンピューティングのフローエントリを見てみましょう。

このフローには、インターネットホストクライアントからアクティブな haproxy までの TCP 接続の状態が反映されています。キャプチャ’の最初のエントリーを見てみましょう。

  • 1つ目のフローエントリには、HTTP リクエストの送信元と宛先が表示されます。これは、インターネットホスト (15.15.15.2) から取得され、受信浮動 IP を現在のノードの cent222 に配置します。

  • S (nh):61 は、インターネットホストへのリクエスト–の送信元への次のホップです。これは、リバースパスフォワーディング (RPF) に類似しています。VRouter では、フロー内のパケットの送信元へのパスを常に維持しています。

  • Nh get コマンドは、詳細な情報を使用して nexthop 61 を解決します。MPLSoGRE フラグが設定されており、Sip と Dip は GRE トンネルの2つの終端であり、現在はノードであり、ゲートウェイルーター’のループバックである IP であることを示しています。

  • TCP: SSrEEr は、tcp 接続の状態を示す TCP フラグです。VRouter は syn (syn) を検知し、双方向接続を確立します (EEr)。

  • Proto (V) フィールドは、VRF 番号とプロトコルタイプを示しています。ここでは、現在の (分離された) NS NS-ユーザー1で2つの VRF を関与しています。

    • VRF 2: デフォルトポッドネットワークの VRF

    • VRF 5: VRF の FIP-VN

    • プロトコル6は TCP (HTTP パケット) を意味します。

Tip

’VRF 2 を後で使用して、VRF ルーティングテーブルでプレフィックスを nexthop に照会します。

全体として、最初のフローエントリは、インターネットホストからの要求パケットがゲートウェイルーターを通過することを確認し、MPLSoGRE トンネルを介して受信外部 VIP 101.101.101.1 に到達することを保証します。NAT が起こるでしょう。’それでは、次のようにしてみましょう。

受信したパブリック浮動 ip から入口までの IP アドレス: FIP (NAT)

Figure 4: アクティブな Haproxy ノード: 受信型 Pod IP への受信パブリック浮動 IP
アクティブな Haproxy ノード: 受信型 Pod IP への受信パブリック浮動 IP

NAT 運用を検証するために必要なのは、前のフロー出力からもう少し掘り下げてみることです。

  • 最初のエントリのアクションフラグ N (D) は宛先 NAT または DNAT を示します。宛先受信外部浮動 IP 101.101.101.1 (外部受信) は、入口内部 VIP に変換されます。

  • 2番目のエントリにあるアクションフラグ N (S) は、送信元 NAT または SNAT を示します。このことは、ソース NAT ソース IP 10.47.255.238 を示しています。これは内部受信であり、VIP は受信外部 VIP に変換されます。

要約すると、アクティブな haproxy ノード cent222 のフローテーブルは、受信浮動 IP アドレス宛てのパケットを受け取ると、ノード cent222 上の vRouter が NAT の操作を実行し、宛先の浮動 IP (101.101.101.1)’を受信側の VIP (10.47.255.238) に変換します。その後、パケットは受信したロード’バランサーの s VRF テーブルに転送され、アクティブ’な haproxy s リスニングインターフェイスにそのことを示します。HTTP プロキシの運用が開始されるように’なりました。その後、そのことについて説明します。

Note

VRouter のフローでは、2つ目のフローエントリは1つ目の流れの反転フローと呼ばれることもあります。受信パケットをインターネットホストに送信するフローエントリ vRouter です。受信ロードバランサー’s の観点から見ると、デフォルトポッドネットワークからソース IP として割り当てられた10.47.255.238 のみを使用し、floating ip について何も認識されません。外部のインターネットホストでも同じことが言えますが、これは浮動 IP へのアクセス方法を認識しているだけで、プライベートな受信内部 VIP についての手掛かりはありません。VRouter は、その間に双方向の NAT 変換を実行しています。

受信ポッド IP to サービス IP アドレス: UDP 経由での MPLS

パケットは、受信したロードバランサー’の s VRF テーブルになり、haproxy のフロントエンドにあります。これは次のようなものです。

  • Haproxy はフロントエンド IP (受信内部 podIP/VIP) でリッスンしており、ポート80はパケットを表示します。

  • Haproxy は、その設定ファイルでプログラムされた受信ルールを確認し、リクエストを webservice のサービス IP にプロキシする必要があることを決定します。

  • VRouter は、受信したロード’バランサーの s VRF テーブルをチェックし、web サービスのプレフィックスを確認します。さらに、IP は宛先ノードの cent333 から学習されます。これは、パケットを転送するための次ホップになります。

  • コンピュートノード間の転送パスは MPLSoUDP トンネルによってプログラムされるため、vRouter は、右 MPLS ラベルを使用して、UDP トンネルを介して MPLS 経由で送信します。

Figure 5では、このプロセスを次に示します。

Figure 5: アクティブな Haproxy ノード: 受信ポッド IP to Service IP
アクティブな Haproxy ノード: 受信ポッド IP to Service IP

最初’に、UI の VRF ルーティングテーブルを見てみましょう。UI では、任意のコンピューティングノードから VRF 名に基づいて VRF ルーティングテーブルを確認できます。

Figure 6: 入口ロード’バランサー s VRF テーブル
入口ロード’バランサー s VRF テーブル

受信した podIP’s VRF (現在の名前空間のデフォルトポッドネットワーク) と同じ VRF を使用すると、サービス ip プレフィックス 10.99.225.17/32 の次ホップは、ip 10.169.25.21 から MPLSoUDP トンネルを使用したその他の計算ノード cent333 であることがわかります。VRouter rt/nh ユーティリティでも同じ結果が得られます。

サービスに受信したトラフィックはすべて Contrail コンピューティングノード間でオーバーレイで発生することに注意してください。つまり、すべてのオーバーレイパケットを MPLS over UDP トンネルにカプセル化する必要があります。Haproxy プロセスのパケット処理の詳細を確認する’には、アクティブな haproxy プロセスが実行されているノード cent222 の物理インタフェースでパケットをキャプチャします。次の画面キャプチャであるFigure 7は、結果を示しています。

Figure 7: アクティブな Haproxy ノード cent222 のファブリックインターフェイス上のパケットキャプチャ
アクティブな Haproxy ノード cent222 のファブリックインターフェイス上のパケットキャプチャ

Figure 7の Wireshark スクリーンショットでは、以下のことを明らかにしています。

  • フレーム43-45、受信プライベート podIP によって、サービス IP およびポートへの新しい TCP 接続が確立されました。これはオーバーレイで発生します。

  • フレーム46新しい TCP 接続では、haproxy がサービス IP への HTTP リクエストを開始します。

  • フレーム50では、HTTP 応答が戻ります。

パケットのカプセル化を示す例としてフレーム46を使用することもできます。’この IP パケットを含む HTTP 要求は、MPLS ラベル付けされており、UDP データグラムの内部に埋め込まれています。パケットの外側の送信元と宛先の IP は、それぞれ 10.169.25.20 (compute node cent222) および 10.169.25.21 (compute node cent333) です。

フォワードとプロキシ

十分に observant ば、このキャプチャでおかしなことを認識しておく必要があります。たとえば、以下のように記述します。

  • ’送信元 ip アドレスは、ロードバランサー’のフロントエンド ip ではなく、インターネットホスト’s の ip 15.15.15.2 にする必要がありますか?

  • 元の HTTP 要求はすべて転送されていますか?

  • 同じ TCP セッション内で、インターネットホスト、クロスゲートウェイルーター、ロードバランサーノード cent222 のトランザクションが、ノード cent333 に置かれているバックエンドポッドまで、すべて停止していますか?

これらの質問すべてに回答することはできません。このテストの haproxy は、レイヤー 7 (アプリケーション層) のロードバランシングを実行しています。その目的は次のとおりです。

  • インターネットホストとの TCP 接続を確立し、HTTP リクエストの監視を継続します。

  • 受信した HTTP 要求が見つかると、そのルールをチェックして、対応するバックエンドへの新しい TCP 接続を開始します。

  • インターネットホストから受信した元の HTTP 要求をコピーし、バックエンドを使用して新しい TCP 接続に貼り付けます。正確に言えば、HTTP 要求は転送されず、プロキシ化されます。

  • Wireshark ディスプレイフィルターを拡張して、15.15.15.2 と101.101.101.1 の両方が含まれるようにします。

    Figure 8: アクティブな Haproxy ノードでのパケットキャプチャ Cent222 Fabric インターフェイス: 全体“のストーリー”
    アクティブな Haproxy ノードでのパケットキャプチャ Cent222 Fabric インターフェイス: 全体“のストーリー”
  • フレーム 39-41: インターネットホストは入口外部パブリック FIP への TCP 接続を確立しました。

  • フレーム 42: インターネットホストから HTTP 要求が送信されました。

  • フレーム 43-52: active haproxy は、サービスへの新しい TCP 接続を確立し、HTTP 要求を送信し、HTTP 応答を取得して、接続を終了しました。

  • フレーム 53-54: アクティブな haproxy は、HTTP 応答をインターネットホストに返信しました。

  • フレーム 55-57: インターネットホストにより HTTP 接続が切断されました。

ここでは、フレーム42を使用して、アクティブな haproxy ノード cent222 とゲートウェイルーターとの間で GRE のカプセル化を介して MPLS を表示します。前のスクリーンショットでフレーム46と比較すると、これは別のラベルであることがわかります。GRE トンネルで運ばれる MPLS ラベルは、vRouter がパケットをアクティブな haproxy に配信する前に削除されます。アクティブな haproxy がリモートノードへの新しい TCP セッションを開始すると、新しいラベルが割り当てられます。

HTTP リクエストは、haproxy’s バックエンドに対してプロキシされていることがわかっています。入口の設定によれば、バックエンドは Kubernetes サービスです。これからサービスに到達するために、すべてのバックエンドポッドが配置されている宛先ノードに要求が送信されます。次に’、宛先ノードで何が起こるかを見てみましょう。

サービス IP からバックエンドへのポッド IP: Floating IP (NAT)

Figure 9: サービス IP からバックエンドへのポッド IP
サービス IP からバックエンドへのポッド IP

宛先ノード cent333 では、パケットが受信内部 IP 10.47.255.238 から webservice のサービス IP 10.99.225.17 に向かうときに、vRouter によって NAT の変換処理が実行されます。サービス IP はバックエンドの podIP 10.47.255.236 に変換されますが、vRouter では’、入口になっているパブリック浮動 IP を受信内部 podip と受信すると、ノード cent222 に表示されるのとほぼ同じ方法で実現できます。

ここでは、シェルスクリプトでキャプチャされたフローテーブルを示しています。このフローは、アクティブな haproxy とバックエンドポッド間の2番目の TCP 接続の状態を示しています。

「’サービス」セクションに類似した内容が表示され’ているため、問題を理解する必要はありません。当然のことですが、2つ目のエントリは、アクティブな haproxy IP (受信された podIP) からのサービス IP への着信要求によってトリガーされます。VRouter では、サービス IP が浮動 IP であることを認識しているため、バックエンドの podIP 10.47.255.236 にマップされ、サービスポートマップはバックエンドポッド内のコンテナターゲットポートに対応します。これは、着信方向で DNAT + DPAT (Dpat) を行い、送信方向に SNAT + SPAT (SPs) を行います。

この転送パスを追跡するもう1つの簡単な方法は、MPLS ラベルを確認することです。前のステップで見てきたラベル38は、アクティブな haproxy が cent222 送信パケットを MPLSoUDP トンネルに計算して cent333 を計算する場合に使用されます。Vrouter mpls ユーティリティを使用して、このインラベルの nexthop をチェックできます。

次ホップが決定されたら、アウトゴーイングインターフェイス (Oif) 番号を見つけることができます。 vif ユーティリティを使用すると、pod インターフェイスを見つけることができます。対応する podIP 10.47.255.236 は、HTTP リクエスト用のバックエンドポッドで、フローテーブルが上で示した内容と一致しています。

最後に、pod は HTTP リクエストを認識し、web ページで応答します。このトラフィックは、キャプチャの最初のフローエントリによって反映されます。これは次のとおりです。

  • 元の発信元 IP はバックエンドの10.47.255.236 ではありません。

  • 元の発信元ポートは web サーバポート80

  • 宛先 IP は、内部 podIP 10.47.255.238 を受信します。

バックエンドポッド: HTTP リクエストの分析

バックエンドポッドインターフェイスで別の tcpdump パケットキャプチャを使用すると、受信した内部 IP とバックエンドの podIP との間のパケットの相互作用を明らかにすることができます。

トラフィックを返す

逆の方向では、podIP は web ブラウザーを実行し、ウェブページで応答します。リクエストのリバースパスに従って応答が実行されます。

  • Pod はロードバランサーフロントエンド IP への応答として MPLSoUDP トンネルを経由します。

  • ノード cent333 の vRouter では、SNAT + SPAT が実行され、podIP: podPort が serviceIP: servicePort に変換されます。

  • この応答は、ノード cent222 で実行中の haproxy に到達します。

  • Haproxy は、バックエンドポッドから HTTP 応答をコピーし、リモートインターネットホストとの接続に貼り付けます。

  • ノード cent222 上の vRouter は SNAT を実行し、ロードバランサーフロントエンド IP を floating IP に変換します。

  • 応答がゲートウェイルーターに送信されます。これにより、インターネットホストに転送されます。

  • インターネットホストが応答を取得します。