Моделюйте повільний зв'язок між двома серверними машинами ubuntu


9

Я хочу імітувати такий сценарій: враховуючи, що у мене є 4 серверні машини ubuntu A, B, C і D. Я хочу зменшити пропускну здатність мережі на 20% між машиною A і машиною C і на 10% між A і B. Як це зробити зробіть це, використовуючи інструменти мережевого моделювання / дроселювання?


iptables можуть мати можливість дроселювання. Я ніколи його не використовував, але варто заглянути.
Майкл Мартінес

@MichaelMartinez Ні, це не так. tcробить, коли використовується з маркуванням iptables.
Ксав'є Лукас

@XavierLucas корисно знати!
Майкл Мартінес

Відповіді:


15

Для цього ви можете використовувати tcокремо з u32фільтрами або поєднувати їх із позначенням iptables (можливо, простіше, якщо ви не хочете вивчати синтаксис складних фільтрів). Я розповім у наступному дописі про колишнє рішення.


Моделювання налаштувань

Як приклад, розглянемо A, B, C і D з віртуальними інтерфейсами 10 Мбіт / с .

Ви в основному хочете:

  • A <==> B: 9 Мбіт / с формуючи для виходу
  • A <==> C: 8 Мбіт / с, формуючи для виходу

Для того, щоб імітувати це, я створити 4 простори мережі імен та віртуальний інтерфейс Ethernet, підключений до мосту.

Звичайно, у вашому випадку ви будете працювати з справжніми NIC, і міст буде вашим шлюзом або комутатором залежно від вашої інфраструктури.

Отже, в моєму моделюванні у нас буде така установка в мережі 10.0.0.0/24:

                                  10.0.0.254            

                                  +-------+                     
                                  |       |                     
                                  |  br0  |                     
                                  |       |                   
                                  +---+---+                     
                                      |                         
                                      | veth{A..D}.peer        
                                      |                      
                  +------------+------+-----+------------+     
                  |            |            |            |      
            vethA |      vethB |      vethC |      vethD |      
              +---+---+    +---+---+    +---+---+    +---+---+  
              |       |    |       |    |       |    |       |   
              |   A   |    |   B   |    |   C   |    |   D   |   
              |       |    |       |    |       |    |       |  
              +-------+    +-------+    +-------+    +-------+    

              10.0.0.1      10.0.0.2     10.0.0.3     10.0.0.4           

По-перше, фаза налаштування, щоб ви могли зрозуміти, з чого вона виготовлена, пропустіть її, якщо ви не знайомі з нею, нічого страшного. Однак ви повинні знати, що команда ip netns exec <namespace> <command>дозволяє виконувати команду в мережевому просторі імен (тобто в одному з вікон попереднього малювання). Це буде використано і в наступному розділі.

# Create the bridge
ip link add br0 type bridge

# Create network namespaces and veth interfaces and plug them into the bridge
for host in {A..D} ; do 
    ip link netns add ${host}
    ip link add veth${host} type veth peer name veth${host}.peer
    ip link set dev veth${host}.peer master br0
    ip link set dev veth${host} netns ${host}
    ip netns exec ${host} ip link set veth${host} up
done

# Assign IPs
ip addr add 10.0.0.254/24 dev br0
ip netns exec A ip addr add 10.0.0.1/24 dev vethA
ip netns exec B ip addr add 10.0.0.2/24 dev vethB
ip netns exec C ip addr add 10.0.0.3/24 dev vethC
ip netns exec D ip addr add 10.0.0.4/24 dev vethD

Таким чином, ми маємо описані раніше налаштування.


Формування трафіку

Настав час перейти до контролю руху, щоб отримати те, що ви хочете. tcІнструмент дозволяє додавати організації черг:

  • Для виходу: раз ядро ​​має надіслати пакети та перш ніж отримати доступ до драйвера NIC.
  • Для вступу: після доступу до драйвера NIC та перед запуском процедур ядра над отриманими пакетами.

Він поставляється з 3 поняттями: qdisc , класи та фільтри . Ці поняття можна використовувати для налаштування складного управління потоком пакетів та пріоритетного трафіку на основі будь-якого критерію / критеріїв, які ви хочете.

Коротко :

  • Qdiscs - це структури, в яких пакети будуть заздалегідь залучатися / відмінятися.
  • Заняття є контейнерами для qdiscs, що діють із певною поведінкою.
  • Фільтри - це способи маршрутизації пакетів між класами, декілька з них можна визначити в одній точці входу з пріоритетами під час обробки.

Все це зазвичай працює як дерево, де листя є qdiscs, а класи - вузлами. Корінь дерева або піддерева буде оголошено як, <id>:а дочірні вузли будуть оголошені як <parent_id>:<children_id>. Майте на увазі цей синтаксис.

Для вашого випадку давайте візьмемо A і зробимо дерево, яке ви хотіли б встановити tc:

                                     1:
                                      |
                                      |
                                      |
                                     1:1
                                   /  |  \
                                  /   |   \
                                 /    |    \
                               1:10  1:20  1:30
                                |     |     |
                                |     |     |
                               :10   :20   :30

Пояснення:

  • 1:це кореневий qdisc, приєднаний до пристрою vethA, він буде сприйматися явно, як htbдля ієрархічного токена Bucket (qdisc пристрою за замовчуванням є pfifoабо pfifo_fastзалежно від ОС). Це спеціально підходить для управління пропускною здатністю. Пакети, які не відповідають фільтрам, визначеним на цьому рівні, перейдуть до 1:30класу.
  • 1:1буде htbкласом, що обмежує весь трафік пристрою до 10 Мбіт / с.
  • 1:10буде htbкласом, що обмежує вихідний трафік до 9 Мбіт / с (90% від 10 Мбіт / с).
  • 1:20буде htbкласом, що обмежує вихідний трафік до 8 Мбіт / с (80% від 10 Мбіт / с).
  • 1:30буде htbкласом, що обмежує трафік до 10 Мбіт / с (резервний).
  • :10, :20, :30є sfqдисципліною стохастичною Fairness черзі. Іншими словами, ці qdiscs забезпечать справедливість у плануванні передач на основі потоків.

Все це налаштовано такими командами:

ip netns exec A tc qdisc add dev vethA root handle 1: htb default 30
ip netns exec A tc class add dev vethA parent 1: classid 1:1 htb rate 10mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:10 htb rate 9mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:20 htb rate 8mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:30 htb rate 10mbit burst 15k
ip netns exec A tc qdsic add dev vethA parent 1:10 handle 10: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:20 handle 20: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:30 handle 30: sfq perturb 10

Останнє, що нам потрібно - це додавання фільтрів, щоб IP-пакети з IP-адресою призначення дорівнювали B, переходили до 1:10класу, а IP-пакети з IP-адресою призначення дорівнювали C 1:20:

ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 1 u32 match ip dst 10.0.0.2/32 flowid 1:10
ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 2 u32 match ip dst 10.0.0.3/32 flowid 1:20

Тепер, коли ви зрозумієте, вам потрібно буде додати подібні tcправила до B і C, щоб передачі в бік A з цих установок також були сформовані.


Тестування

Тепер перевіримо це. Для цього я особисто використовувався iperf, він просто складається з єдиного бінарного файлу, який можна запускати як клієнт або сервер і автоматично надсилатиме якомога більше трафіку між обома хостами.

Між A і B:

 $ ip netns exec B iperf -s -p 8001
  ...
 $ ip netns exec A iperf -c 10.0.0.2 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.2, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58191 connected with 10.0.0.2 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  2.0- 4.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  4.0- 6.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  6.0- 8.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  8.0-10.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  0.0-10.1 sec  10.8 MBytes  8.91 Mbits/sec

Ми отримуємо обмеження пропускної здатності 9 Мбіт / с .

Між A і C:

$ ip netns exec C iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.3 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.3, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58522 connected with 10.0.0.3 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  2.0- 4.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  4.0- 6.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  6.0- 8.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  8.0-10.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  0.0-10.1 sec  9.62 MBytes  7.98 Mbits/sec

Ми отримуємо обмеження пропускної здатності 8 Мбіт / с .

Між A і D:

$ ip netns exec D iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.4 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.4, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 40614 connected with 10.0.0.4 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.62 MBytes  11.0 Mbits/sec
[  5]  2.0- 4.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  4.0- 6.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  6.0- 8.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  8.0-10.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  0.0-10.2 sec  12.0 MBytes  9.89 Mbits/sec

Тут у нас досягнуто віртуального інтерфейсу повної швидкості 10 Мбіт / с .

Зауважте, що вибух першої міри кожного запуску можна краще обробити в htbкласах, скоригувавши адекватний параметр.


Очищення

Видалити :

  • Фільтр пріоритету 1 на 1:: tc filter del dev vethA parent 1: prio 1 u32.
  • Всі фільтри на 1:: tc filter del dev vethA parent 1:.
  • Клас 1:20та його діти : tc class del dev vethA parent 1:1 classid 1:20.
  • Ціле дерево: tc qdisc del dev vethA.

Щоб очистити набір моделювання:

# Remove veth pairs and network namespaces
for host in {A..D} ; do
    ip link del dev veth${host}.peer
    ip netns del ${host}
done

# Remove the bridge
ip link del dev br0

1
Дякую за чудову відповідь. Якщо можливо, можете, будь ласка, додати команди для видалення фільтрів? про всяк випадок, коли хтось захоче відкатати цю установку безпечно після моделювання.
Yehia Elshater

1
@YahiaZakaria Я щойно додав цю інформацію в останній частині свого допису.
Ксав'є Лукас

0

Ubuntu мають IPFW, перенесений з FreeBSD, а IPFW мають DUMMYNET, що дозволяє керувати різними мережевими параметрами - пропускною здатністю, затримкою, швидкістю втрати пакету тощо.


0

Найкраще використовувати інструменти tc із тепер інтегрованим (не менше ніж на сервері Ubuntu) модулем netem. Ви можете знайти більше інформації в цій статті від Stackoverflow .


Нетем - це rtt і емуляція заторів, а не пропускна здатність.
Ксав'є Лукас

1
@XavierLucas, ви праві, для пропускної здатності вам просто потрібен tc, навіть нетем.
Люк Степнєвський

0

Trickle добре працює.

Це обговорення показує деякі обмеження: /unix/109973/how-to-change-speed-limit-of-running-trickle-in substance


Trickle використовується для імітації пропускної здатності мережі для певної програми. Очевидно, що ОП шукає рішення в межах сфери прийому.
Ксав'є Лукас

Trickled може використовуватися для імітації групи з'єднань (не лише одного з'єднання). Дійсно, питання можна інтерпретувати як "всі з'єднання" хост-хост ".
Матвій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.