QoS, klasifikace provozu

Lukáš Holčík, xholcik1@fi.muni.cz

Obsah

1. Co je QoS?

1.1. Úvod

Na poli přepínaných sítí představuje pojem QoS (Quality of Service, kvalita služby) pravděpododobnost naplnění přenosového kontraktu, neformálně pak pravděpodobnost, že paket úspěšně překoná trasu mezi dvěma body na síti. Když vznikl internet, nebyla tu žádná vnímaná potřeba po QoS, takže internet fungoval na principu "best effort". Po síti proplouvaly pakety s nevyužitými bity určujícími typ služby a prioritu. Nicméně paketům jdoucím po síti se může na cestě přihodit mnoho nepěkného. Z hlediska vysílajícího a přijímajícího může dojít k následujícím poruchám:

  1. ztracené pakety - router může selhat při doručování paketu v případě, že jeho buffery jsou naplněné. Přijímající aplikace musí požádat o opětovné vyslání informace, což může představovat vážná zpoždění v celkovém přenosu
  2. zpoždení - paketu může trvat poměrně dlouhou dobu než dosáhne svého cíle vlivem čekání ve frontách, případně zvolením méně výhodně trasy, aby se zabránilo zahlcení. Na druhou stranu může jít velmi rychlou, přímou cestou, takže zpoždění je velmi nepředpovídatelné.
  3. rozptyl - pakety přicházejí do cíle s různým zpožděním. Tato variace ve zpoždění je označována jako rozptyl a vážně ovlivňuje kvalitu přenosu např. multimédií
  4. doručení mimo pořadí - když skupina paketů proudí Internetem, kařdý z nich může být směrován jinou cestou, což pro ně představuje různé zpoždění. Výsledkem toho je, že pakety mohou dorazit v jiném pořadí, než byly vyslány. Tento problém vyžaduje existenci protokolů, které v cíli seřadí pakety podle pořadí, ve kterém byly vyslány.
  5. jiné chyby - např. chyba v paketu, apod.

Aplikace vyžadující QoS:

  1. streamovaná multimédia - vyžadují garantovanou propustnost
  2. VoIP - telefonování přes IP vyžaduje přísné limity na zpoždění a rozptyl
  3. kritické aplikace vyžadující bezpečnost - např. vzdálená chirurgie

Míra QoS je obvykle stanovena na základě smlouvy mezi poskytovatelem a zákazníkem označované jako SLA (Service Level Agreement), která specifikuje parametry vybraným protokolům. Mezi hlavní parametry QoS patří míra propustnosti a zpoždění.

1.2. Modely QoS

1.2.1. IntServ (Integrované služby)

Nepříliš populární model vyžadující záruky po celé trase mezi zdrojovou a cílovou stanicí. Problém je v tom, že každý router musí vést záznam o velkém množství rezervací, čímž se model stává nepoužitelným v prostředí velikosti Internetu. Rezervace jsou řízeny protokolem RSVP (Resource reSerVation Protocol).

1.2.2. DiffServ (Diferencované služby)

Rozšířenější model QoS využívá namísto rezervačního prokokolu pole TOS (Type Of Service) IP paketu. TOS nastavují paketům hraniční směrovače a vnitřní uzly je pak podle toho směrují. V linuxu je vestavěná podpora od řady 2.4.

2. Fronty paketů (Queueing discipline = qdisc)

Fronty slouží jako algortimus k určování, která data se mají odeslat první. Je důležité s uvědomit, že můžeme ovlivnit pouze data, která vysíláme. Díky způsobem, jakým funguje Internet, nemáme žádnou přímou kontrolu nad tím, co k nám proudí za data.

Příchozí provoz na síťovém rozhraní se označuje ingress a jeho tvarování (přeuspořádání, zpomalení, či zahození paketu) se nazývá policing. V Linuxu lze na ingress uplatnit pouze omezení šířky pásma pomocí zahazování paketu. Žádné pokročilé způsoby klasifikace provozu nelze použít. Odchozí provoz se označuje jako egress a jeho tvarování se nazývá shaping. Pomocí shapingu lze pakety zpomalovat, preuspořádávat i zahazovat za použití různě složitých algoritmů.

2.1. Classless qdisc

Classless fronty jsou ty, které příjímají data a zpožďují, zahazují nebo mění pořadí paketů. Používají se na shapování provozu pro rozhraní jako celek. Narozdíl od classful nemohou obsahovat další qdisc.

2.2. Classful qdisc

Když provoz dosáhne classful qdisc, je poslán na nějakou z vnořených tříd - musí být "zatříděn". K určení, co se má s roztříděnými pakety dělat, slouží tzv. filtry. Filtry jsou volány prostřednictvím qdisc.

                     1:   root qdisc
                      |
                     1:1    child class
                   /  |  \
                  /   |   \
                 /    |    \
                /     |     \
              1:10  1:11  1:12   child classes
               |      |     | 
               |     11:    |    leaf class
               |            | 
               10:         12:   qdisc
              /   \       /   \
           10:1  10:2   12:1  12:2   leaf classes

Filtry napojené k příslušnému qdiscu vrací o paketu "rozhodnutí", které je použito k zařazení paketu do jedné z vnořených tříd. Každá podtřída může znova zkusit připojený filtr. Pokud žádný není k dispozici, zařadí paket do qdisc, který je v ní obsažen. Kromě toho, že classful qdisc obsahují další qdisc, většina z nich také provádí shaping, což je dobré k omezování propustnosti a plánování (scheduling, např. pomocí SFQ).

3. Jak na to v Linuxu

3.1 Instalace

Pro naše účely budeme potřebovat:

3.1.1. Podporu QoS v jádře

[Networking/Networking options/QoS and|or fair queueing/*]

3.1.2. tc

Program tc je součástí balíku iproute (na některých distribucích iproute2). Debian:

# apt-get install iproute

3.1.3. IMQ + linux

# cd /usr/src/
# wget http://www.linuximq.net/patchs/linux-2.6.16-imq2.diff
# cd linux-2.6.16
# patch -Np1 -i ../linux-2.6.16-imq2.diff
# make menuconfig
...

důležité je

CONFIG_IP_NF_TARGET_IMQ=m  [Network device support/IMQ (intermediate queueing device) support]
CONFIG_IMQ=m  [Networking options/IP: Netfilter Configuration/IMQ target support]

# make ...
    
    

3.1.4. IMQ + iptables

Kvůli podpoře IMQ je potřeba patchovat i iptables patchem z linuximq.net/patches

$ wget http://www.netfilter.org/projects/iptables/files/iptables-1.3.5.tar.bz2
$ wget http://www.linuximq.net/patchs/iptables-1.3.0-imq1.diff
$ tar jxf iptables-1.3.5.tar.bz2
$ cd iptables-1.3.5
$ patch -Np1 -i ../iptables-1.3.0-imq1.diff
$ make PREFIX=/opt/iptables-imq KERNEL_DIR=/usr/src/linux-'uname -r' install
# make PREFIX=/opt/iptables-imq KERNEL_DIR=/usr/src/linux-'uname -r' install

3.2. Shaping (HTB)

K nastavení shapingu slouží program tc(1).

Popisy parametrů k jednotlivým algoritmům se nacházejí v manuálových stránkách tc-htb(8), tc-pfifo(8), apod..
tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 11
tc class add dev eth0 parent 1:0 classid 1:1 rate 128kbit

tc class add dev eth0 parent 1:1 classid 1:11 rate 64kbit ceil 128kbit
tc class add dev eth0 parent 1:1 classid 1:12 rate 32kbit

tc qdisc add dev eth0 parent 1:11 handle 11:0 sfq perturb 5
tc qdisc add dev eth0 parent 1:12 handle 12:0 sfq perturb 10

3.2.1. Klasifikace

Máme dvě možnosti, jak určit, které pakety se mají přiřadit které třídě:
  1. Pomocí iptables označíme paket značkou (zde '1') a tc filtr si jej podle toho zařadí do určené třídy (zde 1:10).
    iptables -t mangle -A POSTROUTING -d 192.168.0.1 -j MARK --set-mark 1
    tc filter add dev eth0 parent 1:0 protocol ip handle 1 fw flowid 1:10
  2. Určení pomocí tc filtru:
    tc filter add dev eth1 protocol ip parent 1:0 u32 match ip sport 22 0xffff flowid 1:10
    tc filter add dev eth1 protocol ip parent 1:0 u32 match ip dport 22 0xffff flowid 1:10
    Pomocí těchto dvou pravidel jsme řekli, že pakety s cílovým portem 22 patří do třídy 1:10.

Popis příkazu:

tc qdisc add dev eth1 handle 1: root cbq bandwidth 100Mbit avpkt 1000 mpu 64
------------ -------- --------- ---- --- -----------------------------------
     1          2         3       4   5                   6
  1. Tato část říká, že vytváříme qdisc.
  2. Zařízení, ke kterému ho přidáváme - nutný parametr.
  3. Označení (handle), které mu přiřadíme. Když ho nespecifikujeme, vygeneruje se automaticky. Číslo minor (od dvojtečky vpravo) musí být nula.
  4. Znamená přiřaď ho ke "kořenovému uzlu" zařízení. Jenom jeden qdisc může být v kořenu. Každý qdisc může být být rodičem pouze jedné další třídy (class).
  5. Toto pole specifikuje qdisc, který připojíme na tento handle.
  6. Parametry, kterými inicializujeme třídu :0, která je automaticky vytvořena, když vznikne tento qdisc.

Další užitečné příkazy:

[root@icharyd:~]# tc qdisc show
qdisc htb 1: dev eth0 r2q 10 default 30 direct_packets_stat 0
qdisc sfq 10: dev eth0 parent 1:10 limit 128p quantum 1514b perturb 10sec
qdisc sfq 20: dev eth0 parent 1:20 limit 128p quantum 1514b perturb 10sec
qdisc sfq 30: dev eth0 parent 1:30 limit 128p quantum 1514b perturb 10sec

[root@icharyd:~]# tc class show dev eth0
class htb 1:1 root rate 6000Kbit ceil 6000Kbit burst 15Kb cburst 4599b
class htb 1:10 parent 1:1 leaf 10: prio 0 rate 5000Kbit ceil 5000Kbit burst 15Kb cburst 4Kb
class htb 1:20 parent 1:1 leaf 20: prio 0 rate 3000Kbit ceil 6000Kbit burst 15Kb cburst 4599b
class htb 1:30 parent 1:1 leaf 30: prio 0 rate 1000bit ceil 6000Kbit burst 15Kb cburst 4599b

[root@icharyd:~]# tc filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:30
  match 00000050/0000ffff at 20

3.3. Policing (IMQ)

modprobe IMQ

# Musíme přesměrovat příchozí provoz na naše virtuální IMQ zařízení ješte
# před jeho jakýmkoliv zpracováním.

iptables -t mangle -A PREROUTING -j IMQ

# Nyní můžeme vytvořit strom stejně jako v předchozím případě.

tc qdisc del dev imq0 root
tc class add ...
    

4. Rozdělení zátěže na více rozhraní

Dosáhneme toho pomocí metody zv. bonding, neboli sloučení více fyzických rozhraní do jednoho logického, která má musí mít podporu v jádře [Device drivers/Network device support/Bonding driver support]. Příklad zprovoznění:

[root@real-server root]# modprobe bonding
[root@real-server root]# ip addr add 192.168.100.33/24 brd + dev bond0
[root@real-server root]# ip link set dev bond0 up
[root@real-server root]# ifenslave  bond0 eth2 eth3
master has no hw address assigned; getting one from slave!
The interface eth2 is up, shutting it down it to enslave it.
The interface eth3 is up, shutting it down it to enslave it.
[root@real-server root]# ifenslave  bond0 eth2 eth3
[root@real-server root]# cat /proc/net/bond0/info
Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth2
MII Status: up
Link Failure Count: 0

Slave Interface: eth3
MII Status: up
Link Failure Count: 0

Vyčerpávající dokumentaci k této technice najdete v dokumentaci kernelu ($kernel_src/Documentation/networking/bonding.txt).

5. Nástroje k měření

K měření průtoku dat můžeme použít program iptraf(http://cebu.mozcom.com/riker/iptraf/). Jedná se o intuitivní ncurses program. Instalace na Debianu:

# apt-get install iptraf

6. Prameny