Netem – как задерживать пакеты, отправляемые на/получаемые от некоторого хоста.

Вопрос или проблема

Допустим, у нас есть хост A и хост B. Мы хотели бы использовать netem, чтобы смоделировать следующий сценарий: B отправляет пакеты на A с некоторой задержкой.
Как это сделать с помощью netem в двух сценариях:
(1) Запуск netem на хосте A
(2) Запуск netem на хосте B.

Есть идеи?

Существует несколько хороших источников, как ввести задержку для входящих и исходящих пакетов. Эта вики-страница NetEm содержит много информации. Смотрите раздел “1.1 Эмуляция задержек в сети широкого радиуса” для задержки исходящих пакетов и “2.3 Как я могу использовать netem для входящего трафика?” для входящих пакетов. Я попробовал это в своей настройке и не столкнулся с проблемами.

Базовая задержка:

# netperf -H $my_ip -t TCP_RR -P 0 -- -r 64 -o RT_LATENCY
21.800

100мс задержка только на стороне клиента (B):

# tc qdisc add dev $my_interface root netem delay 100ms

Результат:

# netperf -H $my_ip -t TCP_RR -P 0 -- -r 64 -o RT_LATENCY
102184.355

100мс задержка только на стороне клиента (A):

Сначала создайте псевдо-устройство Intermediate Functional Block IFB (можно также использовать ethernet bridge):

# modprobe ifb
# ip link add name ifb0 type ifb
# ip link set dev ifb0 up

Затем перенаправьте весь входящий трафик так, чтобы он сначала проходил через устройство IFB:

# tc qdisc add dev $my_interface ingress
# tc filter add dev $my_interface parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

Теперь просто добавьте задержку к исходящему трафику устройства IFB, который теперь является входящим трафиком для my_interface:

# tc qdisc add dev ifb0 root netem delay 100ms

Результат:

# netperf -H $my_ip -t TCP_RR -P 0 -- -r 64 -o RT_LATENCY
154442.238

Применение обоих результатов в:

# netperf -H $my_ip -t TCP_RR -P 0 -- -r 64 -o RT_LATENCY
333803.282

Как вы можете видеть, задержка превышает добавленные 100мс (или 200мс в последнем примере) + базовую задержку. NetEm вызывает задержку в определенном месте в канале передачи, так что более длительное, чем ожидалось, время может быть побочным эффектом задержки.

Ответ или решение

Использование утилиты netem для эмуляции задержки в сетевом трафике является важной задачей, особенно в тех случаях, когда необходимо тестирование и оптимизация сетевых приложений в условиях, приближенных к реальным сетям с высокой задержкой. Вопрос о том, как настроить задержку между двумя хостами, A и B, с использованием netem, можно рассмотреть в двух основных сценариях: настройка на хосте A и на хосте B.

1. Теория

Netem (Network Emulation) — это мощный инструмент в Linux для эмуляции сетевых условий, включая задержки, потери пакетов и другие аномалии. Он позволяет сетевым администраторам и разработчикам симулировать различные условия широкополосных сетей, чтобы протестировать и оптимизировать производительность приложения перед его развертыванием в реальных условиях.

Основная концепция работы netem заключается в добавлении так называемых "qdisc" (сокращение от queue discipline) к сетевому интерфейсу. Это позволяет управлять очередью пакетов и добавлять различные эмуляторы поведения, такие как задержка, дрожание задержки, пропуск пакетов и т.д.

2. Пример реализации

Сценарий 1: Запуск netem на хосте A

Когда мы запускаем netem на хосте A для добавления задержки к трафику, приходящему от B, мы, по сути, управляем входящим трафиком. Для этого необходимо создать IFB (Intermediate Functional Block) интерфейс, который позволит перехватывать и модифицировать входящий трафик.

  1. Создание IFB интерфейса и настройка его работы:

    # Загрузка модуля ifb
    modprobe ifb
    
    # Создание устройства ifb0
    ip link add name ifb0 type ifb
    
    # Включение устройства
    ip link set dev ifb0 up
  2. Перенаправление входящего трафика на IFB:

    # Добавление правила ingress к основному интерфейсу
    tc qdisc add dev eth0 ingress
    
    # Настройка фильтрации и перенаправления трафика на ifb0
    tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
  3. Добавление задержки через netem к трафику, перенаправленному на IFB:

    # Добавление задержки 100ms
    tc qdisc add dev ifb0 root netem delay 100ms

Сценарий 2: Запуск netem на хосте B

Когда netem настроен на хосте B для управления исходящим трафиком к хосту A, конфигурация проще, поскольку нет необходимости в использовании IFB.

  1. Прямое добавление задержки к исходящему трафику:
    # Добавление задержки к отправляемым данным
    tc qdisc add dev eth0 root netem delay 100ms

3. Применение

Теперь рассмотрим, как эти сценарии будут влиять на реальную работу системы. Применение задержек может быть полезно для тестирования поведения приложений в условиях, имитирующих реальную сеть Интернет или VPN-канал. Это позволяет идентифицировать узкие места и предвидеть определенные проблемы, которые могут возникнуть при эксплуатации в более агрессивной сетевой среде.

Пример использования:

Допустим, наша задача состоит в том, чтобы протестировать работу веб-приложения между клиентским интерфейсом и сервером базы данных. Может случиться так, что именно задержка в сети станет критическим параметром для быстрой обработки клиентских запросов. Настройка netem на хосте, имитирующем клиентскую часть (например, хост B), позволит увидеть, как приложение реагирует на задержки, типичные для медленных WAN-сетей.

В то же время настройка задержки на стороне сервера (хост A) может помочь понять, как сервер справляется с обработкой большого количества задержанных запросов, а также выявить, оптимизированы ли алгоритмы под такие сценарии нагрузки.

Заключая, использование netem открывает возможности реалистичного моделирования сетевой среды, что значительно упрощает задачу оптимизации и адаптации сетевых приложений к различным условиям эксплуатации. Важно помнить, что netem — это всесторонний инструмент, и его использование требует понимания сетевой инфраструктуры и целей тестирования для достижения наилучших результатов.

Оцените материал
Добавить комментарий

Капча загружается...