KVM (konfigurace sítě)
- k user doplnit jak a kudy se do virtualizovaného stroje lze připojit z hostitele
- doplnit sekci openvswitch
- - jak s ním pracovat
- - jako ho používat s qemu
- - jak řešit konfigurační skript pro openvswitch
- k none uvést jak lze takové rozhraní využít uvnitř virtuálního stroje ( lze na ně navěsit bridge pro "zahnízděné" virtuály )
- k #Tunelování ethernetové vrstvy přes TCP doplnit text - proč a kdy to dělat
QEMU pro každé síťové zařízení ( NIC - Network Interface Card ) virtuálního stroje má samostatné dvě části. Část, která zprostředkovává komunikaci QEMU s prostředím virtuálu (označovanou jako fore) a část, která komunikuje se systémem hostitele (označovanou backend). Obě tyto části se konfigurují na příkazovém řádku samostatně, ale přes stejnou přes volbu -net
Jak funguje připojení QEMU
Na schematickém modelu vpravo je zobrazeno jakým způsobem funguje síťová infrastruktura QEMU.
QEMU (zelený blok) jako takové je userspace aplikace, která emuluje hardware pro spuštěný virtuál.
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, tak jako kdyby šlo o fyzické zařízení. Tzn. že rychlost, s jakou pak během virtualizace probíhají síťové přenosy mezi aplikacemi spuštěnými uvnitř virtuálu a backendem QEMU, je daná parametry emulovaného hardware a ovladačem použitým ve virtuálním stroji.
Použití vlan v konfiguraci NIC u QEMU
Nastavení vlan v nastavení NIC u QEMU nemá nic společného s nastavením skutečných vlan (IEEE 802.1Q), ale je určeno k propojení backendu a příslušného NIC rozhraní v rámci spuštěné instance virtuálního stroje.
Pokud totiž žádná vlan v konfiguraci NIC nastavena není, jsou při spuštění QEMU automaticky všechny nadefinované NIC i jejich backendy ve vlan 0, což v případě, že je do virtuálního stroje přivedeno na úrovni backendu více síťových segmentů, může vést k tomu, že mezi nimi začnou protékat data, aniž by na to měl virtualizovaný stroj vůbec nějaký vliv.
GUEST eth0 eth1 eth2 | | | ---------------------------- | NIC NIC NIC | | vlan=0 | | TAP X USER NONE | ---------------------------- | | VLAN1 VLAN2 HOST
Skutečnost že takto mohou být propojeny jinak vzájemně oddělené segmenty může vést k síťovým kolapsům! Viz výše uvedený příklad. |
Nastavení vlan v QEMU je tedy určeno k separaci jednotlivých NIC rozhraní a připojených backendů. Každé NIC zařízení zvoleným číslem vlan svázáno s příslušným backendem. Tím lze vnější konektivitu bezpečně přivést do prostředí virtuálu, aniž by tím hrozilo nekontrolovatelné propouštění ethernetových rámců mezi jinak oddělenými síťovými segmenty.
GUEST eth0 eth1 eth2 | | | ---------------------------- | NIC | NIC | NIC | | vlan=1 | vlan=2 | vlan=0 | | TAP | USER | NONE | ---------------------------- | | VLAN1 VLAN2 HOST
Předchozí text o použití 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 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[1]. |
Možnosti "backendové" části NIC
Backendová část síťové karty zajišťuje komunikaci QEMU s odpovídající síťovou infrastrukturou hostitelského systému. Pokud má virtuální stroj pouze jedno NIC zařízení, a má být navíc za NAT, tak většinou není z hlediska backendu nutné nic složitého řešit. Maximálně 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.
Na příkazovém řádku většinou následuje konfigurace backendu bezprostředně za konfigurací fore části NIC, ale to nestačí! K jednoznačnému svázání příslušného backendu s fore částí NIC musí být nastavená stejná hodnota vlan.
Je-li ve virtuálním stroji vytvořeno více NIC zařízení a všechny mají nastavenou stejnou hodnotu vlan jako příslušný backend, tak to bude mít stejný efekt, jako bychom mezi backend a NIC zařízení připojili HUB.
GUEST eth0 eth1 eth2 | | | ---------------------------- | NIC NIC | NIC | | vlan=1 vlan=1 | vlan=2 | | USER | TAP | ---------------------------- | | VLAN1 VLAN2 HOST
user
Většinou je to jedno, že má QEMU na jeden background připojeno více NIC zařízení, protože výchozí backend, který QEMU používá k připojení k vnější síti je user - což je ve skutečnosti připojení k tap zařízení přes interní NAT.
Při konfiguraci síťového rozhraní ve virtuálním stroji přes DHCP klienta (u linuxu dhclient) interní DHCP server QEMU přidělí každému z nich samostatnou IP adresu. Ve výchozím stavu přiděluje tento interní DHCP server adresy v rozsahu 10.0.2.x , ale dalšími parametry lze tento interní DHCP server podle potřeby překonfigurovat.
… -net nic,maccaddr=00:00:0a:00:00:0a,if=virtio -net user …
|
- k user doplnit jak a kudy se do virtualizovaného stroje lze připojit z hostitele
none
Jak plyne z předchozího odstavce, každé další NIC zařízení v QEMU má k dispozici konektivitu přes NAT. Pokud však chceme mít uvnitř virtuálního stroje NIC zařízení, které žádnou konektivitu nemá, tak ji musíme explicitně zakázat tím, že nastavíme backend none a zařízení, které konektivitu mít mají, svážeme pře vlan s příslušnými backendy.
- k none uvést jak lze takové rozhraní využít uvnitř virtuálního stroje ( lze na ně navěsit bridge pro "zahnízděné" virtuály )
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)
Konfigurace soketu s připojením přes TCP protokol
virtualA --------------- | | virtualB virtualC
Konfigurace stroje virtualA..
… -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..
… -net nic,maccaddr=00:00:0a:00:bb:bb,if=virtio -net socket,connect=virtualA:1234 …
|
Konfigurace stroje virtualC..
… -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í[2], přes které spolu hostitelé mohou komunikovat.
-------------------- | | | virtualA virtualB virtualC
Konfigurace stroje virtualA..
… -net nic,maccaddr=00:00:0a:00:aa:aa,if=virtio -net socket,mcast=224.0.0.1:1234 …
|
Konfigurace stroje virtualB..
… -net nic,maccaddr=00:00:0a:00:bb:bb,if=virtio -net socket,mcast=224.0.0.1:1234 …
|
Konfigurace stroje virtualC..
… -net nic,maccaddr=00:00:0a:00:cc:cc,if=virtio -net socket,mcast=224.0.0.1:1234 …
|
vde
Pozor na verzování VDE. Ačkoliv je v repozitory stále uvedeno číslo verze 2.3.1, prodělal tento balík utilit od doby jejího vydání docela dost změn. Především byly vyřešeny nějaké bugy, ale přibyl také kupříkladu plugin pro virtuální switche, který umožňuje monitorovat IP adresy na jednotlivých portech.
V oficiální distribuci Debianu jsou momentálně k dispozici balíčky založené na verzi z počátku srpna 2010. Ovšem jejich struktura je z mého hlediska poměrně chaotickým reliktem. Vytvořil jsem nově debianizovanou verzi, která formálně na tento distribuční balík navazuje a kterou máte možnost nainstalovat z naší Repository pro Debian amd64. Pokud používáte 32 bitový systém, pak vám nezbyde, než si tento balíček překompilovat. Zdroják v repository by měl být použitelný bez ohledu na platformu. Možná si kladete otázku, v čem je rozdíl, takže - balíček
Naopak jsem z balíků zcela vyřadil utility vdecmd a vdeterm, neboť je nelze nikde jinde použít než pouze s VDE a navíc lze jejich funkcionalitu (např. uchovávání historie příkazů) vyřešit mnohem elegantněji přes rlwrap. |
VDE je virtuální switch, který využívá sokety, což sebou přináší omezení při použití tzv. Jumbo Frames. To jsou pakety s větší velikostí než je 1472 bajtů (MTU 1500). U soketů je totiž maximální velikost ethernetového paketu omezena na 1514 bajtů přes IPN_SO_MTU: maximum transfer unit |
Možnosti napojení backendu QEMU na sokety se využívá i při připojení přes VDE (Virtual Distributed Etherenet) virtuální switche, u kterých jsou fyzické ethernetové zásuvky nahrazeny sokety. U VDE je oproti připojení přes backend socket je výhodné, že virtuální switche běží v userspace a k vytvoření a propojování virtuální síťové infrastruktury nejsou nutně zapotřebí práva superuživatele, což je výhodné, neboť ani při vytvoření komplikované ethernetové infrastruktury nejsou nutné žádné zásahy do stávající síťové infrastruktury hostitele.
Virtuální switch
Základním prvkem VDE je virtuální switch. Ten vytvoří spuštěná instance aplikace vde_switch, a vypadá jako běžný adresář, ve kterém je soket s názvem ctl
[3]. Umístění tohoto adresáře ( aka virtuálního switche) lze změnit při spouštění virtálního switche parametrem -s
(resp. --sock
). Není-li při spouštění příkazu vde_switch uvedeno jinak, je totiž výchozím adresářem virtuálního switche - /tmp/vde.ctl
a v případě, že je spuštěna paralelně další instance bez PID souboru to nemusí dopadnout dobře, neboť více procesů nemůže obsluhovat současně jeden soket.
Spuštěná instance aplikace vde_switch pak řídí komunikaci mezi sokety virtuálních zásuvek, které se umísťují do adresáře virtuálního switche, stejným způsobem, jako firmware fyzického switche řídí komunikaci mezi porty.
stroj:~# vde_switch -d -s /tmp/virtualni_switch
|
Řízení virtuálního switche
Aby bylo možné virtuální switch řídit, je třeba pamatovat při spouštění virtuálního switche na vytvoření soketu, přes který bude probíhat řízení switche. Normálně totiž, není-li virtuální switch spuštěn s parametrem -d
jako démon na pozadí, je dostupná řídící konzole switche přímo na terminálu, ze kterého je virtuální switch spuštěn.
V případě, že chceme virtuální switch spouštět na pozadí, je nutné řídící konzoli virtuálního switche připojit na unixový soket, ke kterému se pak lze připojit aplikací unixterm. Cestu na soket nastavíme parametrem -M
.
Další věc, která není k zahození je vytvoření PID souboru. Jednak se lze na tento soubor navázat při skriptování, ale především tím lze jednoduše zabránit spuštění paralelní instance virtuálního switche. Sice by se tím nic moc nestalo, ale nedošlo by k napojení jeho řídící konzole na soket a tak by byl tím pádem defakto nedostupný a nezbylo by, než jej "ustřelit" přes příkaz kill
.
Silně doporučuji při nahazování konektivity do vnější sítě používat pro tuto zásuvku nastavení PID souboru. Jednak lze pak jednoduše ve skriptu kontrolovat, je-li skript stále připojen[4], ale především tím lze zabránit paralelnímu připojení stejného rozhraní do jednoho místa.
To je zásadní rozdíl virtuálního switche od skutečného. V reálu totiž nikdy do jedné zástrčky současně dva konektory nedáte, kdežto u virtuálního switche v tom není žádný problém. Vytvoří se tím smyčka, která může "odbouchnout" port na switchi na mnohem vyšší úrovni, než je zrovna switch přes který je připojen váš hostitel[5]. U virtuálních zásuvek uvnitř VDE infrastruktury to až tak nevadí, protože vde switch pro každou zásuvku automaticky vytváří samostatný port a je-li aktivováno SPT (Spanning Tree Protokol), tak situaci vyřeší tím, že port který je v konfliktu ihned "ustřelí". |
Asi největší výhodou přístupu k řídící konzoli switche je možnost rychle si ověřit co je do switche vlastně připojeno a jak
Z předchozí ukázky výpisu lze vyčíst že je jsou do switche připojeny dvě zásuvky[6]. Jedna z nich je připojena na tap zařízení a druhá rozvádí připojení dál do VDE infrastruktury. VDE switche podporují pluginy a tak lze použít i plugin, který umožňuje zjistit jaká MAC adresa na kterém portu visí.
Přes tuto řídící konzoli lze také switch korektně vypnout příkazem shutdown
.
Virtuální zásuvky
Virtuální zásuvka je ekvivalentem síťové zásuvky (portu) na fyzickém switchi. Součástí VDE je několik aplikací, co umí vytvořit virtuální zásuvku. Mohou si ji také vytvořit i aplikace, které podporují VDE. Do QEMU byla nativní podpora VDE přidána 19. července 2008. U starších verzí QEMU, bylo možné VDE používat přes wrapper vdeq.
- vde_plug
- je základní utilita, která se používá pro vytvoření virtuální zásuvky. Utilita dpipe vytváří virtuální dráty tím, že spojuje rourami stdin a stdout vstupy a výstupy virtuálních zásuvek.
- vde_pcapplug
- utilita, která se používá pro připojení virtuálního switche k síťovému interface na úrovni IP (TUN)
- vde_plug2tap
- se používá pro připojení virtuálního portu switche k síťovému interface na úrovni ethernetu (TAP)
Spojování VDE switchů
Pro vytvoření virtuálního drátu mezi virtuálními switchi se v rámci nejrůznějších manuálů k VDE píše především o dpipe
- dpipe
- je utilita ke spojování vstupů a výstupů virtuálních zásuvek (ve skutečnosti soketů), vytvořených utilitou vde_plug. Emuluje obousměrnou rouru tím, že propojí deskriptory vstupu a výstupu. Používá se především k propojení virtuálních switchů v rámci jednoho stroje, ale dá se použít i k propojení virtuálních switchů napříč internetem. Vlastní přenos datového proudu přes síť však musí zajistit jiná aplikace. V příkladech použití VDE2 se nejčastěji objevuje ssh i když lze použít také socat nebo 'nc, jak uvidíte v níže uvedených příkladech.
Mnohem výhodnější než kombinaci dpipe, vde_plug a ssh je ale použít k propojení virtuálních switchů vde_cryptcab.
- vde_cryptcab
- Na rozdíl od dpipe, která pouze propojuje vstupy a výstupy mezi virtuální zásuvkou A a virtuální zásuvkou B, funguje na principu server - klient. Takže přes jeden naslouchající port virtuální zásuvky zapojené do virtuálního switche na stroji A lze připojit přes UDP protokol virtuální zásuvku z virtuálního switche na stroji B i virtuální zásuvku z virtuálního switche na stroji C a dalších. Pro šifrování propojení se používá algoritmus blowfish, který je rychlejší než algoritmy, které defaultně používá ssh. Data se honí přes UDP protokol, který má jednodušší hlavičky než TCP protokol přes který jede ssh, tudíž za stejný časový úsek lze sítí protlačit více dat než přes ssh tunel. Navíc lze monitorovat, jaká spojení jsou realizována.
Další utilitou, která umožňuje propojovat VDE switche přes internet je vde_over_ns.
- vde_over_ns
- Umožňuje tunelovat virtuální drát přes DNS protokol. Ten totiž obvykle nebývá při připojení do vnější sítě omezován. Takto realizované datové přenosy jsou však z principu pomalé a navíc při nich dochází k 10% ztrátě paketů. Jde tudíž o vyloženě nouzovou záležitost.
Schéma použití dpipe:
dpipe <plugA> = <plugB>
|
A příklad reálného použití:
stroj:~# dpipe vde_plug /tmp/virtual_switch_A = vde_plug /tmp/virtual_switch_B
|
Následující příklad demonstruje propojení virtuálního switche virtual_switch_A
na stroji A s virtuálním switchem virtual_switch_B
na stroji B pomocí dpipe prostřednictvím ssh.
Výhodné je, že tomto případě může být spojení sestaveno pouze ze stroje A.
A:~# dpipe vde_plug /tmp/virtual_switch_A = ssh user@B vde_plug /tmp/virtual_switch_B
|
Pokud chceme stejné spojení realizovat přes socat, musíme spojení sestavovat postupně na stroji A i B. Pro přenos můžeme použít jak UDP, tak TCP. Vždy však musí být jedna strana jako server v režimu LISTEN čekat na připojení klienta. Nejprve je tedy třeba spustit "naslouchající" zásuvku na UDP portu stroje A
A:~# dpipe vde_plug /tmp/virtual_switch_A = socat - UDP4-LISTEN:6666,reuseaddr &
|
A teprve pak připojit k naslouchajícímu portu přes socat zásuvku na stroji B
B:~# dpipe vde_plug /tmp/virtual_switch_B = socat - UDP4:A:6666 &
|
Více podrobností ke konfiguraci portů při přesměrování přes socat viz manuál.
Co se však ukázalo jako nežádoucí, to bylo použití komprese. U ssh se ve výchozí konfiguraci totiž data nekomprimují. Při použití komprese se spojení mezi virtuálními switchi hroutilo.
Podstatně větší roli na výkon při síťové komunikaci, než použití přenosové utility, má fakt, zda-li je či není u virtuálního stroje zapnuta KVM virtualizace a také jaké NIC zařízení QEMU do virtuálu propaguje.
Připojení VDE switche na vnější síť
Konektivitu z vnější sítě lze do VDE infrastruktury přivést buď připojením tap zařízení, na úrovni druhé vrstvy (ethernet), nebo přes pcap - na úrovni třetí vrstvy (TCP).
Rozdíl je v tom, že při připojení virtuální zásuvky přes vde_pcapplug vlastně nastavíme síťové zařízení které má poskytnout konektivitu do promiskuitního režimu, a z něj si pak "odsáváme" potřebnou konektivitu. Kdežto při připojení virtuální zásuvky přes vde_plug2tap "napíchneme" virtuální drát přímo na samostatné virtuální zařízení, které si vytvoříme v kernelu a toto zařízení pak umístíme do společného bridge se zařízením, kterým se do stroje dostává vnější konektivita. Čímž v podstatě dosáhneme stejného efektu, jako bychom použili u virtuálního stroje backend tap[7].
Příklad připojení zařízení eth0 na virtuální switch /tmp/virtual_switch_A
přes vde_pcapplug
user@stroj~$ sudo vde_pcapplug -m 660 -g kvm -s /tmp/virtual_switch_A eth0
|
Použití vde_plug2tap je stejné. Rozdíl je pouze v tom, že vde_plug2tap nelze na jiné zařízení než typu tap použít. Více o zařízení typu tuntap viz backend tap.
Utility
- vde_l3
- je v podstatě virtuální IPv4 router, který umožňuje routovat datové přenosy mezi dvěma i více virtuálními switchi. Jeho hlavní význam je však v tom, že umožňuje realizovat shapping ( traffic control ) na úrovni třetí vrstvy (TCP/IP). Na úrovni druhé vrstvy, se kterou pracují vde_switche totiž jinak QoS implementovat nelze.
- wirefilter
- je utilita, která umožňuje za běhu měnit vlastnosti virtuálního drátu. Tzn. že umí nasimulovat pomalejší připojení. Daní za tuto funkcionalitu je však 10% ztráta paketů.
- vde_autolink
- je nadstavba pro virtuální switche, která umožňuje automatické sestavování a údržbu virtuálních drátů.
- slirpvde
- je věc převzatá do VDE z QEMU. SLiRP je aplikace, která emuluje připojení přes sériovou linku. V podstatě se jedná o virtuální rozhraní, které zajišťuje NAT mezi vnější a vnitřní sítí. Pro použití VDE v kombinaci s QEMU nemá tato aplikace žádný význam.
wirefilter
Součástí vde2 je také nástroj wirefilter, který umožňuje dynamicky měnit parametry virtuálního drátu a tím i ovlivňovat dostupnou konektivitu ve virtuálu. To však má smysl pouze pro testovací a experimentální účely, neboť daní za tento komfort je 10% ztráta paketů a tím i pokles propustnosti sítě.
Použití aplikace wirefilter je jednoduché - přidá se do kolony příkazu dpipe do místa, na kterém chceme připojení "škrtit". Viz příklad spojení virtuálního switche virtual_switch_A
na stroji A s virtuálním switchem virtual_switch_B
přes wirefilter, na kterém pak lze řídit po připojení přes soket /tmp/wire_A_B.console
průtok dat:
A:~# dpipe vde_plug /tmp/virtual_switch_A = wirefilter -M /tmp/wire_A_B.console = vde_plug /tmp/virtual_switch_B
|
Skript pro nahození a připojení virtuálního switche přes pcap
Jednoduchý spouštěcí skript pro vytvoření soketu, na který mohou být připojovány další virtuální switche spouštěných strojů:
Skript po spuštění vytvoří adresář pro sokety, jehož název který bude končit příponou .switch
, pid soubor s příponou .pid
a řídící soket s příponou .manage
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
..
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é..
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...
A:~# ip link set tap0 up
|
...a pak ho přidat do bridge new_bridge
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.
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
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
… -net nic,maccaddr=00:00:0a:00:00:aa,if=virtio,vlan=1 -net tap,ifname=tap0,vlan=1 …
|
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:
- V jádře musí být zaveden modul
vhost-net
- Síťové zařízení propagované do virtuálu musí mít nastaveno
model=virtio
- 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é)
- V konfiguraci backendu musí být uvedena volba
vhost=on
… -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...
openvswitch
- doplnit sekci 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
- k #Tunelování ethernetové vrstvy přes TCP doplnit text - proč a kdy to dělat
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 od backend části síťového rozhraní liší od pohledu tím, že začíná parametrem nic.
… -net nic,maccaddr=00:00:0a:00:00:0a,if=virtio -net none
…
|
Výše uvedený příklad demonstruje vytvoření síťového rozhraní s MAC adresou 00:00:0a:00:00:0a, které se ve virtuálu "ohlásí" jako virtio zařízení.
Nastavení dalších síťových zařízení se provádí zcela jednoduše - přidáním dalších "párů" volby -net
.
V případě, že je konfigurováno více NIC pro jeden stroj je nutné zajistit, aby nemohlo dojít na síti k nějakému konfliktu - duplicitní MAC adresa, překřížené vlany, aj. |
vlan
Parametr vlan je třeba použít pokud má mít virtuální stroj více síťových rozhraní, které mezi sebou nesmí být vzájemně propojeny. Není-li parametr vlan uveden, nastavuje QEMU automaticky pro všechny NIC vlan 0. Takže v případě, že je každý NIC na úrovni backendu připojen do jiného subnetu, začne mezi nimi propouštět pakety, aniž by s tím spuštěný virtuál měl cokoliv do činění.
macaddr
QEMU pro každé další síťové rozhraní negeneruje automaticky samostatnou MAC adresu, nýbrž používá pořád tu stejnou. Má-li tedy virtuální stroj mít více síťových karet, nebo je-li připojených více virtuálních strojů virtualizovaných přes QEMU do jednoho síťového segmentu, je vhodné pro každé NIC nastavit vlastní MAC adresu.
model
Prostřednictvím konfiguračního parametru model lze vhodnou volbou typu virtuální síťové karty ovlivnit, jaký ovladač virtualizovaný stroj použije pro komunikaci se síťovým rozhraním a tím ovlivnit i rychlost zpracování jeho síťové komunikace.
Jaké modely umí QEMU emulovat, lze zjistit spuštěním QEMU s volbou..
… -net nic,model=?
|
Použitelné modely 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
Speciálně u virtio NIC lze nastavit i další parametry, které umožňují emulovat síťovou kartu na PCI-E, z hlediska běžného nasazení však nejsou tyto parametry podstatné. |
name
Parametr name umožňuje nastavit pro NIC jméno, pod kterým pak bude příslušné rozhraní známé v prostředí monitorovací konzole QEMU.
- ↑ http://www.h7.dion.ne.jp/~qemu-win/HowToNetwork-en.html
- ↑ http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xml
- ↑ Pozor na záměnu, nejde o soket přes který lze VDE switch řídit!
- ↑ Je-li proces realizující zásuvku ukončen, přestane v adresáři
/proc
existovat podadresář s tímto číslem procesu - ↑ Tato situace může nastat především tehdy, když správce fyzické infrastruktury takovou situaci nemá ošetřenou na switchích nižší úrovně. Ty by totiž měly zachytit tento problém hned v první linii.
- ↑ Je-li vnější konektivita do switche přivedena přes vde_pcapplug , je místo vde_plug ve výpisu vde_pcapplug)
- ↑ Rozdíl je ale v tom, že je-li použit přímo backend tap, tak ovladač
virtio-net
z virtuálního stroje může využívat "zkratku" do prostoru jádra hostitele přes modulvhost-net
, je-li k dispozici. Což bohužel u připojení přes VDE nelze.