Tc

A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
72. sor: 72. sor:
   
 
* Az egész nagy doboz a kernel
 
* Az egész nagy doboz a kernel
* Elvileg nincs bemeneti queue (azért meg lehet oldani)
+
* Ha a gépnek szól egy csomag akkor az felfele megy, ha nem, akkor jobbra
* Ha a gépnek szól egy csomag akkor az felfele megy, ha nem akkor jobbra
+
  +
==== A hierarchia ====
  +
  +
Minden interfacenek van egy kimeneti root qdisc-je, az alapértelmezésben pfifo_fast. Minden qdisc-hez és class-hez tartozik egy handle (kezelő), amivel a későbbi parancsoknál lehet hivatkozni az adott qdisc-re. Egy interfésznek a kimeneti qdisc-en kívűl lehet bemeneti qdisc-je is.
  +
  +
A handle-ök nevei 2 számból állnak <major>:<minor>. az osztályoknak a szülőivel azonos major azonosítóval kell rendelkezniük. A minor azonosítónak pedig egyedinek kell lennie az adott qdiscben és és annak osztályaiban.
  +
  +
==== A fa szerkezet ====
  +
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
  +
  +
  +
  +
=== CBQ ===
  +
A legrégebbi és talán a legkomplexebb qdisc és persze a legelterjedtebb is.
  +
  +
Ha nekiesünk, mint tót az annyának, akkor érdekes eredményt kaphatunk. Pl ha egy 10 Mbites forgalmat akarunk 1 Mbitre korlátozni, akkor a cbq-val könnyen azt is elérhetjük, hogy az idő 10%-ben teli a sávszélesség és 90%-ban meg üres, pedig nekünk nem ez kellene. Érdemes végig mazsolázni a paramétereket, hogy jól be tudjuk állítani.
  +
  +
Alapesetben kiszámolja, hogy mekkora legyen az atlagos idő, amikor nem ad (avgidle), hogy a sávszélesség a kivánt legyen, erre exponenciálisan súlyozott mozgó átlagot használ. Ebból tudja, hogy mikor kell adnia ami a csövön befér és meddig nem kell adnia. Egy túlterhelt linknek lehet akár negatív avgidle értéke is, akkor egyszerűen nem ad csomagot amig ismét el nem éri a kívánt értéket. Viszont egy alacsony kihasználtságú linken óriási burst-ök is kialakulhatnak.
  +
  +
==== CBQ paraméterek ====
  +
avpkt
  +
* Átlagos csomag hossz (byte-ban). Ez szükséseges a minidle kisámításához, ami a maxburstből van származtatva, de azt csomag ban mérik.
  +
  +
bandwidth
  +
* Az eszköz fizikai sávszélessége. Ez a az idle time kiszámításához szükséges.
  +
  +
cell
  +
* Ennyi idő alatt rakunk ki a vonalra egy csomagot. Ez adja a granularitást. Csomagméret alapján nőhet. Általában 8 az értéke, de 2 többszörösének kell lennie.
  +
  +
maxburst
  +
* A maxidle kiszámításához használják. Ha a maxidle és az avgidle közel azonos, akkor gyakran burst-ösödhet, mielött lekapcsolja az adást. Érdemes magasabbra állítani, így toreránsabb lesz a burst-ökhöz. A maxidle csak ezen a paraméteren keresztül állítható.
  +
  +
minburst
  +
* Mivel a CBQ túlterhelésnél hajlamos az eldugulásra, az lenne a jó, ha kiszámolnánk, hogy menny az idle time aztán küldenénk egy csomagot, majd pihennénk egy idle time-ni időt. De sajnos ez a kernel ütemezője miatt sem olyan egyszerű, hiszen neéhz kevesebb mint 10 ms-nél rövidebre ütemezni egy eseményt. Így mégis csak jobb, ha először sokat adunk és utána csak minburst-nyi csomagokat rakunk ki egyszerre, aztán megint pihenünk egy kicsit. A nagyobb minburst érték jobb forgalomformázáshoz vezet nagyobb időre vetítve, de ms-os felbontásnál nagyobb burst-öket okoz.
  +
  +
minidle
  +
* Ha az avgidle kisebb mint 0, akkor addig nem rakunk csomagot a vonalra, amig az avgidle nem lesz elég nagy egy csomag küldésére. Hogy megelőzzük a hirtelen burst-öket a link lekacsolása miatt, az avgidle-t visszaállítjuk a minidle-re, ha túl alacsonyra csökkenne. A megadott értéket negatív számként kell értelmezni, mikroszekundumban.
  +
  +
mpu
  +
* Minimum Packet Size. Szükséges az idle time pontosabb kiszámításához. Az ethernet, ha üres csomagot küldünk, akkor is kitömi 64byte-osra, mert különben nem lehetne érzékelni az üttközést.
  +
  +
rate
  +
* milyen időközönként hagyhatja el csomag az adott qdisc-et.
  +
  +
A CBQ prioritásokat is képes figyelembe venni. Az magasabb prioritásúakkal kezdni, és megy körbe.
  +
Nénány paraméter a súlyozott round rubin (WRR) processhez, ami a prioritásokat kérdezgeti le.
  +
  +
allot
  +
* Egyszerre ennyi adatot küldhet egy osztály. (Plusz infó a wight paraméternél.
  +
  +
prio
  +
* A CBQ is tud úgy vislekedni, mint a PRIO, előszőr a nagyobb prioritással rendelkező csomagokat küldi ki, majd utána a többit prioritási sorrenben. Addig nem küld ki alacsonyabb prioritású csomagot, amig van magasabb prioritású.
  +
  +
whight
  +
* A súlyozásban segíti a WRR-t. Minden osztály esélyt kap egy-egy körben. Ha van egy osztály, aminek jóval nagyobb a forgalma, akkor ez segíthet abban, hogy több adatot tudjon kiküldeni egy kör alatt, mint a többiek. A sőlytényezőket normalizálja, csak az arány a lényeg. A normalizált súlyt ezután megszorozza az allot paraméterrel ebből megkapja, hogy egy körben mennyi adatot küldhet ki az adott osztály.
  +
  +
Egy CBQ-n belül ugyan azon a major számon kell osztozniuk.
  +
  +
Pár paraméter a sávszélesség megosztáshoz és kölcsönkéréshez.
  +
  +
isolated/sharing
  +
* Az isolated a hozzá rendelt sávszélt nem osztja meg a testvér osztályaival. A sharing igen.
  +
  +
bounded/borrow
  +
* A bounded nem kér kölcsön, a borrow igen.
  +
  +
Viszont egy osztályon belüli gyermek osztályok már kérhetnek kölcsön egymástól.
  +
  +
Példa
  +
  +
  +
1: root qdisc
  +
|
  +
1:1 child class
  +
/ \
  +
/ \
  +
1:3 1:4 leaf classes
  +
| |
  +
30: 40: qdiscs
  +
(sfq) (sfq)
  +
  +
Van egy 100mbit-es NIC-ünk, a webservernek 5mbit sávot adunk, az smtp-nek pedig 3 mbit-et
  +
  +
# tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit \
  +
avpkt 1000 cell 8
  +
# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit \
  +
rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20 \
  +
avpkt 1000 bounded
  +
  +
Ezzel a két folyamhoz összesen 6 mbit sávot rendelünk.
  +
  +
# tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit \
  +
rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20 \
  +
avpkt 1000
  +
# tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit \
  +
rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20 \
  +
avpkt 1000
  +
  +
Itt pedig a fenti külön-külön sávot rendeljük a két folamhoz.
  +
  +
# tc qdisc add dev eth0 parent 1:3 handle 30: sfq
  +
# tc qdisc add dev eth0 parent 1:4 handle 40: sfq
  +
  +
Ezzel meghatározzuk a qdisc algoritmusát.
  +
  +
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  +
sport 80 0xffff flowid 1:3
  +
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  +
sport 25 0xffff flowid 1:4
  +
  +
Itt pedig azt határozzuk meg, hogy melyik folyamot melyik kezeljen.
  +
  +
A pfifo_fast a TOS bitek alapján osztályozza a csomagokat. Erre a CBQ-ban is van lehetőség. Erre a split és a defmap paraméterek szolgálnak. A split azt mondja meg, hogy melyik qdisc-ben alkalmazzuk ezt az osztályozást is, a defmap pedig, hogy mely TOS biteknek szükséges beállítva lenni, hogy a szabály érvényeslüljön a csomagra.

A lap 2006. november 24., 23:30-kori változata

Tartalomjegyzék

1 tc

A hálózatunkba beérkező forgalmat nem tudjuk sajnos igazán jól formázni, mert nincs hatásunk rá. Kb. olyan mit a papíralapú levelezés, a postásnak nem mondhatjuk meg, hogy naponta csak 5 levelet tegyen a levélszekrényünkbe, mert különben gond lesz. Viszont az olyan forgalmat, aminek forrása az általunk felügyelt hálózatban van, azt már könnyen szabályozhatjuk. Erre jó a tc.


1.1 A traffic control architektúrája

1.1.1 Terminológia

Queueing Discipline (qdisc)

  • Egy eszköz feldolgozási sorának algoritmusa

root qdisc

  • Ez a qdisc kapcsolódik az eszközhöz, az a fa struktúra gyökere.

Classless qdisc

  • Osztályozás mentes viselkedés, a queue-ba kerüls csomagokat nem szórja szét osztályokba, csak újraütemezi, várakoztatja vagy eldobja. Semmit nem lehet rajta konfigurálni, egyszerüen csak van és lehet használni.

Classful qdisc

  • Osztályokra bontható qdisc. Az osztályokból egy fa struktúra építhető fel. Az ilyen qdisc-eknek már sok (rengeteg) paraméterét lehet beállítani.
    • pfifo_fast
    • Token Bucket Filter (TBF)
    • Stochastic Fairness Queueing (SFQ)
    • PRIO
    • Class Based Queueing (CBQ)
    • Hierarchical Token Bucket (HTB)

Class (osztály)

  • Egy qdisc-nek több osztálya is lehet, egy osztálynak lehet több gyermek osztálya. Minden osztályhoz tartozik egy qdisc.

Classifier (osztályozó)

  • Ez dönti el, hogy melyik csomag melyik osztályba kerül tovább.

Filter (szűrő)

  • Az osztályozás a szűrőkkel pontosítható, ha egy csomag paraméterei megfelel egy kondíciónak, akkor az osztályozó aképp fog eljárni vele.

Scheduling (ütemezés)

  • A csomagok ütemezését szolgálja a qdisc-eken keresztül az osztályozó segítségével.

Shaping (formázás)

  • Az határozza meg, hogy egy csomag mikor kerülhet ki a médiumra, hogy az adott paramétereket (sávszélesség, burstösség) teljesítse a csomagfolyam.

Policing (rendelkezés)

  • Meghatárzza, hogy mi történjen a csomaggal. Késleltetést szenvedjen, eldobásra kerüljön (a Linux csak eldobni tudja, mivel nincs bemeneti sor).

Work-Conserving

  • Ez olyan qdisc, ha van kiköldendő csomag, akkor azt kiküldi.

non-Work-Conserving

  • Ez olyan qdisc, hogy ha van kiküldendü csomag, akkor azt csak akkor küldi ki, ha belefér a paraméterek álatal meghatározott forgalmi mintába (pl. nem lesz túl burstös)

1.1.2 A tc a kernelben

               Userspace programs
                    ^
                    |
    +---------------+-----------------------------------------+
    |               Y                                         |
    |    -------> IP Stack                                    |
    |   |              |                                      |
    |   |              Y                                      |
    |   |              Y                                      |
    |   ^              |                                      |
    |   |  / ----------> Forwarding ->                        |
    |   ^ /                           |                       |
    |   |/                            Y                       |
    |   |                             |                       |
    |   ^                             Y          /-qdisc1-\   |
    |   |                            Egress     /--qdisc2--\  |
 --->->Ingress                       Classifier ---qdisc3---- | ->
    |   Qdisc                                   \__qdisc4__/  |
    |                                            \-qdiscN_/   |
    |                                                         |
    +---------------------------------------------------------+
  • Az egész nagy doboz a kernel
  • Ha a gépnek szól egy csomag akkor az felfele megy, ha nem, akkor jobbra

1.1.3 A hierarchia

Minden interfacenek van egy kimeneti root qdisc-je, az alapértelmezésben pfifo_fast. Minden qdisc-hez és class-hez tartozik egy handle (kezelő), amivel a későbbi parancsoknál lehet hivatkozni az adott qdisc-re. Egy interfésznek a kimeneti qdisc-en kívűl lehet bemeneti qdisc-je is.

A handle-ök nevei 2 számból állnak <major>:<minor>. az osztályoknak a szülőivel azonos major azonosítóval kell rendelkezniük. A minor azonosítónak pedig egyedinek kell lennie az adott qdiscben és és annak osztályaiban.

1.1.4 A fa szerkezet

                    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


1.2 CBQ

A legrégebbi és talán a legkomplexebb qdisc és persze a legelterjedtebb is.

Ha nekiesünk, mint tót az annyának, akkor érdekes eredményt kaphatunk. Pl ha egy 10 Mbites forgalmat akarunk 1 Mbitre korlátozni, akkor a cbq-val könnyen azt is elérhetjük, hogy az idő 10%-ben teli a sávszélesség és 90%-ban meg üres, pedig nekünk nem ez kellene. Érdemes végig mazsolázni a paramétereket, hogy jól be tudjuk állítani.

Alapesetben kiszámolja, hogy mekkora legyen az atlagos idő, amikor nem ad (avgidle), hogy a sávszélesség a kivánt legyen, erre exponenciálisan súlyozott mozgó átlagot használ. Ebból tudja, hogy mikor kell adnia ami a csövön befér és meddig nem kell adnia. Egy túlterhelt linknek lehet akár negatív avgidle értéke is, akkor egyszerűen nem ad csomagot amig ismét el nem éri a kívánt értéket. Viszont egy alacsony kihasználtságú linken óriási burst-ök is kialakulhatnak.

1.2.1 CBQ paraméterek

avpkt

  • Átlagos csomag hossz (byte-ban). Ez szükséseges a minidle kisámításához, ami a maxburstből van származtatva, de azt csomag ban mérik.

bandwidth

  • Az eszköz fizikai sávszélessége. Ez a az idle time kiszámításához szükséges.

cell

  • Ennyi idő alatt rakunk ki a vonalra egy csomagot. Ez adja a granularitást. Csomagméret alapján nőhet. Általában 8 az értéke, de 2 többszörösének kell lennie.

maxburst

  • A maxidle kiszámításához használják. Ha a maxidle és az avgidle közel azonos, akkor gyakran burst-ösödhet, mielött lekapcsolja az adást. Érdemes magasabbra állítani, így toreránsabb lesz a burst-ökhöz. A maxidle csak ezen a paraméteren keresztül állítható.

minburst

  • Mivel a CBQ túlterhelésnél hajlamos az eldugulásra, az lenne a jó, ha kiszámolnánk, hogy menny az idle time aztán küldenénk egy csomagot, majd pihennénk egy idle time-ni időt. De sajnos ez a kernel ütemezője miatt sem olyan egyszerű, hiszen neéhz kevesebb mint 10 ms-nél rövidebre ütemezni egy eseményt. Így mégis csak jobb, ha először sokat adunk és utána csak minburst-nyi csomagokat rakunk ki egyszerre, aztán megint pihenünk egy kicsit. A nagyobb minburst érték jobb forgalomformázáshoz vezet nagyobb időre vetítve, de ms-os felbontásnál nagyobb burst-öket okoz.

minidle

  • Ha az avgidle kisebb mint 0, akkor addig nem rakunk csomagot a vonalra, amig az avgidle nem lesz elég nagy egy csomag küldésére. Hogy megelőzzük a hirtelen burst-öket a link lekacsolása miatt, az avgidle-t visszaállítjuk a minidle-re, ha túl alacsonyra csökkenne. A megadott értéket negatív számként kell értelmezni, mikroszekundumban.

mpu

  • Minimum Packet Size. Szükséges az idle time pontosabb kiszámításához. Az ethernet, ha üres csomagot küldünk, akkor is kitömi 64byte-osra, mert különben nem lehetne érzékelni az üttközést.

rate

  • milyen időközönként hagyhatja el csomag az adott qdisc-et.

A CBQ prioritásokat is képes figyelembe venni. Az magasabb prioritásúakkal kezdni, és megy körbe. Nénány paraméter a súlyozott round rubin (WRR) processhez, ami a prioritásokat kérdezgeti le.

allot

  • Egyszerre ennyi adatot küldhet egy osztály. (Plusz infó a wight paraméternél.

prio

  • A CBQ is tud úgy vislekedni, mint a PRIO, előszőr a nagyobb prioritással rendelkező csomagokat küldi ki, majd utána a többit prioritási sorrenben. Addig nem küld ki alacsonyabb prioritású csomagot, amig van magasabb prioritású.

whight

  • A súlyozásban segíti a WRR-t. Minden osztály esélyt kap egy-egy körben. Ha van egy osztály, aminek jóval nagyobb a forgalma, akkor ez segíthet abban, hogy több adatot tudjon kiküldeni egy kör alatt, mint a többiek. A sőlytényezőket normalizálja, csak az arány a lényeg. A normalizált súlyt ezután megszorozza az allot paraméterrel ebből megkapja, hogy egy körben mennyi adatot küldhet ki az adott osztály.

Egy CBQ-n belül ugyan azon a major számon kell osztozniuk.

Pár paraméter a sávszélesség megosztáshoz és kölcsönkéréshez.

isolated/sharing

  • Az isolated a hozzá rendelt sávszélt nem osztja meg a testvér osztályaival. A sharing igen.

bounded/borrow

  • A bounded nem kér kölcsön, a borrow igen.

Viszont egy osztályon belüli gyermek osztályok már kérhetnek kölcsön egymástól.

Példa


              1:           root qdisc
              |
             1:1           child class
            /   \
           /     \
         1:3     1:4       leaf classes
          |       |
         30:     40:       qdiscs
        (sfq)   (sfq)

Van egy 100mbit-es NIC-ünk, a webservernek 5mbit sávot adunk, az smtp-nek pedig 3 mbit-et

# tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit         \
  avpkt 1000 cell 8
# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit  \
  rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20      \
  avpkt 1000 bounded

Ezzel a két folyamhoz összesen 6 mbit sávot rendelünk.

# tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit  \
  rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20      \ 
  avpkt 1000                       
# tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit  \
  rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000

Itt pedig a fenti külön-külön sávot rendeljük a két folamhoz.

# tc qdisc add dev eth0 parent 1:3 handle 30: sfq
# tc qdisc add dev eth0 parent 1:4 handle 40: sfq

Ezzel meghatározzuk a qdisc algoritmusát.

# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 80 0xffff flowid 1:3
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 25 0xffff flowid 1:4 

Itt pedig azt határozzuk meg, hogy melyik folyamot melyik kezeljen.

A pfifo_fast a TOS bitek alapján osztályozza a csomagokat. Erre a CBQ-ban is van lehetőség. Erre a split és a defmap paraméterek szolgálnak. A split azt mondja meg, hogy melyik qdisc-ben alkalmazzuk ezt az osztályozást is, a defmap pedig, hogy mely TOS biteknek szükséges beállítva lenni, hogy a szabály érvényeslüljön a csomagra.

Személyes eszközök