KVM (konfigurace sítě)

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání

QEMU i v případě síťových zařízení rozlišuje - podobně jako u blokových zařízení - stranu, která zprostředkovává komunikaci QEMU s prostředím virtuálu (označovanou jako fore) a stranu, která komunikuje se systémem hostitele (označovanou backend).

Konfigurace síťových zařízení QEMU

Problém s konfigurací síťových zařízení u QEMU tkví v tom, že původně se virtuální síťové karty (fore), i jejich backend - přes který se k virtuálu dostává konektivita, konfigurovaly na příkazovém řádku stejnou volbou -net. O tom, zda-li jde o konfiguraci virtuální síťovky nebo backendu rozhodoval prvním předaný parametr. V případě síťové karty to byl parametr nic (synonymum Network Interface Card ) - všechno jiné mohlo zastupovat typ backendu.

QEMU zatím stále kvůli zpětné kompatibility tento způsob konfigurace sítě podporuje, ale správně je primárně nastavení virtuální síťové karty (fore) přes volbu -device a příslušného backendu přes volbu -netdev.

Rozdíl mezi starým a současným způsobem konfigurace

Pro pochopené rozdílu mezi starým a současným způsobem konfigurace je nejlepší ukázat, jak QEMU pracuje s konektivitou při konfiguraci přes (nyní již zastaralou) volbu -net.

Pokud bychom chtěli vytvořit stejné nastavení, jaké vznikne při použití volby -net, museli bychom při konfiguraci přes -device a -netdev použít backend hubport. QEMU totiž původně využívalo pro připojení vnější a vnitřní sítě interní virtuální hub[1], do kterého se zapojila jak emulovaná virtuální síťová karta, tak backend. A pokud nebyl žádný prostřednictvím volby -net nastavený, QEMU automaticky předpokládalo[2], že má použít NAT ( viz user).

… -net nic,macaddr=00:00:0a:00:00:0a …

Výsledek nastavení byl tedy stejný, jako kdybyste uvedli toto:

… -net nic,macaddr=00:00:0a:00:00:0a -net user …

Síťové zapojení pak interně odpovídalo následujícímu schématu:

    GUEST   HOST
    eth0   (NAT)
     |       |
-----------------
|   NIC    USER |
-----------------

S každou další volbou -net se v tomto virtuálním hubu objeví další port. Není-li uvedeno jinak, QEMU v případě použití volby -net automaticky předpokládalo, že kromě virtuálních síťových karet bude připojen také backend, který spojí interní síť virtuálu s vnější sítí prostřednictvím hostitele. Proto použilo výchozí backend user. Pokud měl být virtuální stroj bez přístupu do vnější sítě, bylo nutné implicitně nastavit backend none:

… -net nic,maccaddr=00:00:0a:00:00:0a -net none …

Do virtuálního hubu pak nebyla přivedena konektivita do vnější sítě.

    GUEST
    eth0
     |
-----------------
|   NIC    NONE |
-----------------
Poznámka U posledních verzí QEMU už není při použití původní konfigurační volby -net výchozí backend user, ale none.

Ve většině případů si u virtuálního stroje vystačíte s jedním síťovým rozhraním. Problém nastane pokud potřebujete více síťových rozhraní, napojených na různé backendy. Následující příklad demonstruje, co se stane v případě, že bychom chtěli toto řešit pouze přes volbu -net:

… -net nic,macaddr=00:00:0a:00:00:0a -net user \
  -net nic,macaddr=00:00:0a:00:00:0b -net tap,ifname=tap0 …

Stav zapojení by vypadal takto:

        GUEST
    eth0    eth1
     |       |
------------------
|   NIC     NIC  |
|   USER    TAP  |
------------------
     |       |
   (NAT)    tap0
        HOST

Ve virtuálu by se vytvořily dvě síťové karty, ale pakety ze sítě do které bychom byli připojeni přes zařízení tap0 "prosakovaly" i na virtuální síťovou kartu, která má být přístupná pouze přes NAT. A ba co hůře! Pakety, které měly zůstat schované v interní síti za NATem by pronikaly do vnější sítě, což může vést k neblahým důsledkům. Může nastat...

  • konflikt v IP adresách (postiženým počítačům přestane "záhadně" fungovat síť)
  • síťová smyčka (na postiženém síťovém segmentu může dojít totálnímu zahlcení sítě)
  • případně potenciální útočník může zachytit komunikaci z vnitřní sítě, která by jinak byla schovaná za NATem

Provizorním řešením bylo zavedení parametru vlan.

Poznámka Následující text o tom jak je to s použitím vlan u QEMU je velmi důležitý z hlediska pochopení dalšího textu.

Většinou totiž mívají virtuální stroje maximálně jedno až dvě rozhraní a jen málokdo řeší, jak dostat do jednoho virtuálního stroje více subnetů. Proto se také u většiny postupů na internetu s nastavením a významem vlan při konfiguraci síťových rozhraní u QEMU často nesetkáte.

Osobně jsem zjistil k čemu jsou až v situaci, kdy jsme narazili na skutečnost, že nám u virtuálního stroje, který byl předtím virtualizován v prostředí XENu najednou někudy protékají pakety mezi interní VLAN a veřejnou sítí.

Při laborování s tímto virtuálním strojem jsme s překvapením zjistili, že pakety začínají protékat dřív, než vůbec stroj začne bootovat! Zkusili jsme tedy oddělit jednotlivé NIC (a k nim i příslušné backendy) právě pomocí vlan a tak intuitivně přišli na to, k čemu vlastně jsou. Až dodatečně jsem narazil i na webovou stránku, která použití vlan zmiňuje a vysvětluje[3].

Použití vlan v konfiguraci NIC u QEMU

Nastavení parametru vlan v rámci volby -net u QEMU nemá nic společného s nastavením skutečných vlan (IEEE 802.1Q). Je určeno pouze k propojení příslušných fore rozhraní a backendů do jedné instance virtuálního hubu.

Jak bylo demonstrováno výše, pokud tento parametr uveden není, jsou automaticky všechny síťové karty i backendy zapojeny do jednoho virtuálního hubu a data protékají, aniž by na to měl virtualizovaný stroj vůbec nějaký vliv. Pokud však uvedeme parametr vlan, dojde vytvoření nové, nezávislé instance interního hubu identifikované právě hodnotou parametru vlan.

… -net nic,macaddr=00:00:0a:00:00:0a -net user \
  -net nic,macaddr=00:00:0a:00:00:0b,vlan=1 -net tap,ifname=tap0,vlan=1 \
  -net nic,macaddr=00:00:0a:00:00:0c,vlan=2 -net none,vlan=2

Při aplikaci výše uvedené konfigurace se tak vytvoří kromě výchozího hubu s číslem 0, další dva. A každé rozhraní má dostupné pouze svůj backend. Tím pádem data mezi nimi nemohou protékat.

           GUEST
    eth0    eth1      eth2
     |       |         |
----------------------------
|   NIC  |  NIC   |   NIC  |
| vlan=0 | vlan=1 | vlan=2 |
|  USER  |  TAP   |  NONE  |
----------------------------
     |        |
   (NAT)    tap0
        HOST

Výpis příkazu info network na monitorovací konzoli QEMU by pak vypadal takto:

Poznámka
hub 2
 \ hub2port0: e1000.2: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0c
hub 1
 \ hub1port1: tap.0: index=0,type=tap,ifname=tap0
 \ hub1port0: e1000.1: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0b
hub 0
 \ hub0port1: user.0: index=0,type=user,net=10.0.2.0,restrict=off
 \ hub0port0: e1000.0: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0a

Jen pro srovnání uvádím jak by tento výpis vypadal, pokud by parametry vlan uvedeny nebyly:

Poznámka
hub 0
 \ hub0port4: e1000.2: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0c
 \ hub0port3: tap.0: index=0,type=tap,ifname=tap0
 \ hub0port2: e1000.1: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0b
 \ hub0port1: user.0: index=0,type=user,net=10.0.2.0,restrict=off
 \ hub0port0: e1000.0: index=0,type=nic,model=e1000,macaddr=00:00:0a:00:00:0a


Konfigurační možnosti "fore" části NIC

Vytvoření síťového rozhraní v prostředí virtuálního stroje zajišťuje část fore, která se nastavuje prostřednictvím konfigurační volby -device, která musí obsahovat jako první povinný parametr - typ virtuální síťové karty která se má nastavit.

Jaké modely síťových zařízení umí QEMU použít či emulovat, lze zjistit spuštěním QEMU s volbou:

Poznámka
… -device ?

Seznam typů síťových zařízení, které umí vaše verze QEMU použít, je v sekci Network devices:.

Pokud chcete vědět, jaké konfigurační volby lze pro zvolené síťové zařízení použít, můžete opět použít parametr otazník. Tentokrát umístěný bezprostředně za první povinný parametr - název typu síťového zařízení které chcete použít, tak jak ho vrátil předchozí výpis:

Poznámka
… -device virtio-net-pci,?

Vhodnou volbou typu virtuální síťové karty lze ovlivnit, jaký ovladač pak virtualizovaný stroj použije pro komunikaci se síťovým rozhraním a tím ovlivnit i rychlost při zpracování síťové komunikace uvnitř virtuálního stroje.

U původní konfigurační volby -net, která používala jako povinný parametr určující že má jít o konfiguraci virtuální síťovky klíčové slovo nic, se používal pro nastavení typu síťové karty parametr model. U volby -device se již tento parametr nepoužívá, protože je typ síťového zařízení určen povinným prvním parametrem.

Seznam virtuálních síťových karet, které lze použít při konfiguraci přes volbu -net je omezenější. Proto pokud používáte starší verzi QEMU, nebo nadstavbu, která neumí pracovat s volbou -netdev, múžete zjistit použitelné typy síťových karet takto:

Poznámka
… -net nic,model=?

Vypsaný seznam použitelných typů se bude do určité míry prolínat s tím co se dá použít v rámci volby -device, proto zde uvádím následující stručný přehled typů virtuálních síťových karet z hlediska propustnosti:

virtio
Virtio network device je z hlediska konektivity tou nejoptimálnější volbou, pokud má virtuální stroj k dispozici virtio ovladače. QEMU totiž při komunikaci přes virtio nic neemuluje, ale předává pakety ke zpracování přímo do kernelu. Ovladače k virtio pro systémy MS Windows lze stáhnout z webu fy. Red Hat inc.. Ovladač v linuxovém jádře virtuálního stroje se jmenuje virtio-net.
e1000
Emulace skutečné síťové karty Intel 82549EM Gigabit je v QEMU výchozí, pokud však nemá virtualizovaný systém pro tuto síťovou kartu nainstalovaný ovladač, je nutno vyzkoušet některé jiné z následujících zařízení.
pcnet
Gigabajtová síťová karta, která se hlásí jako AMD 79c970 [PCnet 32 LANCE]]. Ovladač k ní je součástí vmware tools
rtl8139
Emuluje kartu s čipem Realtec. Tento typ 100 megabitové síťové karty patřil mezi nejběžnější síťové karty, které nebyly z produkce Intelu. Výhodné je, že ovladač k této síťové kartě je přímo ve Windows XP
ne2k_pci
Realtek RTL-8029(AS) byla pouze 10 megabitová síťová karta, jedna z posledních, které ještě podporovaly koaxiální kabeláž. Tuto síťovou kartu však bylo možné rozchodit i pod DOSem

Úplné nastavení síťového rozhraní pak vypadá asi takto:

Poznámka
… -netdev user,id=interni_nat -device virtio-net-pci,mac=00:00:0a:00:00:0a,id=eth0,netdev=interni_nat …

Interně stav zapojení této konfigurace vypadá takto:

    GUEST
    eth0
     |
virtio-net-pci
    HOST

Viirtuální síťové rozhraní eth0 je přímo napojeno na virtualizovaný síťový ovladač v jádře hostitele backendem virtio-net-pci. Klíčový je při konfiguraci virtuálního síťového zařízení parametr netdev, kterým je spojeno s backendem.

Poznámka Při konfiguraci přes volbu -net tento parametr do jisté míry nahrazuje parametr vlan, který s tomto případě nemá s konfigurací síťových VLAN nic společného a slouží pouze k identifikaci virtuálního hubu, přes který se má spojit virtuální síťovka s backendem:
… -net nic,macaddr=00:00:0a:00:00:0a,name=eth0,if=virtio,vlan=0 -net user,vlan=0
netdev
Klíčový parametr, kterým je svázána virtuální síťová karta s backendem který jí zajistí připojení do síťové infrastruktury. Pokud při konfiguraci není uveden, najede QEMU se síťovou kartou, která není nikam zapojena - je bez konektivity.
Obsah parametru musí být shodný s id příslušného backendu. Viz možnosti "backendové" části QEMU.
mac
Parametr pro nastavení MAC adresy virtuální síťové karty.
QEMU pro každé další síťové rozhraní negeneruje automaticky samostatnou MAC adresu, nýbrž používá pořád tu samou. Což v zásadě nevadí, pokud virtuál nemá více síťových karet, nebo pokud není zapojen do stejného segmentu s virtuály, které rovněž nemají nastavenou unikátní MAC adresu.
Poznámka Při konfiguraci virtuální síťové karty prostřednictvím volby -net se parametr, kterým lze nastavit MAC adresu nejmenuje mac, ale macaddr.
id
Identifikátor síťové karty síťové karty, pod kterým bude příslušné rozhraní k nalezení v prostředí monitorovací konzole QEMU. V případě, že není nastaven, bude vygenerován automaticky.
Poznámka Při konfiguraci prostřednictvím volby -net se tento identifikátor nastavuje parametrem name.
vlan
Nastavení VLAN
Upozornění Parametr vlan má u virtuálních síťových karet konfigurovaných volbou -device stejný význam jako u fyzických síťových zařízení, ale zcela jiný než u konfigurace přes volbu -net. Viz použití parametru vlan v konfiguraci NIC.

Možnosti "backendové" části QEMU

Na úpravě následující části se pracuje, proto je u některých backendů uveden ještě pouze jejich použití se starým způsobem konfigurace přes volbu -net
Model qemu networking.svg

Backendová část QEMU zajišťuje komunikaci virtuální síťové karty s odpovídající síťovou infrastrukturou hostitelského systému. Pokud má virtuální stroj pouze jedno NIC zařízení, které má být navíc za NATem, není z hlediska konfigurace backendu nutné nic složitého řešit. Maximálně ještě tak vytažení nějakého portu z virtuálu.

Situace se však od základu mění, pokud má mít virtuální stroj síťových zařízení více a navíc - má-li každé z nich používat jiný backend.

U původní konfigurace prostřednictvím volby -net většinou na příkazovém řádku následovala konfigurace backendu bezprostředně za konfigurací virtuální síťové karty, ale pro jednoznačné svázání příslušného backendu s virtuální kartou bylo nutné nastavit pomocí identické hodnoty vlan samostatný virtuální hub.

… -net nic,macaddr=00:00:0a:00:00:aa,if=virtio,vlan=0 \
  -net tap,ifname=tap0,vlan=0

Při konfiguraci pomocí volby -netdev to není nutné, protože je povinný parametr id, kterým se pak virtuální síťová karta konfigurovaná volbou -device sváže s příslušným backendem. Id backendu je pak obsahem parametru netdev v konfiguraci virtuálního síťového zařízení.

Následující příklad demonstruje správné konfigurační nastavení pro dosažení stejné konfigurace jako je uvedeno výše:

… -device virtio-pci-net,mac=00:00:0a:00:00:aa,netdev=tap.0 \
  -netdev tap,id=tap.0,ifname=tap0 …

Na schematickém obrázku vpravo je vyobrazeno kudy tečou síťové pakety u různých typů backendů, které lze použít pro zajištění konektivity virtuálního stroje u QEMU.

QEMU (zelený blok) jako takové je userspace aplikace, která - za předpokladu, že virtuální stroj nemá k dispozici ovladač pro zařízení virtualizované hypervizorem - emuluje chybějící hardware.

Poznámka Pokud není v jádře přítomný hypervizor, který by umožňuje virtuálu využít virtualizaci CPU na úrovni hardware hostitele, tak je virtualizován i procesor virtuálního stroje.

Virtuální stroj pak komunikuje s emulovaným hardware, stejně, jako by šlo o fyzické zařízení.

Rychlost, s jakou pak během virtualizace probíhají síťové přenosy mezi aplikacemi spuštěnými uvnitř virtuálu a vnější sítí je tak daná

  1. parametry emulovaného hardware,
  2. vlastnostmi ovladače použitého v operačním systému virtualizovaného stroje
  3. a použitým backendem QEMU.

V současné době má QEMU k dispozici tyto backendy:

user
Zprostředkovává virtuálnímu stroji vnější konektivitu přes interní NAT a DHCP server
tap
Připojuje virtuální síťovou kartu na tap zařízení, případně
bridge
V podstatě jde o připojení přes tap, s tím že se QEMU postará jak o vytvoření tap zařízení, tak jeho přidání do příslušného bridge.
l2tpv3
umožňuje připojit síť virtuálního stroje na virtuální drát, vytvořený přes L2TPv3 protokol do kterého je zapouzdřená ethernetová vrstva.
socket
Obaluje síťový provoz virtuálního stroje takovým způsobem, aby bylo možné zajistit konektivitu do jiné sítě prostřednictvím přes unixový soket nebo UDP port.
vhost-user
Přesměrovává síťový provoz virtuálního stroje na lokální znakové zařízení hostitele.
hubport
Vytváří stejný typ interního hubu, jaký QEMU automaticky použije u původní konfigurační volby -net

Síťové zařízení bez vnější konektivity

Pokud chceme mít ve virtuálním stroji k dispozici síťové zařízení bez vnější konektivity, stačí vynechat parametr netdev, přes který se přiřazuje virtuální síťová karta k backendu konfigurovanému volbou -netdev:

… -device virtio-pci-net …

Při spouštění sice QEMU zařve, že příslušnému zařízení chybí vhodný protějšek, ale svůj účel to splní.

U konfigurace přes volbu -net to tak jednoduché nebylo. Tam bylo naopak nutné implicitně nastavením klíčového slova none říct, že se virtuální hub na žádný backend připojit nemá. Pokud bylo síťových zařízení nakonfigurováno více, tak pochopitelně s odpovídajícím parametrem vlan. Viz ukázkový příklad:

… -net nic,maccaddr=00:00:0a:00:00:aa,if=virtio,vlan=1 -net none,vlan1 …

hubport

Je backend, který vytvoří stejný virtuální hub, jako když použijete původní konfigurační volbu -net. Ovšem nasimulovat jeho prostřednictvím chování, které bylo popsáno hned v úvodu této kapitoly - viz rozdíl mezi starým a současným způsobem konfigurace, kdy dochází k nežádoucímu prosakování paketů jeho prostřednictvím - nelze.

Volba -netdev totiž nemá k dispozici parametr, kterým by bylo možné připojit na port virtuálního hubu cokoliv jiného než virtuální síťovou kartu nastavenou přes volbu -device.

S využitím tohoto backendu tedy můžeme vytvořit virtuální hub bez vnější konektivity...

Poznámka
… -netdev hubport,id=hub0port0,hubid=0 \
  -device e1000,id=e1000.0,netdev=hub0port0 \
  -netdev hubport,id=hub0port1,hubid=0 \
  -device e1000,id=e1000.0,netdev=hub0port1 …

..stejný jako by se vytvořil při konfiguracI přes volbu -net...

Poznámka
… -net nic,macaddr=00:00:0a:00:00:0a \
  -net nic,macaddr=00:00:0a:00:00:0b \
  -net none …

...ale bez rizika, že díky nepozornosti došlo k připojení tohoto virtuálního hubu do vnější sítě.

user

Tento backend je určen především pro vytvoření testovacího prostředí, které je schované vůči vnější síti za NATem, ale není od vnější sítě zcela odříznuté, jako by tomu bylo v případě, že bychom použili #hubport.

Kromě toho, že realizuje NAT, funguje také jako DHCP server a může fungovat také jako TFTP server. To má význam především v tom případě, že se má v virtuální prostředí spouštět jako diskless.

Nejjednodušší konfigurace, která bude mít podobný efekt, jako měla konfigurace přes volbu -net může vypadat takto:

Poznámka
… -netdev user,id=user.0 -device e1000,netdev=user.0 …

Takto by to vypadalo postaru..

Poznámka
… -net nic -net user …

Při konfiguraci síťových rozhraní ve virtuálním stroji, je-li použit DHCP klient (u linuxu dhclient), přidělí interní DHCP server QEMU každému z nich samostatnou IP adresu.

Není-li uvedeno jinak, přiděluje interní DHCP server adresy v rozsahu 10.0.2.x , ale prostřednictvím dalších parametrů lze nastavení interního DHCP serveru podle potřeby překonfigurovat.

Ve skutečnosti ale není výsledek konfigurace stejný, jako v případě použití volby -net. Ta totiž připojí backend user přes interní hub, kdežto v případě konfigurace přes -netdev je možné k internímu DHCP serveru připojit pouze jedno virtuální rozhraní.

Pro každý další nakonfigurovaný backend se jinak spouští nová samostatná instance interního DHCP serveru s vlastním NATem.

Lze použít interní DHCP na více rozhraní?

Ano, ale pouze za předpokladu, že virtuální stroj má interně připojeno virtuální rozhraní na kterém naslouchá DHCP server do bridge, nebo virtuálního switche do kterého jsou zapojeny další virtuální síťové karty.

Změna výchozí konfigurace interního DHCP serveru

net
Konfigurace rozsahu přidělovaných IPv4 adres
hostname
Doménové jméno, které bude vracet virtuální DNS server do prostředí virtuálu
dhcpstart
Výchozí IP adresa rozsahu, ze kterého se budou přidělovat IP adresy
dns
IP adresa virtuálního DNS serveru, které předá klientovi DHCP server pro zápis do souboru /etc/resolv.conf
dnssearch
Doména, kterou předá klientovi DHCP server pro zápis do souboru /etc/resolv.conf

Tunelování portů z virtuálního stroje ven a zpět

hostfwd
Konfigurace čísla portu hostitele, který na kterém bude naslouchat port tunelovaný z prostředí virtuálu
guestfwd
Konfigurace čísla portu hostitele, na který se bude chytat port z prostředí virtuálu

Zavádění systému přes PXE

bootfile
cesta k souboru který umí zavést operační systém přes PXE. U ISC DHCP serveru je součástí proměnné ....
tftp
cesta do adresáře, kde jsou uloženy soubory které se PXE zavaděč bude snažit stáhnout přes TFTP protokol

socket

Pokud nepotřebujeme mít ve virtuálních strojích vnější konektivitu ale chceme je pouze propojit mezi sebou, můžeme využít ke komunikaci background socket, který komunikuje na úrovni 5. vrstvy.

  • Komunikace mezi stroji může probíhat jak prostřednictvím TCP, tak UDP paketů.
  • Při použití TCP protokolu bude fungovat stroj virtualA jako server a stroj virtualB jako klient.
  • Přes soket lze navzájem propojit do jedné sítě i více než dva stroje. U připojení přes TCP by konfigurace dalších strojů vypadala stejně jako u stroje virtualB.
  • Při použití UDP protokolu vypadá konfigurace u všech strojů stejně.
  • Je třeba mít na paměti, že každý stroj musí mít svou vlastní nekonfliktní MAC adresu, což QEMU interně neřeší. Je tedy třeba pro každý stroj unikátní MAC nastavit ručně.
  • Pokud má TCP komunikace probíhat po síti, tak se v konfiguraci stroje virtualB, virtualizovaného na jiném stroji, uvede místo localhost IP adresa stroje, kde je virtualizován virtualA (který má otevřen soket v režimu LISTEN)
Upozornění Komunikace přes sokety má několik omezení:
  • Aby mohl být při spuštění virtuálního stroje vytvořen příslušný soket, musí být QEMU spuštěno pod uživatelem root, protože obyčejný uživatel zpravidla k soketům nemá přístup
  • Při připojení přes soket na úrovni TCP stroje mezi sebou komunikují prostřednictvím stroje, který má soket nastaven v režimu listen (což je u výše uvedeného příkladu stroj virtualA. Ten funguje jako server. V případě, že bude vypnut, síťová komunikace mezi ostatními stroji přestane fungovat!

Konfigurace soketu s připojením přes TCP protokol

virtualA ---------------
             |         |
          virtualB  virtualC

Konfigurace stroje virtualA..

Poznámka
… -net nic,maccaddr=00:00:0a:00:aa:aa,if=virtio -net socket,listen=localhost:1234 …

-net nic,maccadr=aa. -net socket,listen=localhost:1234

Konfigurace stroje virtualB..

Poznámka
… -net nic,maccaddr=00:00:0a:00:bb:bb,if=virtio -net socket,connect=virtualA:1234 …

Konfigurace stroje virtualC..

Poznámka
… -net nic,maccaddr=00:00:0a:00:cc:cc,if=virtio -net socket,connect=virtualA:1234 …

Konfigurace soketu s připojením přes UDP protokol

Při propojení strojů přes UDP protokol nefiguruje v konfiguraci IP adresa žádného hostitele, ale multicastová adresa rozhraní[4], přes které spolu hostitelé mohou komunikovat.

    --------------------
    |        |         |
virtualA  virtualB  virtualC

Konfigurace stroje virtualA..

Poznámka
… -net nic,maccaddr=00:00:0a:00:aa:aa,if=virtio -net socket,mcast=224.0.0.1:1234 …

Konfigurace stroje virtualB..

Poznámka
… -net nic,maccaddr=00:00:0a:00:bb:bb,if=virtio -net socket,mcast=224.0.0.1:1234 …

Konfigurace stroje virtualC..

Poznámka
… -net nic,maccaddr=00:00:0a:00:cc:cc,if=virtio -net socket,mcast=224.0.0.1:1234 …

QEMU connection model socket.svg

tap

Na kterési stránce jsem narazil u tap zařízení na přirovnání, že jde o dírku, kterou tečou síťová data z userspace do prostoru jádra. Moc výstižné mi to však nepřišlo, protože mi přes tap zařízení zpočátku žádná data netekla a vůbec jsem nechápal proč. Pokusím se tedy vyložit k jaké představě o tap zařízení jsem nakonec dospěl já.

Pro větší názornost začnu vytvořením tap zařízení s názvem tap0..

Poznámka
A:~# ip tuntap add dev tap0 mode tap

Tím vytvořím virtuální síťový interface (chcete-li - síťovou kartu), který není nahozený ani nakonfigurovaný, ale především není nikam připojený!, takže jím logicky ani nemohou protékat žádná data. ALE! Vzhledem k tomu, že jde o zařízení na 2. vrstvě (ethernet), lze ho přidat do bridge s jiným síťovým zařízením.

Připojení tap zařízení k internetu přes bridge

Laickým pohledem je bridge burza, na které si její členové - přidaná síťová zařízení - navzájem vyměňují pakety. Pro manipulaci s bridgem se používá nástroj brctl a vytvoření bridge s názvem kupř. new_bridge je až stupidně snadné..

Poznámka
A:~# brctl addbr new_bridge

Ovšem prázdný bridge je stejně k ničemu, jako nepřipojené tap0 zařízení, takže nejprve je třeba nahodit tap0 zařízení, vytvořené předešlým příkazem...

Poznámka
A:~# ip link set tap0 up

...a pak ho přidat do bridge new_bridge

Poznámka
A:~# brctl addif new_bridge tap0

Bridge se ze síťového hlediska chová jako síťové zařízení, takže mu lze nakonfigurovat IP adresu a pak přes něj komunikovat, ovšem pro sdílení konektivity ho konfigurovat není nutné. Musí se však nahodit, jako každý jiný interface.

Poznámka
A:~# ip link set new_bridge up

Pokud bychom v tuto chvíli nahodili nějaký virtuál, připojeným na tap0, tak už bychom mohli přes tcpdump, připojený na bridge vidět, jak na něj přicházejí se strany virtuálu pakety. Přidáme-li do něj interface, který má konektivitu do vnější sítě, tak už by virtuál mohl začít komunikovat se světem.

Ale nepředbíhejme. Dejme tomu, že vnější konektivitu získáváme z rozhraní eth1. Přidáme jej tedy do bridge new_bridge stejně jako předtím tap0

Poznámka
A:~# brctl addif new_bridge eth1

Jenže ouha?! Na eth1 pakety chodí, na bridge pakety chodí, ale když připojím tcpdump na tap0 - tak ani ťuk. Přitom zařízení je nahozené, jak je to tedy možné?!

Nebudu napínat - přes tap0 zařízení začnou běhat pakety teprve ve chvíli, až se na něj něco připojí, nebo až dostane IP adresu. Zdá se to naprosto logické a prosté, ale sám jsem zabil dva dny, než jsem na takovou blbinu přišel.

Použití vytvořeného tap zařízení v QEMU

Máme-li tedy vytvořené tap0 zařízení v bridgi se zařízením, které nám zprostředkuje vnější konektivitu, můžeme je použít v konfiguraci backendu

Poznámka
… -net nic,maccaddr=00:00:0a:00:00:aa,if=virtio,vlan=1 -net tap,ifname=tap0,vlan=1

QEMU connection model tap.svg

QEMU, tap zařízení a vhost-net

Pro větší názornost jsem si dal tu práci a vytvořil polopatická schémata, na kterých je demonstrováno, kudy a jak probíhá u různých backendů síťová komunikace. Z pouhého naznačení toku dat však ještě neplyne informace o tom, kdo a kde vlastně odvádí při síťové komunikaci největší díl práce - proto přibyla ikonka maníka, která to má naznačit.

Díky tomu lze názorně vysvětlit proč u VDE switche dává připojení přes TCP spojení a ssh lepší výsledky, než při pouhém přesměrování portů.

Je to tím, že když jsou zásuvky připojené datovým proudem přes ssh, tak se stará o zdárný průběh přenosu dat TCP protokol hostitele. Pakety se dostávají k síťovému rozhraní virtuálu již zkompletované, takže virtuál již nemusí řešit poztrácené pakety. To však neplatí, pokud je připojení realizováno přes sokety, nebo sockatem přes UDP.

Podobně je tomu při připojení přes tap zařízení.

Z hlediska napojení na fyzikou infrastrukturu to sice může být z hlediska konektivity rychlejší cesta, ale z hlediska virtuálního stroje znamená větší průtok dat větší množství práce navíc. Obzvláště tehdy, když QEMU emuluje síťové zařízení.

Aby se zredukoval objem úkonů při komunikaci mezi QEMU a virtuálem, byly vytvořeny virtio ovladače, u kterých se skutečné fyzické zařízení neemuluje, ale požadavky zevnitř virtuálního stroje se rovnou předávají přes QEMU jádru hostitele. Z hlediska síťové komunikace tak použitím virtio ovladačů sice došlo k jistému zrychlení, ale při zpracování síťové komunikace zde pořád zůstává přechod na úrovni userspace hostitele.

Řešením, které se to snaží překlenout je jaderný modul vhost-net, který je záležitostí hostitele, nikoliv hosta. Jeho použitím se přesouvá zpracování síťové komunikace z userspace do jádra, neboť ovladač virtio-net, z virtuálu nechodí se svými požadavky ke kováříčkovi (QEMU), ale rovnou ke kováři (kernel)! Viz schéma hned v úvodu této stránky.

Nastavení použití jaderného modulu vhost-net je jednoduché. Především je třeba mít na paměti následující body:

  1. V jádře musí být zaveden modul vhost-net
  2. Síťové zařízení propagované do virtuálu musí mít nastaveno model=virtio
  3. Komunikace přes vhost funguje pouze u backendu tap, ale smysl má pouze tehdy, je-li tap zařízení připojené bridgem přímo na fyzický interface (při tunelování druhé vrstvy přes TCP/IP, jak to dělá l2tpv3 je to zbytečné)
  4. V konfiguraci backendu musí být uvedena volba vhost=on
Poznámka
… -net nic,maccaddr=00:00:0a:00:00:aa,if=virtio,vlan=1 -net tap,ifname=tap0,vlan=1,vhost=on …

Jak pak probíhá tok dat a kde leží těžiště zpracování naznačuje následující schéma...

QEMU connection model tap vhost.svg

openvswitch

- jak s ním pracovat
- jako ho používat s qemu
- jak řešit konfigurační skript pro openvswitch


Tunelování ethernetové vrstvy přes TCP

QEMU connection model l2tp.svg

  1. HUB zařízení v současné době většinou nahradily switche, které byly ve své době výrazně dražším kusem HW. HUB je totiž ve své podstatě "hloupé" zařízení. Pasivní síťový prvek, který neobsahuje žádnou řídící logiku a příchozí síťové pakety tupě rozesílá na všechny existující porty, jelikož netuší který z nich vede k adresátovi. I když se za učitých okolností může takové chování hodit, vede v běžném provozu ke zbytečnému datovému toku, který pak snižuje reálnou propustnost sítě.
  2. U novějších verzí QEMU již tomu tak není. V případě, že není žádný backend nastaven, aplikuje se jako výchozí backend none.
  3. http://www.h7.dion.ne.jp/~qemu-win/HowToNetwork-en.html
  4. http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xml