Тему нагрузочного тестирования сетевого оборудования принято как-то обходить стороной, обычно упоминается вскользь в разрезе жутко дорогого специализированного железа. Не нашел информации про данный open-source продукт на русском языке так что позволю себе слегка популяризировать. В статье опишу небольшой HOWTO с целью познакомить людей с софтварными трафик генераторами.

Cisco TREX — высокопроизводительный генератор трафика. Для своей работы использует dpdk. Аппаратные требования — 64-bit архитектура, совместимая сетевая карта, поддерживаемые ос * Fedora 18-20, 64-bit kernel (not 32-bit) * Ubuntu 14.04.1 LTS, 64-bit kernel (not 32-bit). Вы можете запустить на другом линуксе, запилив себе необходимые драйвера и собрав свою версию из файлов, которые лежат в репозитории на гитхабе, здесь все стандартно.

DPDK


Data Plane Development Kit (DPDK), изначально разработанный Intel и переданный в открытое сообщество.
DPDK это фреймворк который предоставляет набор библиотек и драйверов для ускорения обработки пакетов в приложениях, работающих на архитектуре Intel. DPDK поддерживается на любых процессорах Intel от Atom до Xeon, любой разрядности и без ограничения по количеству ядер и процессоров. В настоящее время DPDK портируется и на другие архитектуры, отличные от x86 — IBM Power 8, ARM и др.
Если не углубляться в технические подробности, DPDK позволяет полностью исключить сетевой стек Linux из обработки пакетов. Приложение, работающее в User Space, напрямую общается с аппаратным обеспечением.
Помимо поддержки физических карточек имеется возможность работать с paravirtualized картами VMware (VMXNET /
VMXNET3, Connect using VMware vSwitch) и E1000 (VMware/KVM/VirtualBox).

DEPLOY


Скачаем, распакуем, соберем trex.
WEB_URL=http://trex-tgn.cisco.com/trex # или csi-wiki-01:8181/trex (Cisco internal)
mkdir trex
cd trex
wget --no-cache $WEB_URL/release/v2.05.tar.gz
tar -xzvf v2.05.tar.gz
cd v2.05
cd ko/src  
make  
make install  
cd -  


Интерфейсы, с которых будет производиться тестирование, необходимо вытащить из линукса и передать под управление dpdk, для этого необходимо выполнить команду, которая выведет PCI id всех интерфейсов.
 $>sudo ./dpdk_setup_ports.py --s

 Network devices using DPDK-compatible driver
 ============================================

 Network devices using kernel driver
 ===================================
 0000:02:00.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth2 drv=e1000 unused=igb_uio *Active*
 0000:03:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv= unused=ixgb #1
 0000:03:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv= unused=ixgb #2
 0000:13:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv= unused=ixgb #3
 0000:13:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv= unused=ixgb #4


 Other network devices
 =====================


Затем добавить их в конфигурационный файл, рекомендуется скопировать, потому что тогда trex будет его автоматически подхватывать, без необходимости указывать путь в ручную при каждом запуске.
cp  cfg/simple_cfg.yaml /etc/trex_cfg.yaml

Как вы успели заметить, конфигурация хранится в популярном ныне формате YAML, забегая вперед, в нем же хранятся конфигурационные файлы тестов. В нем так же рекомендуется задать мак адреса.
На всякий случай пример того, как файл должен выглядеть:
        - port_limit      : 2
          version       : 2
          interfaces    : ["03:00.0","03:00.1"]   2
          port_info       :  # set eh mac addr
                  - dest_mac        :   [0x1,0x0,0x0,0x1,0x0,0x00]  # port 0
                    src_mac         :   [0x2,0x0,0x0,0x2,0x0,0x00]                                     1
                  - dest_mac        :   [0x2,0x0,0x0,0x2,0x0,0x00]  # port 1                           1
                    src_mac         :   [0x1,0x0,0x0,0x1,0x0,0x00

port 0 — src
port 1 — dst

Давайте уже нагрузим что-нибудь


Физические интерфейсы необходимо подключить куда-нибудь по схеме вход-выход. Один интерфейс будет отсылать пакеты другой принимать (на самом деле генератор умеет эмулировать полноценные честные tcp сессии, но сейчас не об этом)

Следующая команда запустит тест, который будет нагружать железо dns запросом в одном и том же направлении на протяжении 100 секунд, кстати, если вы захотите чтобы шаблон отрабатывал на всех интерфейсах(данный пакет уходил в обоих направлениях), то можно добавить ключ -p
sudo ./t-rex-64 -f cap2/dns.yaml -c 4 -m 1 -d 100 -l 1000

-c — число ядер процессора.
-m — множитель cps каждого шаблона пакетов.
-d — время теста.
-l — частота (в Hz) latency пакетов, много параметров считается без их учета.

В данном случае вывод будет содержать что-то такое (слегка ужал, выбрав самое интересное)
 -Global stats enabled
 Cpu Utilization : 0.0  %  29.7 Gb/core 
 Platform_factor : 1.0
 Total-Tx        :     867.89 Kbps                                             
 Total-Rx        :     867.86 Kbps                                             
 Total-PPS       :       1.64 Kpps
 Total-CPS       :       0.50  cps

 Expected-PPS    :       2.00  pps   9
 Expected-CPS    :       1.00  cps   10
 Expected-BPS    :       1.36 Kbps   11

 Active-flows    :        0 6 Clients :      510   Socket-util  : 0.0000 %
 Open-flows      :        1 7 Servers :      254   Socket   :        1  Socket/Clients :  0.0
 drop-rate       :       0.00  bps   
 current time    : 5.3 sec
 test duration   : 94.7 sec

Cpu Utilization — среднее значение нагрузки на CPU передающими тредами. Для налучшей производительности рекомендуется держать меньше 80%.
Total-Tx — суммарная скорость на передающем интерфейсе (в данном случае port 0)
Total-Rx — суммарная скорость на принимающем интерфейсе (в данном случае port 1)
Total-PPS — packets per second число пакетов на интерфейсах
Total-CPS — connections per second по сути этот параметр означает число запуска шаблонов, которые указаны в конфигурационном файле в секунду.

Expected-PPS — Ожидаемое число пакетов в секунду, в теории стремится к cps*число пакетов шаблона.
Expected-CPS — cps указанный в yaml файле теста.
Expected-BPS — суммарный трафик, объем шаблона * cps.

Active-flows — число внутренних потоков t-rex. По сути этот параметр является числом сессий, за которыми следит t-rex. например, если вы запустите тест с pcap длительность сессии в котором равна 30 сек, то это показатель должен стремится к 30*Expected-CPS.

При желании действительно «нагрузить» сеть, можно увеличить множитель шаблона и добавить -p.
sudo ./t-rex-64 -f cap2/dns.yaml -c 4 -m 9000 -d 100 -l 1000 -p

Будет увеличено число потоков с одним и тем же IP, если критично разнообразие трафика (src адресов), то необходимо увеличивать CPS в конфигурационном файле, кстати, о нем.

Конфигурации тестов


Рассмотрим cap2/dns.yaml:
- duration : 10.0
  generator :  
          distribution : "seq"
          clients_start : "16.0.0.1"
          clients_end   : "16.0.1.255"
          clients_end : "48.0.0.1"
          servers_end   : "48.0.0.255"
          clients_per_gb : 201
          min_clients    : 101
          dual_port_mask : "1.0.0.0" 
          tcp_aging      : 1
          udp_aging      : 1
  mac        : [0x00,0x00,0x00,0x01,0x00,0x00]
  #vlan       : { enable : 1  ,  vlan0 : 100 , vlan1 : 200 }
  #mac_override_by_ip : true
  cap_info : 
     - name: cap2/dns.pcap
       cps : 1.0
       ipg : 10000
       rtt : 10000
       w   : 1

clients_start — clients_end — диапазон rsc адерсов.
clients_start — clients_end — диапазон dst адресов.

— name: cap2/dns.pcap — задаем pcap файл, который будет использоваться в качестве шлаблона.
cps — число соединений в секунду, по сути равняется числу одновременно последовательно запущенных потоков из вашего шаблона. Т.е. если в тесте у вас инкрементируется адрес, а cps: 10 то будет одновременно запущено 10 потоков с разными адресами.
ipg — должен быть таким же как rtt.

В общем случае логика тирекса выглядит так: он проходит по всему диапазону IP адресов, на каждой итерации меняя dst и src адреса, когда они заканчиваются, цикл повторяется с инкрементом порта и так 64к раз.

Тестируем NAT


Серьезные парни из циски реализовали очень важную функцию, они позволили генератору создавать честные tcp сессии и следить за ними. Например, если между нашими интерфейсами будет NAT, то можно сказать «у нас нат» и трафик будет учитываться с детектированием трансляции.
Всего есть три режима:
mode 1 Данный режим работает только на TCP. Смотрим на ACK, который приходит за первым SYN и таким образом обучаемся. Это хороший честный режим.
mode 2 Работает с IP option.
mode 3 Работает как режим 1, только не учит Sequence Number на сервере в сторону клиента. Может дать прирост cps относительного первого режима.

sudo ./t-rex-64 -f cap2/http_simple.yaml -c 4  -l 1000 -d 100000 -m 30  --learn-mode 1

-Global stats enabled 
 Cpu Utilization : 0.1  %  13.4 Gb/core 
 Platform_factor : 1.0  
 Total-Tx        :      24.12 Mbps   Nat_time_out    :        0 
 Total-Rx        :      24.09 Mbps   Nat_no_fid      :        0 
 Total-PPS       :       5.08 Kpps   Total_nat_active:        1 
 Total-CPS       :      83.31  cps   Total_nat_open  :     1508 

 Expected-PPS    :       3.08 Kpps  
 Expected-CPS    :      83.28  cps  
 Expected-BPS    :      22.94 Mbps  

 Active-flows    :       11  Clients :      252   Socket-util : 0.0001 %    
 Open-flows      :     1508  Servers :    65532   Socket :       11 Socket/Clients :  0.0 
 drop-rate       :       0.00  bps   
 current time    : 18.7 sec  
 test duration   : 99981.3 sec  

Nat_time_out — должно быть ноль, число потоков, за которыми тирекс по каким-то причинам не смог уследить, обычно происходит если пакеты где-то дропают.
Nat_no_fid — должно быть ноль, обычно происходит при слишом больших таймаутах внутри тестируемого оборудования.
Total_nat_active: активное число потоков, должно быть низким при низком rtt.
Total_nat_open: общее число потоков, может отличаться пр однонаправленном (uni-directional) шаблоне.

На самом деле есть еще один важный параметр, который мы не указали --l-pkt-mode нужна эта штука для указания типа пакетов, которыми мы измеряем latency, именно к нему относится ключ -l, к слову, они не учитываются нигде кроме вывода latency, т.е. на параметры типа open-flows влиять не должны.
0 (default) SCTP packets;
1 ICMP с обеих сторон;
2 Stateful, отправляет ICMP с одной стороны и матчит их с другой. Этот параметр имеет смыл, если ваше оборудование дропает пакеты снаружи;
3 отправляет ICMP пакеты всегда с 0 sequence number.

Конец.


Если будет заинтересованность в следующий раз расскажу про изменения в версии 2.06.
Настоятельно рекомендую рассмотреть данный генератор для тестирования ваших проектов, он неприхотлив, доступен, и, самое главное, open source.

Источники


trex-tgn.cisco.com/trex/doc
sdnblog.ru/what-is-intel-dpdk
github.com/cisco-system-traffic-generator/trex-core
Поделиться с друзьями
-->

Комментарии (7)


  1. mickvav
    25.07.2016 16:23

    Спасибо за статью, учтём.


  1. RicoX
    25.07.2016 22:52
    -1

    Замените пожалуйста

    make install  
    
    , хорошая же заметка, полезная, а тут как серпом по тестикулам.


    1. avonar
      25.07.2016 23:13
      +1

      Мне искренне жаль ваши тестикулы, но ошибки здесь нет https://github.com/cisco-system-traffic-generator/trex-core/blob/master/scripts/ko/src/Makefile


      1. tst
        26.07.2016 17:02
        +1

        На досуге поглядите статью:
        habrahabr.ru/post/130868

        проще всего заменить make install на checkinstall


        1. avonar
          26.07.2016 17:08
          +2

          Проще всего посмотреть-таки мейк файл на который я ссылку дал. Целый страшный модуль ядра.
          Господа, я не против checkinstall, но здесь просто нет необходимости.


  1. abnicken
    27.07.2016 10:16
    +2

    Я бы добавил, что Trex не всегда отображает соответствие номера шины тому или иному интерфейсу, то есть по вызову команды

    sudo ./dpdk_setup_ports.py --s
    

    не всегда можно увидеть данное соответствие. И не стоит передавать под управление DPDK менеджмент интерфейс.

    Чтобы избежать этого можно сначала вывести такое соответствие и с учетом полученной информации уже менять конфигурационный файл
    lshw -c network -businfo
    


    Чтобы потом вернуть интерфейс обратно из под управления DPDK пригодится команда
    sudo ./dpdk_nic_bind.py -b <DRIVER_NAME> <BUS_NUMBER>
    


    Вообще, достаточно приятный инструмент. У него насколько я знаю вышел недавно GUI, а также можно легко самому написать обертку вокруг его API. Что мне еще понравилось в Trex так это режим stateless с возможностью генерировать пакеты с переменными полями mac_src/ip_src/ip_dst и так далее.


    1. avonar
      27.07.2016 11:18

      Да, про dpdk хорошее уточнение. Вот только гуи у него под винду. Но написать обертку над api действительно несложно.