KVM (řízení přes konzole QEMU)

Z DCEwiki
Verze z 9. 10. 2011, 11:45, kterou vytvořil Keny (diskuse | příspěvky) (→‎Vzdálená správa)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Skočit na navigaci Skočit na vyhledávání

Virtuální konzole v grafickém prostředí X serveru

Virtuální stroj lze ovládat přes virtuální konzoli, která se při spuštění QEMU v grafickém prostředí otevře jako další okno, ve kterém běží virtualizovaný stroj. To co vidíte je však pouze grafická konzole QEMU. Kromě ní obsahuje virtuální konzole ještě další tři. Pokud pracujete přímo s virtuální konzolí v grafickém prostředí X serveru, pak se můžete mezi nimi přepínat následující kombinací kláves

CTRL+ALT 1 - grafická konzole (virtuální displej monitoru)
CTRL+ALT 2 - monitorovací konzole
CTRL+ALT 3 - serial0 konzole
CTRL+ALT 4 - parallel0 konzole
CTRL+ALT - opuštění virtuální konzole QEMU

Přepínání linuxových konzolí

Pokud budete virtualizovat v rámci QEMU linuxový stroj, můžete poměrně brzy narazit na otázku, jakým způsobem se lze přepnout v rámci grafické konzole QEMU na jinou konzoli virtuálního stroje.

Přepínání linuxových konzolí v rámci virtuální konzole QEMU

Z monitorovací konzole
odesláním příkazu sendkey ctrl-alt-f[číslo konzole]
Z grafického prostředí
příkazem chvt číslo konzole
Z textové konzole
buď rovněž příkazem chvt číslo grafické konzole, nebo (pokud nejste na konzoli přihlášeni) současným podržením kláves ALT + SHIFT a stiskem příslušné klánesy F1~7

Přepínání linuxových konzolí v rámci virtualizovaného linuxu přes SPICE

Poznámka Není-li nastaveno jinak, pak jsou při spuštění virtualizace přes qemu-spice nastaveny ostatní konzole na null, zatímco grafický výstup je exportován přes SPICE.
Z monitorovací konzole (pokud je dostupná)
odesláním příkazu sendkey ctrl-alt-f[číslo konzole]
Z grafického prostředí
příkazem chvt číslo konzole
Z textové konzole
buď rovněž příkazem chvt číslo grafické konzole, nebo (pokud nejste na konzoli přihlášeni) podržením klávesy ALT (dokud se neobjeví symbol ALT na obraze) a stiskem příslušné klánesy F1~7

Vzdálená správa

Pro vzdálenou správu virtuálního stroje jsou v QEMU dostupné dva kanály, jejichž prostřednictvím lze provádět s virtuálním strojem nejrůznější operace, od získávání informací o běžícím virtuálním stroji, až po posílání klávesových kódů do prostředí virtuálního stroje.

  • monitorovací konzole - se vytvoří, je-li na příkazové řádce při spouštění virtuálního stroje předána volba -monitor
  • QMP konzole - se vytvoří, je-li na příkazové řádce při spouštění virtuálního stroje předána volba -qmp

Ve výchozím nastavení každá z nich přistupuje na standardní výstup, s tím, že vyšší prioritu má volba uvedená jako poslední, proto je rozumnější je buď přesměrovat na nějaký síťový port (pro připojení přes TCP), nebo na lokální unixový soket.

  • grafická konzole - Od QEMU verze 0.8.1 je možné ke grafické konzoli virtuálního stroje přistupovat vzdáleně, prostřednictvím VNC protokolu a od verze 0.13.0 se pracuje na intergraci protokolu SPICE, který umožňuje do jednoho komunikačního kanálu soustředit veškerou komunikaci klienta se vzdáleným strojem - v současnosti jde kromě obrazu a znakových zařízení o přenos zvuku.

Přesměrování monitorovací konzole

Upozornění Pokud chcete přistupovat ke grafické konzoli virtuálního stroje přes SPICE nebo VNC protokol a spustíte virtualizovaný stroj jako démona, ztratíte přístup k monitorovací konzoli a tím i možnost ovládat virtuální stroj ze strany hostitele! Abyste se této situaci vyhnuli, musíte na to při konfiguraci virtuálního stroje pamatovat a monitorovací konzoli přesměrovat.

Přesměrování monitorovací konzole lze nastavit volbou -monitor. QEMU umožňuje nastavit více monitorovacích konzolí, každá však funguje samostatně.

Přesměrování na standardní výstup

Lze provést přes parametr stdio. Jinak přesměrování ma standardní výstup je výchozí volba, pokud se virtuální stroj nepouští v grafickém módu, a s volbou -daemonize

Přesměrování na jinou systémovou konzoli

Lze provést přes parametr tty


Přesměrování na předem zvolený síťový port

Lze provést asi nejjednodušeji nastavením parametru telnet. Viz příklad konfigurace virtuálního stroje:

Poznámka
... -monitor telnet::1234,server,nowait ...

Popis parametrů:

  • Za parametrem telnet může (ale nemusí) být uvedena IP adresa, na které bude vyčkávat telnetový server. Není-li uvedena, použije se výchozí IP adresa hostitele, tedy nikoliv localhost!
  • Není-li za adresou uvedeno číslo portu, bude server vyčkávat na standardním čísle portu pro telnet ()
  • Bez parametru server lze pouze číst výstup, což v případě monitorovací konzole, přes kterou potřebujeme zadávat příkazy postrádá smysl. Tudíž na něj nesmíme zapomenout
  • Parametr nowait zase umožní, aby virtuální stroj nečekal na vaše připojení k monitorovací konzoli. Pokud na něj zapomenete, bude spuštění virtuálního stroje pozastaveno dokud se na monitorovací konzoli nepřipojíte.
Upozornění Pozor, pokud budete mít nakonfigurováno více monitorovacích rozhraní a u některého z nich na parametr nowait zapomenete, bude hostitel se spuštěním virtuálu vyčkávat, dokud se k tomuto rozhraní nepřipojíte!

Na monitorovací konzoli se lze pak lze vzdáleně připojit pomocí aplikace telnet:

Poznámka
user@stroj:~$ telnet <IP hostitele virtuálu> 1234
Trying <IP hostitele virtuálu>...
Connected to <IP hostitele virtuálu>.
Escape character is '^]'.
QEMU 0.13.50 monitor - type 'help' for more information
(qemu)

Jenže takové připojení není nijak zabezpečené a je vhodné maximálně na nějaké pokusy. Proto je lepší použít localhost a zabalit komunikaci do ssh protokolu...

Poznámka
... -monitor telnet:localhost:1234,server,nowait ...

Na monitorovací konzoli se pak lze vzdáleně připojit tak, že se zavolá telnet na vzdáleném stroji skrz ssh:

Poznámka
user@stroj:~$ telnet <IP hostitele virtuálu> 2345
Trying <IP hostitele virtuálu>...
telnet: Unable to connect to remote host: Connection refused
user@stroj:~$ ssh user@<IP hostitele virtuálu> "telnet localhost 2345"
user@<IP hostitele virtuálu>'s password: 
Trying ::1...
Connected to localhost.
Escape character is '^]'.
QEMU 0.13.50 monitor - type 'help' for more information
(qemu)

Pochopitelně podmínkou je, aby měl uživatel, který má mít k monitorovací kozoli přístup měl na hostitelském stroji uživatelský účet s povoleným ssh přístupem.

Presměrování monitorovací konzole do soketu

Pokud však na virtuálního hostitele přistupuje přes ssh více uživatelů a potřebujeme přístup k monitorovací konzoli omezit na úzce vymezený okruh uživatelů, je lepší přesměrovat komunikaci s monitorovací konzolí do unixového soketu. To lze provést přes parametr unix

Poznámka
... -monitor unix:/tmp/lokalni_soket,server,nowait ...

Parametry pro unixový soket:

  • Na rozdíl od připojení přes telnet se za parametrem unix uvádí cesta do adresáře ve kterém se má vytvořit soket (což je soubor typu soket)
  • Pro ostatní parametry server a nowait platí v plné míře to, co bylo uvedeno výše.

Na monitorovací konzoli, přesměrovanou na unixový soket, se pak lze vzdáleně připojit např. pomocí utility unixterm, která je součástí instalačního balíku vde2 (viz VDE v kapitole KVM (konfigurace sítě))

Poznámka
user@stroj:~$ ssh user@<IP hostitele virtuálu> "unixterm /tmp/lokalni_soket"
user@<IP hostitele virtuálu>'s password: 
QEMU 0.13.50 monitor - type 'help' for more information
(qemu)

Pochopitelně uživatel musí mít právo spouštět utilitu unixterm, a také právo zapisovat do vytvořeného soketu /tmp/lokalni_soket.

Monitorovací konzole

Je v podstatě příkazová řádka pro řízení virtuálního prostředí, ve kterém virtuální stroj běží.

Jejím prostřednictvím lze..

  • získávat nejrůznější informace o stavu virtuálního prostředí
  • přidávat či odebírat další zařízení
  • řídit virtuální stroj - spouštět, pozastavovat, zastavovat, vydávat příkazy pro migraci, atd.

Klasická monitorovací konzole je tzv. lidsky přístupná, ale pro skriptovatelné řízení je výhodnější použít QMP


Poznámka Monitorovací konzole přes QMP - qmp-shell

Součástí zdrojových kódů QEMU je také skript v pythonu qmp-shell, který funguje stejně jako monitorovací konzole, ovšem příkazy posílá přeformátované do JSON přes QMP soket

QMP

QMP (QEMU Monitor Protokol) je protokol založený na JSON, jehož prostřednictvím lze rovněž komunikovat s virtuálním prostředím, podobně jako přes monitorovací konzoli. Na rozdíl od ní však komunikace probíhá ve strojově zpracovatelném formátu, tudíž odpadá závislost druhotném zpracování návratové hodnoty příkazu, jak je tomu u klasické monitorovací konzole.

Upozornění QMP se objevilo v QEMU od verze 0.13 a jeho vývoj stále probíhá, proto je vhodné sledovat jeho aktuální dokumentaci .
Upozornění QMP a jeho použití s knihovnou libvirt

Jelikož QMP umožňuje přímý přístup k virtuálnímu stroji, je podpora přístupu přes QMP u knihovny libvirt defaultně vypnutá. Lze ji však při kompilaci této knihovny zapnout a pak přes knihovnu yayl komunikaci přes JSON používat.

Komunikace s QEMU konzolemi přes sokety

Interaktivní práce se sokety

Pro interaktivní přístup ke konzolím přes sokety, lze použít buď socat nebo jednoduchou utilitu unixterm, která je součástí nástrojů k vde2. Ovšem socat má mnohem větší možnosti, jak se ukáže posléze..

Otevření monitorovací konzole přes unixterm

Poznámka
stroj:~# unixterm /tmp/monitor.soket
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) ^Cstroj:~#

.. a stejná konzole přes socat

Poznámka
stroj:~# socat STDIO "/tmp/monitor.soket,crnl"
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) ^Cstroj:~#

Jak vidno, výstup vypadá, i funguje v obou případech stejně, ovšem nadále již budu popisovat práci pouze s aplikací socat, jelikož unixterm nelze používat pro neinteraktivní přístup.

Otevření QMP konzole přes socat..

Poznámka
patty:~# socat STDIO "/tmp/qmp.soket,crnl"
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 14, "major": 0}, "package": ""}, "capabilities": []}}
^Cstroj:~#
Poznámka Užitečný wrapper - rlwrap

Při interaktivní práci se sokety se hodí wrapper rlwrap. Aplikace unixterm, ani socat totiž nemají historii příkazů, která se však při interaktivní práci s konzolí hodí. A to je právě funkcionalita, kterou tato utilita zajistí.

Komunikace se sokety ve skriptu

Pro komunikaci se sokety ve skriptech je ideální socat, protože umožňuje (mimo jiné) přesměrovávat vstupy a výstupy i mezi sokety vzájemně.

Při neiteraktivní práci s konzolemi QEMU však narazíte na určité rozdíly. Při komunikaci přes QMP je totiž nutné nejprve odeslat příkaz, kterým se QMP komunikace zinicializuje a teprve potom vlastní příkaz. Viz níže..

Výstup příkazu odeslaného na monitorovací konzoli...

Poznámka
stroj:~# echo 'info pci' | socat - GOPEN:"/tmp/monitor.soket,crnl"
QEMU 0.14.50 monitor - type 'help' for more information
(qemu) 
(qemu) 
(qemu) info pci
  Bus  0, device   0, function 0:
    Host bridge: PCI device 8086:1237
      id ""
  Bus  0, device   1, function 0:
    ISA bridge: PCI device 8086:7000
      id ""
  Bus  0, device   1, function 1:
    IDE controller: PCI device 8086:7010
      BAR4: I/O at 0xc000 [0xc00f].
      id ""
  Bus  0, device   1, function 3:
    Bridge: PCI device 8086:7113
      IRQ 9.
      id ""
  Bus  0, device   2, function 0:
    VGA controller: PCI device 1013:00b8
      BAR0: 32 bit prefetchable memory at 0xf0000000 [0xf1ffffff].
      BAR1: 32 bit memory at 0xf2000000 [0xf2000fff].
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0000fffe].
      id ""
  Bus  0, device   3, function 0:
    Ethernet controller: PCI device 8086:100e
      IRQ 11.
      BAR0: 32 bit memory at 0xf2020000 [0xf203ffff].
      BAR1: I/O at 0xc040 [0xc07f].
      BAR6: 32 bit memory at 0xffffffffffffffff [0x0001fffe].
      id ""
  Bus  0, device   4, function 0:
    RAM controller: PCI device 1af4:1002
      IRQ 11.
      BAR0: I/O at 0xc080 [0xc09f].
      id ""
(qemu) 
(qemu) stroj:~#

Výstup příkazu odeslaného na QMP konzoli...

Poznámka
patty:~# echo -e '{ "execute": "qmp_capabilities" }\n{ "execute": "query-pci" }' \
 | socat - GOPEN:"/tmp/qmp.soket,crnl"
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 14, "major": 0}, "package": ""}, "capabilities": []}}
{"return": {}}
{"return": [{"bus": 0, "devices": [{"bus": 0, "qdev_id": "", "slot": 0, "class_info": 
{"class": 1536, "desc": "Host bridge"}, 
"id": {"device": 32902, "vendor": 4663}, "function": 0, "regions": []}, 
{"bus": 0, "qdev_id": "", "slot": 1, "class_info": {"class": 1537, "desc": "ISA bridge"}, 
"id": {"device": 32902, "vendor": 28672}, "function": 0, "regions": []}, 
{"bus": 0, "qdev_id": "", "slot": 1, "class_info": {"class": 257, "desc": "IDE controller"}, 
"id": {"device": 32902, "vendor": 28688}, "function": 1, "regions": [{"bar": 4, "size": 16, 
"address": 49152, "type": "io"}]}, {"bus": 0, "qdev_id": "", "irq": 9, "slot": 1, 
"class_info": {"class": 1664, "desc": "Bridge"}, "id": {"device": 32902, "vendor": 28947}, 
"function": 3, "regions": []}, {"bus": 0, "qdev_id": "", "slot": 2, "class_info": 
{"class": 768, "desc": "VGA controller"}, "id": {"device": 4115, "vendor": 184}, 
"function": 0, "regions": [{"prefetch": true, "mem_type_64": false, "bar": 0, "size": 33554432, 
"address": 4026531840, "type": "memory"}, {"prefetch": false, "mem_type_64": false, 
"bar": 1, "size": 4096, "address": 4060086272, "type": "memory"}, {"prefetch": false, 
"mem_type_64": false, "bar": 6, "size": 65536, "address": -1, "type": "memory"}]}, {"bus": 0, 
"qdev_id": "", "irq": 11, "slot": 3, "class_info": {"class": 512, "desc": 
"Ethernet controller"}, "id": {"device": 32902, "vendor": 4110}, "function": 0, 
"regions": [{"prefetch": false, "mem_type_64": false, "bar": 0, "size": 131072, 
"address": 4060217344, "type": "memory"}, {"bar": 1, "size": 64, "address": 49216, "type": "io"}, 
{"prefetch": false, "mem_type_64": false, "bar": 6, "size": 131072, 
"address": -1, "type": "memory"}]}, {"bus": 0, "qdev_id": "", "irq": 11, "slot": 4, 
"class_info": {"class": 1280, "desc": "RAM controller"}, "id": {"device": 6900, "vendor": 4098}, 
"function": 0, "regions": [{"bar": 0, "size": 32, "address": 49280, "type": "io"}]}]}]}
stroj:~#

Jak je vidno z příkladů, příkazy, které se zadávají přes monitorovací konzoli lze zadávat i přes QMP, ovšem jejich názvy nejsou zcela identické. Jaké příkazy lze přes JSON aktuálně použít, lze zjistit zavoláním příkazu query-commands..

Poznámka
stroj:~# echo -e '{ "execute": "qmp_capabilities" }\n{ "execute": "query-commands" }' \
 | socat - GOPEN:"/tmp/qmp.soket,crnl"
...


Migrace

KVM umožňuje migrování virtuálních strojů za běhu. Aby to však bylo možné, musí být splněny patřičné podmínky. Především ta, že na výchozím i cílovém stroji musí být schopen virtuální stroj běžet v identické konfiguraci. To znamená že:

  • Virtuální CPU musí být při spuštění nakonfigurován tak, aby oba stroje byly schopny vyhovět požadavků virtuálu. Jaké procesor podporuje "flags", lze zjistit výpisem souboru /proc/cpuinfo na obou virtualizačních strojích. "Flags", které instrukční sada jednoho z procesorů nepodporuje, je třeba zakázat.
  • Oba stroje musí mít zajištěnou konektivitu do stejného síťového segmentu ve kterém má být virtuál dostupný. V ideálním případě to znamená mít na obou strojích shodně nastavené síťování, což s VDE není žádný problém - viz kapitola KVM (konfigurace sítě).
  • Image virtuálního stroje by měl být zároveň dostupný na obou strojích, tzn. že by měl být umístěn v rámci clusterového řešení souborového systému (GFS2, OCFS2, CEPH, Lustre,..) či zařízení (RADOS), které umožňuje současný přístup k témuž souboru z více přípojných bodů.
  • Spuštěný virtuální stroj musí mít dostupnou monitorovací konzoli, přes kterou jej lze řídit. V níže uvedeném příkladu čeká na TCP portu číslo 2345, v praxi je však bezpečnější komunikaci zabalit do ssh připojení. Viz výše.

Vlastní průběh migrace je pak již docela triviální.

Na cílovém stroji, kam má být virtuál přesunut, se spustí ve stejné kombinaci jako na zdroji, pouze s tím rozdílem, že se přidá volba -incoming s patřičnými parametry. QEMU na cílovém stroji tak bude vyčkávat, dokud nedostane od zdroje pokyn, že má místo něj pokračovat ve virtualizaci.

Vlastní migrace pak odstartuje přes monitorovací konzoli příkazem migrate.

Snapshoty

Snapshoty se provádí v podstatě úplně stejně jako migrace. Rozdíl je pouze v tom, že cílem migrace nemusí být jiný stroj, ale soubor.