Network problem emulation with Iptables and Iproute2
Однажды мне понадобилось в Zabbix сделать мониторинг потери пакетов между мастером и репликами (репликация плохо себя чувствует если канал не очень хороший). Для этого, в Zabbix есть встроенный параметр icmppingloss, на удаленный хост отправляется серия ICMP пакетов и результат фиксируется в системе мониторинга. И вот параметр добавлен, триггер настроен. Казалось бы задача выполена, однако как говорится "Доверяй, но проверяй". Осталось проверить что триггер сработает когда потери действительно будут. Итак, как сэмулировать потерю пакетов? Об этом, да и не только, пойдет речь под катом.Первая мысль которая пришла мне в голову это использовать iptables. И правда, недолгий поиск привел меня к модулю statistic - если вкратце, то этот модуль обрабатывает пакеты привнося в процесс некоторую статистическую вероятность. Вобщем задача была решена с помощью правила
или
Как видно тут есть 2 варианта: --mode random --probability 0.1 - означает что пакет будет выбран случайно, c вероятностью 10%. И --mode nth --every 10 - обрабатывать каждый десятый пакет. Таким способом я добился потери пакетов около 10%, триггер сработал, все замечательно. На этом вроде бы можно и остановиться, но совершенно случайно я узнал о такой функциональности как Network Emulator из ядерной подсистемы Network QoS. Причем возможности NetEm гораздо шире чем у модуля statistic:
- задержка (delay) - добавление указанной задержки к отправляемым пакетам на указанном интерфейсе;
- распределение (distribution) - позволяет указать вариант распределения задержки;
- сброс (drop) - позволяет указать потерю пакетов;
- повреждение (corrupt) - определяет возможность повреждения пакетов;
- дублирование (duplicate) - позволяет определить дублирование пакетов перед тем как они будут поставлены в очередь;
- переупорядочивание (reorder) - определяет переупорядочивание пакетов (используется совместно с задержкой);
- лимитирование (limit) - ограничивает эффект выше указанных опций на указанное число пакетов.
# grep NETEM /boot/config-$(uname -r)
CONFIG_NET_SCH_NETEM=m
Как видно из вывода поддержка в виде модуля, поэтому подгружаем его. Также нам понадобится утилита tc из пакета iproute2.
# modprobe sch_netem
Если же, ничего нету, то необходимо пересобрать ядро. Кто знаком с конфигурированием и сборкой ядра - небольшая подсказка, Network emulator находится здесь:
Networking -->
Networking Options -->
QoS and/or fair queuing -->
Network emulator
Кто незнаком со сборкой ядра, ищите статьи по сборке ядра в документации к вашему дистрибутиву.
Когда все готово, можно приступать. Рекомендую открыть вторую сессию в которой запустить ping до какого-либо узла в локальной сети. Таким образом вносимые эмуляции будут наблюдаться достаточно четко. Для экспериментов нам понадобится утилита tc из пакета iproute2. Полный синтаксис выглядит следующим образом:
ACTION := [ add | change | delete ]
OPTIONS := [ LIMIT ] [ DELAY ] [ DROP ] [ CORRUPT ] [ DUPLICATION ] [ REORDER ]
LIMIT := limit packets
DELAY := delay TIME [ JITTER [ CORRELATION ]]] [ distribution { uniform | normal | pareto | paretonormal } ]
DROP := drop PERCENT [ CORRELATION ]
CORRUPT := corrupt PERCENT [ CORRELATION ]]
DUPLICATION := duplicate PERCENT [ CORRELATION ]]
REORDER := reorder PERCENT [ CORRELATION ] [ gap DISTANCE ]
1) Задержка пакетов.
Добавляем к отправке пакетов задержку в 100ms:
Здесь мы указываем джиттер и таким образом к уже имеющейся задержке в 100ms и добавляем некоторое отклонение в +/- 10ms.
Теперь добавляем корреляцию, таким образом задержка при отправке слеудющего пакета будет зависеть от задержки предыдущего пакета.
2) Распределение задержки.
В предыдущих примерах мы получали более-менее равномерное распределение задержек на все количество отправленных пакетов. Однако в настоящем мире, сетевые задержки совсем неравномерны. Для получения более реалистичной картины используется распределение (по-умолчанию, если не указывать распределение явно, то используется normal). В примере ниже мы указываем распределение pareto, также доступны normal и paretonormal - задержка будет расчитываться по математическим формулам. Кроме того можно создать свои таблицы распределения. На мой взгляд, это довольно специфичный кейс применения, но вдруг кто-то заинтересуется.
3) Потеря пакетов. С этого все и началось, да...
Указывает потерю пакетов в размере 20%.
Дополнительно можно указать корреляцию, в таком случае, генератор случайных чисел будет менее случайным и можно будет наблюдать всплески в потерях:
4) Повреждение пакетов.
Намеренное повреждение пакетов, каким образом оно делается? С указанной вероятностью, в случайное место внутри случайно выбранного пакета, записывается некорректный бит. В итоге, контрольная сумма не сходится - пакет отбрасывается. Также как и в случае потерь, можно указать корреляцию для формирования всплесков.
5) Дублирование пакетов.
Дублирование пакетов определяется таким же образом как и потеря либо коррупция пакетов. И конечно же можно указать и корреляцию.
6) Переупорядочивание пакетов
В следующем примере 30% пакетов будут отправлены сразу же, остальные будут задержаны на 100ms.
В примере ниже, первые 4 пакета (gap - 1) будут задержаны на 100ms, последующие пакеты
будут отправлены немедленно с вероятностью 25% (+корреляция 50%) или наоборот задержаны с вероятностью 75%. Как только пакет будет переупорядочен, итерация повторяется и следующие 4 пакета задерживаются,остальные отправляются немедленно либо задерживаются с указанной вероятностью.
Кому лень заморачиваться с этим делом, есть небольшой демо-ролик
Вот такие дела. На главную "Virtualizing Linux"
Комментариев нет:
Отправить комментарий