Cisco TRexトラフィックジェネレータ:ネットワークデバイスの負荷テストの開始





別のルーターを開発するときに、便利なオープンソースの部分であるCisco TRexトラフィックジェネレーターを使用してネットワークパフォーマンスをテストしました。このツールとは何ですか?どうやって使うのですか?そして、それは開発エンジニアにとってどのように役立ちますか?以下は、これらの質問に対する回答です。



1. Cisco TRexとは



これは、標準のIntel DPDKベースのプロセッサで実行され、ステートフル/ステートレスモードをサポートするオープンソースソフトウェアトラフィックジェネレーターです。比較的シンプルで完全にスケーラブルです。



このツールの英語のドキュメントは、Webサイトで入手できます



Trexを使用すると、さまざまなタイプのトラフィックを生成し、受信時にデータを分析できます。 MACおよびIPレベルでの作業がサポートされています。パケットのサイズと数を設定し、データ転送速度を制御できます。



ジェネレーターの操作はLinux環境で構成されています。



Trexジェネレーターの重要な違いの1つは、DPDKテクノロジーの使用です。これにより、Linuxネットワークスタックのパフォーマンスボトルネックを回避できます。 DPDKまたはデータプレーン開発キットは、パケット処理からLinuxネットワークスタックを除外し、ネットワークデバイスと直接やり取りできる高速パケット処理用のライブラリとドライバーのセットです。



DPDKは、汎用プロセッサをパケット転送サーバーに変えます。この変革により、高価なスイッチやルーターが不要になります。ただし、DPDKは特定のネットワークアダプターの使用に制限を課しています。サポートされているハードウェアのリストはリンクに示されています-これはIntelからの最も人気のあるプラットフォームです、つまり Linuxドライバーe1000、ixgbe、i40e、ice、fm10k、ipn3ke、ifc、igcで動作するハードウェアサポートが提供されます。



また、TRexサーバーが10 Gbpsで動作するには、4コア以上のマルチコアプロセッサが必要です。できれば、同時マルチスレッド(ハイパースレッド)をサポートするIntel CPUが望ましいです。



2. TRexを入手して試す方法



1)trex-tgn.cisco.comサーバーからアーカイブをダウンロードします。trex-tgn.cisco.com/ trex / release



/ユーザーのホームディレクトリ「/ home / user」にアーカイブを解凍します。userはユーザー名です。



[bash]>wget --no-cache https://trex-tgn.cisco.com/trex/release/latest
[bash]>tar -xzvf latest


2)データを送受信するためのインターフェースの設定



TRexのアーカイブに含まれている「dpdk_setup_ports.py」ユーティリティを使用して設定を実行してみましょう。 TRexがMACレベルまたはIPレベルで使用するネットワークインターフェイスを設定できます。開始するには、このユーティリティを「sudo ./dpdk_setup_ports.py –i」インタラクティブ設定キーで実行する必要があります。



最初のステップは、MACレベルでの構成を破棄することです(MACベースの構成を使用しますか?(Y / N)n)。



2番目のステップは、使用するネットワークインターフェイスのペアを選択することです。この場合、Intel X710ネットワークカードは4つのネットワークインターフェイスで機能し、ネットワークカードの1番目と4番目のソケットを使用します。







3番目のステップでは、システムが自動的に閉じた構成を作成することを提案します-データがポート1を出てポート2(およびその逆)に到着すると、すべて1台のPCにあります。このスキームを放棄し、2台のPCのルーティングスキームを構成する必要がありました。



4番目と5番目のステップでは、構成を/etc/trex_cfg.yamlファイルに保存することに同意します。



たとえば、次の接続スキームのIPレベルでの構成を検討してください







。構成ファイルは「/etc/trex_cfg.yaml」にあります。CPUが8スレッドをサポートする2ポートNICの簡単な構成ファイルを以下に示します。



### Config file generated by dpdk_setup_ports.py ###
- version: 2
  interfaces: ['01:00.0', '01:00.3']
  port_info:
      - ip: 192.168.253.106
        default_gw: 192.168.253.107
      - ip: 192.168.254.106
        default_gw: 192.168.254.107
 
  platform:
      master_thread_id: 0
      latency_thread_id: 1
      dual_if:
    	- socket: 0
      	threads: [2,3,4,5,6,7]


構成では:



  • '01:00.0 '、'01:00.3'-使用されているLinuxシステムのEthインターフェースの名前。
  • ip:192.168.253.106-トラフィックが生成されるサーバーTRex PCのポートのアドレス。
  • default_gw:192.168.253.107-PC DUT(被試験デバイス)の1ポートのアドレス。
  • ip:192.168.254.106-QOSルールを通過した後にトラフィックが返されるサーバーTRex PCポートのアドレス。
  • default_gw:192.168.253.107-PC DUTの2つのポートのアドレス。


注意!TRexシステムでは、システムで使用されるストリームを生成するときに同じサブネットを使用することは禁止されています。このため、パケットを生成するときは、サブネット16.0.0.0および48.0.0.0が使用されます。



3)リモートマシンのインターフェイスの



構成トラフィックを通過させるシステム(DUT)がパケットの受信先と送信先を認識できるように、転送とルーティングを構成する必要があります。



DUT PCでフロールーティングルールを構成します。



sudo echo 1 > /proc/sys/net/ipv4/ip_forward
sudo route add -net 16.0.0.0 netmask 255.0.0.0 gw 192.168.253.106
sudo route add -net 48.0.0.0 netmask 255.0.0.0 gw 192.168.254.106


4)astfモードでTRexサーバーを起動します。



cd v2.XX
sudo ./t-rex-64 -i --astf


TRexサーバーが正常に起動すると、テストに使用されたイーサネットポートに関する情報が表示されます。



The ports are bound/configured.
port : 0 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
port : 1 
------------
link         :  link : Link Up - speed 10000 Mbps - full-duplex
promiscuous  : 0 
number of ports         : 2 
max cores for 2 ports   : 1 
tx queues per port      : 3


5)TRexコンソール



起動します。コンソールを使用して、別のウィンドウで、既製のサンプルからストリーム生成を起動します(astfサンプルのフォルダーはTRexのアーカイブにあります)。



cd v2.XX
./trex-console
start -f astf/http_simple.py -m 1
 
start (options):
-a (all ports)
-port 1 2 3 (ports 1 2 3)
-d duration (-d 100 -d 10m -d 1h)
-m stream strength (-m 1 -m 1gb -m 40%)
-f load from disk the streams file


起動が成功すると、TRexサーバーコンソールにトラフィックフロー統計が表示されます。



Global stats enabled
Cpu Utilization : 0.3  %  0.6 Gb/core 
Platform_factor : 1.0  
Total-Tx        :     759.81 Kbps  
Total-Rx        :     759.81 Kbps  
Total-PPS       :      82.81  pps  
Total-CPS       :       2.69  cps  
 
Expected-PPS    :       0.00  pps  
Expected-CPS    :       0.00  cps  
Expected-L7-BPS :       0.00  bps  
 
Active-flows    :        2  Clients :        0   Socket-util : 0.0000 %    
Open-flows      :      641


3. TRexによる開発とテストの自動化



ネットワークルーターを開発する過程で、TRexの多くのテストを作成したため、Pythonを使用して自動モードで実行するという疑問が生じました。編成方法:



TRexサーバーをstlモードで起動しました。



cd v2.XX
sudo ./t-rex-64 -i --stl


TRexはPythonと連動するため、Pythonの環境変数を設定します。



export PYTHONPATH = / home / !!! user !!! / v2.XX / Automation / trex_control_plane / interactive、where "!!! user !!!" -ユーザー名とホームディレクトリ、v2.XX-ダウンロードされ、このフォルダに解凍されたTRexソフトウェアのバージョン。



Pythonを使用してトラフィックジェネレーターを開始しました。構成例のリストを以下に示します。



python example_test_2bidirectstream.py



予想される出力:



Transmit: 10000.24576MByte/s Receive: 10000.272384MByte/s
Stream 1 TX: 4487179200 Bit/s RX: 4487179200 Bit/s
Stream 2 TX: 2492873600 Bit/s RX: 2492873600 Bit/s
Stream 3 TX: 1994294400 Bit/s RX: 1994294400 Bit/s
Stream 4 TX: 997147200 Bit/s RX: 997147200 Bit/s


この例を見てみましょう:



c = STLClient(server = '127.0.0.1')



TRexサーバーへの接続を作成します。この場合、接続はサーバーと同じマシンに作成されます。



  • 「Base_pkt_dir_a、base_pkt_dir_b、base_pkt_dir_c、base_pkt_dir_d」-送信元と宛先のアドレス、送信元と宛先のポートを含むパケットテンプレート。この例では、1つの方向に2つ、反対方向に2つ、4つのストリームが作成されます。
  • 「S1、s2、s3、s4」-ストリームIDやビットレートなど、STLStreamクラスから生成されたストリームのパラメーターを要求します。この例では、ID1 = 4.5 Gbps、ID2 = 2.5 Gbps、ID3 = 2 Gbps、ID4です。 = 1 Gbps。


ストリーム構成ファイルexample_test_2bidirectstream.pyのリスト



# get TRex APIs
from trex_stl_lib.api import *
 
c = STLClient(server = '127.0.0.1')
c.connect()
 
try:
    # create a base packet with scapy
    base_pkt_dir_a = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=5001,sport=50001)
    base_pkt_dir_b = Ether()/IP(src="48.0.0.1",dst="16.0.0.1")/UDP(dport=50001,sport=5001)
 
    base_pkt_dir_c = Ether()/IP(src="16.0.0.2",dst="48.0.0.2")/UDP(dport=5002,sport=50002)
    base_pkt_dir_d = Ether()/IP(src="48.0.0.2",dst="16.0.0.2")/UDP(dport=50002,sport=5002)
 
    # pps : float
    # Packets per second
    #
    # bps_L1 : float
    # Bits per second L1 (with IPG)
    #
    # bps_L2 : float
    # Bits per second L2 (Ethernet-FCS)
    packet_size = 1400
 
    def pad(base_pkt):
        pad = (packet_size - len(base_pkt)) * 'x'
        return pad
 
    s1 = STLStream(packet=STLPktBuilder(base_pkt_dir_a/pad(base_pkt_dir_a)), mode=STLTXCont(bps_L2=4500000000), flow_stats=STLFlowStats(pg_id=1))
    s2 = STLStream(packet=STLPktBuilder(base_pkt_dir_b/pad(base_pkt_dir_b)), mode=STLTXCont(bps_L2=2500000000), flow_stats=STLFlowStats(pg_id=2))
    s3 = STLStream(packet=STLPktBuilder(base_pkt_dir_c/pad(base_pkt_dir_c)), mode=STLTXCont(bps_L2=2000000000), flow_stats=STLFlowStats(pg_id=3))
    s4 = STLStream(packet=STLPktBuilder(base_pkt_dir_d/pad(base_pkt_dir_d)), mode=STLTXCont(bps_L2=1000000000), flow_stats=STLFlowStats(pg_id=4))
 
    my_ports = [0, 1]
 
    c.reset(ports = [my_ports[0], my_ports[1]])
 
    # add the streams
    c.add_streams(s1, ports = my_ports[0])
    c.add_streams(s2, ports = my_ports[1])
    c.add_streams(s3, ports = my_ports[0])
    c.add_streams(s4, ports = my_ports[1])
 
    # start traffic with limit of 10 seconds (otherwise it will continue forever)
    # bi direction
    testduration = 10
    c.start(ports=[my_ports[0], my_ports[1]], duration=testduration)
    # hold until traffic ends
    c.wait_on_traffic()
 
    # check out the stats
    stats = c.get_stats()
 
    # get global stats
    totalstats = stats['global']
    totaltx = round(totalstats.get('tx_bps'))
    totalrx = round(totalstats.get('rx_bps'))
    print('Transmit: {}MByte/s Receive: {}MByte/s'.format((totaltx / 1000000), (totalrx / 1000000)))
    c.clear_stats(ports = [my_ports[0], my_ports[1]])
 
    # get flow stats
    totalstats = stats['flow_stats']
    stream1 = totalstats[1]
 
    stream2 = totalstats[2]
    stream3 = totalstats[3]
    stream4 = totalstats[4]
    totaltx_1 = stream1.get('tx_pkts')
    totalrx_1 = stream1.get('rx_pkts')
    print('Stream 1 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_1['total'] / testduration * packet_size * 8),
                                                               (totalrx_1['total'] / testduration * packet_size * 8)))
    totaltx_2 = stream2.get('tx_pkts')
    totalrx_2 = stream2.get('rx_pkts')
    print('Stream 2 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_2['total'] / testduration * packet_size * 8),
                                                               (totalrx_2['total'] / testduration * packet_size * 8)))
    totaltx_3 = stream3.get('tx_pkts')
    totalrx_3 = stream3.get('rx_pkts')
    print('Stream 3 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_3['total'] / testduration * packet_size * 8),
                                                               (totalrx_3['total'] / testduration * packet_size * 8)))
    totaltx_4 = stream4.get('tx_pkts')
    totalrx_4 = stream4.get('rx_pkts')
    print('Stream 4 TX: {} Bit/s RX: {} Bit/s'.format((totaltx_4['total'] / testduration * packet_size * 8),
                                                               (totalrx_4['total'] / testduration * packet_size * 8)))
except STLError as e:
    print(e)
 
finally:
    c.disconnect()


結論



このガイドをHabr用に準備するとき、4つのスレッドでDUTシステムの動作を開始してテストし、スレッドに関する情報とグローバル統計を収集しました。



上記の操作はpythonを使用して起動されます。つまり、TRexを使用すると、ネットワークデバイスとソフトウェア製品のテストとデバッグをループで、またはpythonで順次テストを実行するときに自動化できます。



では、なぜシスコのTRexは他の同様のトラフィックジェネレータよりも優れているのでしょうか。たとえば、人気のあるクライアントサーバープログラムiperf? TRexの使用シナリオでは、ストリームの設定と操作の説明が表示されます。テストツールとデバッグツールの両方が優れています。iperf-外出先で機能をすばやくテストできます。TRexは、特定のタスクの各ストリームを構成し、出力結果を分析するためにマルチスレッドストリームを構成する機能が重要である、複雑なネットワークデバイスとシステムのテストと開発を自動化する優れた仕事をします。 ...



TRexを使用すると、ほぼすべての種類のトラフィックのテンプレートを作成し、それらを増幅して、TCP-SYN、UDP、およびICMPストリームを含む大規模なDDoS攻撃を生成できます。大量のトラフィックストリームを生成する機能により、複数のターゲットサーバー上の複数のクライアントからの攻撃をシミュレートできます



したがって、このツールをまだ試していない場合は、メモを取ることができます。そして、あなたが試した場合-コメントであなたの例とフィードバックを共有してください。TRexが他のエンジニアによってどのように考えられ、使用されているかを知るのは興味深いことです。



All Articles