Aby to zrobić, możesz użyć tc
samego z u32
filtrami lub w połączeniu ze znakowaniem iptables (być może bardziej proste, jeśli nie chcesz nauczyć się składni filtrów złożonych). W następnym poście szczegółowo opiszę poprzednie rozwiązanie.
Symulowanie konfiguracji
Jako przykład rozważmy A, B, C i D z uruchomionymi wirtualnymi interfejsami 10 Mbit / s .
Zasadniczo chcesz:
- A <==> B: kształtowanie 9 Mbit / s dla wyjścia
- A <==> C: kształtowanie 8 Mbit / s dla wyjścia
Aby to zasymulować, utworzę 4 sieciowe przestrzenie nazw i wirtualne interfejsy Ethernet podłączone do mostka.
Oczywiście w twoim przypadku będziesz pracować z prawdziwymi kartami sieciowymi, a most będzie twoją bramą lub przełącznikiem w zależności od infrastruktury.
W mojej symulacji będziemy mieli następującą konfigurację w sieci 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
Po pierwsze, fazę konfiguracji, abyś mógł zrozumieć, z czego jest wykonana, pomiń ją, jeśli nie jesteś z nią zaznajomiony, nic wielkiego. Musisz jednak wiedzieć, że polecenie ip netns exec <namespace> <command>
pozwala wykonać polecenie w sieciowej przestrzeni nazw (tj. W jednym z pól poprzedniego losowania). Zostanie to wykorzystane również w następnej sekcji.
# 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
W tym momencie mamy opisaną wcześniej konfigurację.
Kształtowanie ruchu
Czas przejść do kontroli ruchu, aby uzyskać to, czego chcesz. tc
Narzędzie pozwala na dodanie dyscyplin kolejkowania:
- Dla wyjścia: gdy jądro musi wysłać pakiety i przed uzyskaniem dostępu do sterownika karty sieciowej.
- Do wejścia: po uzyskaniu dostępu do sterownika karty sieciowej i przed uruchomieniem procedur jądra dla odebranych pakietów.
Zawiera 3 pojęcia: qdisc , klasy i filtry . Pojęć tych można używać do konfigurowania zarządzania złożonym przepływem pakietów i ustalania priorytetów ruchu na podstawie dowolnych kryteriów / kryteriów.
W skrócie :
- Qdisc są strukturami, w których pakiety będą zwykle kolejkowane / usuwane z kolejki.
- Klasy są pojemnikami na qdisc działającymi z określonymi zachowaniami.
- Filtry to sposoby kierowania pakietów między klasami, wiele z nich można zdefiniować w tym samym punkcie wejścia z priorytetami podczas przetwarzania.
Wszystko to zwykle działa jako drzewo, w którym liście są qdisc, a klasy są węzłami. Katalog główny drzewa lub poddrzewa zostanie zadeklarowany jako, <id>:
a węzły podrzędne zostaną zadeklarowane jako <parent_id>:<children_id>
. Pamiętaj o tej składni.
W twoim przypadku weźmy A i wyrenderuj drzewo, które chcesz skonfigurować tc
:
1:
|
|
|
1:1
/ | \
/ | \
/ | \
1:10 1:20 1:30
| | |
| | |
:10 :20 :30
Objaśnienie:
1:
jest qdisc root dołączony do urządzenia vethA, zostanie on wzięty jawnie jak w htb
przypadku Hierarchy Token Bucket (domyślna qdisc urządzenia to pfifo
lub pfifo_fast
zależy od systemu operacyjnego). Jest to szczególnie odpowiednie do zarządzania pasmem. Pakiety niepasujące do filtrów zdefiniowanych na tym poziomie trafią do 1:30
klasy.
1:1
będzie htb
klasą ograniczającą cały ruch urządzenia do 10 Mbit / s.
1:10
będzie htb
klasą ograniczającą ruch wyjściowy do 9 Mbit / s (90% z 10 Mbit / s).
1:20
będzie htb
klasą ograniczającą ruch wyjściowy do 8 Mbit / s (80% z 10 Mbit / s).
1:30
będzie htb
klasą ograniczającą ruch do 10 Mbit / s (awaryjne).
:10, :20, :30
są sfq
qdisc dla Kolejkowania Stochastic Fairness. Innymi słowy, te qdisc zapewnią uczciwość w planowaniu transmisji w oparciu o przepływy.
Całą tę konfigurację wykonują następujące polecenia:
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
Ostatnią rzeczą, której potrzebujemy, jest dodanie filtrów, aby pakiety IP z docelowym adresem IP równym B trafiły do 1:10
klasy, a pakiety IP z docelowym adresem IP równym C trafiły do 1:20
klasy:
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
Teraz, gdy wpadłeś na ten pomysł, musisz dodać podobne tc
reguły do B i C, aby nadać kształt również transmisjom w kierunku A z tych platform.
Testowanie
Teraz przetestujmy to. W tym celu jestem osobiście przyzwyczajony do gry iperf
, po prostu składa się z pojedynczego pliku binarnego, który można uruchomić jako klient lub serwer i automatycznie wysyła jak najwięcej ruchu między dwoma hostami.
Pomiędzy A i 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
Otrzymujemy nasz limit przepustowości 9 Mbit / s .
Pomiędzy A i 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
Otrzymujemy nasz limit przepustowości 8 Mbit / s .
Pomiędzy A i 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
Tutaj mamy osiągnięty wirtualny interfejs z pełną prędkością 10 Mbit / s .
Zauważ, że seria pierwszego pomiaru każdego przebiegu może być lepiej obsługiwana w htb
klasach poprzez dostosowanie odpowiedniego parametru.
Sprzątanie
Usuwać :
- Filtr priorytetu 1 na
1:
: tc filter del dev vethA parent 1: prio 1 u32
.
- Wszystkie filtry na
1:
: tc filter del dev vethA parent 1:
.
- Klasa
1:20
i jej dzieci: tc class del dev vethA parent 1:1 classid
1:20
.
- Całe drzewo:
tc qdisc del dev vethA
.
Aby wyczyścić zestaw symulacji:
# 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