Virtualizzare Linux con lguest
Introduzione
In questo articolo parlerò nuovamente di una funzione del kernel Linux: se nell’articolo precedente era kexec, in questo sarà lguest.
lguest non è altro che un hypervisor molto leggero (circa 5000 linee di codice), che permette in modo molto semplice di creare un sistema di paravirtualizzazione (non permette una virtualizzazione completa) con Linux (che è l’unica architettura supportata).
È formato da due parti distinte, una parte kernel, rappresentata da un modulo ‘lg’ (è anche possibile compilarlo direttamente nel kernel) che si occupa del lavoro sporco e una parte user-space, l’hypervisor.
Funzionamento
Il funzionamento di lguest è abbastanza semplice da comprendere, in quanto non impiega nessuna tecnica speciale come fanno altri sistemi tipo Xen.
Il cuore di tutto sta nel modulo del kernel che si occupa innanzitutto di allocare una porzione di meoria dinamica del kernel, in cui viene caricato un piccolo hypervisor incaricato di spostarsi dal kernel al sistema guest. Il processo di paravirtualizzazione viene compiuto grazie all’implementazione di paravirt_ops, che deve essere compilato nel kernel da eseguire come guest. Il modulo del kernel si occupa anche di fornire un’interfaccia tramite un file speciale posizionato in /dev/lguest. Il client in user-space, per creare un sistema guest, dovrà semplicemente scrivere un comando di inizializzazione in quel file indicando alcuni valori, come ad esempio dove trovare il kernel e la porzione di memoria da utilizzare.
A questo punto il client in user-space si occupa di allocare un tot di memoria virtuale che poi sarà mappata nel sistema guest come memoria fisica. In questa porzione viene caricato il kernel virtualizzato e poi l’user-space guest (in pratica il filesystem di root del sistema virtualizzato). Un semplice file può essere utilizzato per fornire al sistema guest un’immagine di un disco gestito dal client che si dovrà preoccuperà di spostare blocchi di dati nella memoria dinamica. Per quanto riguarda la rete, il creatore di lguest consiglia di utilizzare una periferica TAP configurata sul sistema host.
Per far partire il sistema guest, lg modifica opportunamente la page tables del kernel, per fare in modo che il sistema guest appena caricato
Bene o male questo è il funzionamento di lguest. Vediamo ora come mettere queste cose in pratica.
Root Filesystem
Iniziamo subito con la creazione di quello che sarà il filesystem di root del sistema guest. Sconsiglio vivamente di utilizzare una partizione esistente in quanto potrebbero sorgere problemi gravi.
Con questo procedimento verrà creato un sistema Debian da zero. È anche possibile trovare in rete immagini di altri sistemi (per quanto ne sappia, il team di Gentoo fornisce immagini di dischi con la distro preinstallata).
Prima di tutto creiamo il file nel quale verrà installato il sistema, come dimensione 1G dovrebbe bastare:
$ dd if=/dev/zero of=debian.img bs=1 count=1 seek=1G
Creiamo il filesystem:
# mke2fs -j -v debian.img
E montiamolo:
# mkdir /mnt/virtual # mount debian.img /mnt/virtual -o loop
(potrebbe essere necessario caricare il modulo per il loopback)
Per installare il sistema base utilizzeremo un tool, debootstrap, che si occupa di scaricare e installare i pacchetti basilari per il nostro sistema. Dopo averlo installato:
# debootstrap --verbose --arch i386 squeeze /mnt/virtual http://debian.fastweb.it/debian
Potete ovviamente configurarlo come volete, modificando l’architettura, la versione di debian e il repository da cui prelevare i pacchetti.
Ora abbiamo un sistema perfettamente funzionante, ma che richiede alcune configurazioni aggiuntive prima di poter essere utilizzato con lguest.
Perciò la prima cosa da fare è entrare nel sistema con chroot:
# chroot /mnt/virtual
Da cui:
# apt-get update
Per una configurazione terra terra (orario + lingua + password root):
# dpkg-reconfigure tzdata # apt-get install locales # dpkg-reconfigure locales # passwd root
Ora è necessario creare un device a blocchi che verrà utilizzato come console virtuale:
# mknod hvc0 c 229 0
e fare in modo che parta all’avvio modificando il file inittab:
# nano /etc/inittab
cambiando le linee che regolano l’avvio dei terminali:
1:2345:respawn:/sbin/getty hvc0 #2:2345:respawn:/sbin/getty tty2 #3:2345:respawn:/sbin/getty tty3 #4:2345:respawn:/sbin/getty tty4 #5:2345:respawn:/sbin/getty tty5 #6:2345:respawn:/sbin/getty tty6
Per finire creiamo un nuovo utente (chiamatelo pure come vi pare):
# adduser user
E poi usciamo
# exit
Kernel
Il modo più semplice per eseguire lguest, come suggerisce il creatore stesso, è utilizzare lo stesso kernel sia come host che come guest.
Abbiamo però bisogno di una configurazione particolare, quindi verificate le seguenti impostazioni nel vostro kernel (se non sono presenti ricompilate):
CONFIG_EXPERIMENTAL=y CONFIG_PARAVIRT=y CONFIG_LGUEST_GUEST=y CONFIG_HIGHMEM64G=n CONFIG_PHYSICAL_ALIGN=0x100000 CONFIG_VIRTIO_BLK=m CONFIG_VIRTIO_NET=m CONFIG_TUN=m CONFIG_LGUEST=m
Nella cartella del kernel ‘Documentation/lguest’ è presente il client user-space, se non è stato compilato con il kernel, digitate ‘make’.
A questo punto abbiamo tutto il necessario per avviare lguest.
Let’s virtualize
Per prima cosa è necessario caricare il modulo del kernel
# modprobe lg
Dopodichè, sempre dalla cartella di lguest
# ./lguest [mem] [kernel] --tunnet=[ip] --block=[rootfile] root=/dev/vda
Dove:
- [mem] indica la quantità di memoria da utilizzare in MB
- [kernel] il percorso del kernel da usare
- [ip] l’indirizzo di rete da attribuire al sistema guest
- [rootfile] il file da usare come root
Dopo aver definito root, è possibile indicare altri valori da passare al kernel.
Un esempio di utilizzo:
# ./lguest 64 /boot/vmlinuz-`uname -r` --tunnet=192.168.1.38 --block=debian.img root=/dev/vda ro quiet
debian.img starebbe ad indicare il file che abbiamo creato prima, mentre come kernel è stato impostato quello attualmente in uso.
Se tutto è andato per il verso giusto, il nuovo kernel dovrebbe partire.
Conclusione
La caratteristica più interessante di lguest è senza dubbio la sua facilità di comprensione e di utilizzo. Essendo scritto in quasi 5000 righe di codice non ha certo funzionalità avanzate da farlo competere con altri grossi progetti di virtualizzazione come Xen o KVM ma è senza dubbio un ottimo punto di partenza per meglio comprendere la virtualizzazione. E comunque non si può certo dire che su Linux manchino soluzioni per la virtualizzazione.
AlexBio's Blog

No Comments Yet