Вопрос или проблема
Мне нужно протестировать пропускную способность сети сервера до/из самого себя (это долгая история!).
Я люблю Iperf и использую его в сети, но не могу разобраться, как привязать его к одному интерфейсу и слушать только через него.
Из документации я предположил бы, что это должно сработать: iperf -B eth0 -s для привязки одного экземпляра к eth0, затем в другой сессии: iperf -B eth1 -c ip.of.eth.1.
Это вообще не работает и на самом деле вызывает ошибку. Если я использую IP вместо интерфейса, это работает, но пропускная способность составляет 29 Гбит/с – так что, если только нет какой-то магии, что у меня супер сервер с картой на 30 Гбит/с, я предполагаю, что я даже не касаюсь сети и это просто идет локально.
Может ли кто-то помочь мне здесь или знает лучший тест/инструмент?
Да, этот трафик передается локально, не достигая ваших физических интерфейсов. Он передается с использованием интерфейса loopback. Ядро определяет, что назначение локальное, поэтому трафик возвращается обратно на машину, не проходя через eth0 или eth1.
Я знаю, что это старое, но публикую на случай, если это поможет кому-то еще.
Цитата из документации пользователя iPerf 2
Если iPerf в режиме сервера, то указание хоста с -c ограничит соединения, которые iPerf примет, указанным хостом. Плохо работает для UDP.
Я использовал это для тестирования пропускной способности TCP на Windows 7 64-bit с LAN на WiFi интерфейсы. Работало нормально с iperf 2.0.8 или 2.0.5, не уверен на счет других версий. Смотрите ниже используемые команды.
iperf.exe -B 192.168.0.1 -s -c 192.168.0.2 -P 0 -i 1 -p 5001 -f m
iperf.exe -B 192.168.0.2 -c 192.168.0.1 -P 1 -i 1 -p 5001 -f m -t 100 -F c:\data.bin
Поскольку я не могу комментировать из-за недостаточной репутации, я добавлю ответ, который не является ответом, но “решения”, упомянутые в https://stackoverflow.com/questions/2734144/linux-disable-using-loopback-and-send-data-via-wire-between-2-eth-cards-of-one/4490220#4490220, теоретически хороши, но ни одно из них на самом деле не работает (по крайней мере на Debian/Ubuntu, так как iperf не может назначать IP-адреса, когда вы либо удаляете локальные маршруты, либо пытаетесь использовать виртуальные NAT-адреса).
Просто чтобы сэкономить людям время и усилия для чего-то, что кажется хорошим в теории, но на самом деле не работает на (современных) Debian/Ubuntu…
Решение, предложенное Сэмом Льюисом:
https://www.samlewis.me/2020/04/force-ethernet-loopback/
Создайте пространство имен для каждого адаптера
ip netns add ns_eth0
ip netns add ns_eth1
Переместите адаптеры в пространства имен
ip link set eth0 netns ns_eth0
ip link set eth1 netns ns_eth1
Назначьте IP-адреса каждому адаптеру
ip netns exec ns_eth0 ip addr add dev eth0 192.168.1.1/24
ip netns exec ns_eth1 ip addr add dev eth1 192.168.1.2/24
Включите адаптеры
ip netns exec ns_eth0 ip link set eth0 up
ip netns exec ns_eth1 ip link set eth1 up
Проверьте, что каждый адаптер может пинговать другой
ip netns exec ns_eth0 ping 192.168.1.2
ip netns exec ns_eth1 ping 192.168.1.1
Запустите ваши тесты, уверенные в том, что трафик действительно проходит через физический интерфейс!
ip netns exec ns_eth0 iperf3 -s
ip netns exec ns_eth1 iperf3 -c 192.168.1.1
Вернитесь к оригинальному состоянию
ip netns del ns_eth0
ip netns del ns_eth1
Ответ или решение
Тестирование сетевой производительности компьютера через Iperf, когда вам нужно измерить пропускную способность между двумя интерфейсами на одной и той же машине, является интересной и технически непростой задачей. В типичной ситуации использование утилиты Iperf подразумевает тестирование между двумя узлами сети, но в вашем случае, когда необходимо протестировать взаимодействие между двумя интерфейсами одной системы, возникает несколько нюансов.
Теория
Iperf известен как мощный инструмент для измерения пропускной способности сети по протоколам TCP и UDP. Он позволяет оценивать сеть на предмет узких мест и производительности. Обычно Iperf позволяет запустить серверную часть на одном хосте и клиентскую – на другом, после чего производится тестирование пропускной способности между ними. Однако, при тестировании через саму машину существует вероятность, что сетевой стек обойдет физические интерфейсы и будет использовать локальную петлю (loopback), что и произошло в вашем случае.
Пример
Вы столкнулись с проблемой, когда даже при указании интерфейсов через -B
(bind) параметры работаете исключительно через локальные адреса и видете крайне высокие значения пропускной способности, которые не являются правдоподобными для физической сети. Это связано с тем, что при передаче данных в пределах одной системы линукс может определять, что источник и назначения находятся на той же машине и маршрутизирует их через loopback-интерфейс, увеличивая тем самым качество измеренной пропускной способности.
Для выполнения вашего сценария в системе на базе Ubuntu или Debian можно создать пространства имен (network namespaces), что предоставит необходимую изоляцию сетевых интерфейсов в пределах одной машины:
Применение
-
Создание пространств имен: Сначала создаем два пространства имен, по одному для каждого сетевого интерфейса.
ip netns add ns_eth0 ip netns add ns_eth1
-
Перемещение интерфейсов: Перемещаем каждый из интерфейсов в соответствующее пространство имен. Это позволяет нам отделить их друг от друга в сетевом контексте.
ip link set eth0 netns ns_eth0 ip link set eth1 netns ns_eth1
-
Назначение IP-адресов: Назначаем IP-адреса каждому интерфейсу в их новом изолированном пространстве.
ip netns exec ns_eth0 ip addr add dev eth0 192.168.1.1/24 ip netns exec ns_eth1 ip addr add dev eth1 192.168.1.2/24
-
Активация интерфейсов: Поднимаем интерфейсы, чтобы они могли взаимодействовать.
ip netns exec ns_eth0 ip link set eth0 up ip netns exec ns_eth1 ip link set eth1 up
-
Проверка соединения: Убедитесь, что интерфейсы могут отправлять пакеты друг другу, используя команду ping.
ip netns exec ns_eth0 ping 192.168.1.2 ip netns exec ns_eth1 ping 192.168.1.1
-
Запуск теста Iperf: Теперь вы можете запускать Iperf в контексте каждого пространства имен. Таким образом, обеспечивается прохождение трафика именно через необходимые физические интерфейсы.
ip netns exec ns_eth0 iperf3 -s ip netns exec ns_eth1 iperf3 -c 192.168.1.1
-
Восстановление состояния: После тестирования вы можете вернуть систему в исходное состояние, удалив созданные пространства имен.
ip netns del ns_eth0 ip netns del ns_eth1
Этот подход обеспечивает реальную передачу данных через физические интерфейсы, исключая возможность использования loopback, что является критически важным для корректного измерения сетевой производительности в вашем сценарии.
Заключение
Использование сетевых пространств имен является мощной техникой в Linux, позволяющей экспериментировать и тестировать сети в пределах одного устройства с высокой степенью изоляции. Это подход может быть полезен не только для тестирования сетевой производительности, но и для изоляции различных приложений и сервисов для повышения безопасности или в целях разработки и отладки. Ваша задача — убедиться, что весь трафик действительно проходит через физические интерфейсы, и данная методика решает эту проблему, обеспечивая точность и корректность результатов.