Поглаживаем ящерицу или сетевое нагрузочное тестирование с cisco trex
Тему нагрузочного тестирования сетевого оборудования принято как-то обходить стороной, обычно упоминается вскользь в разрезе жутко дорогого специализированного железа. Не нашел информации про данный 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