Virtualizzazione basata su container: OpenVZ

Guida da adottare! Bannermv.png



Document-page-setup.png Attenzione: questo articolo è ancora incompleto e in fase di scrittura da parte del suo autore.

Sentitevi liberi di contribuire, proponendo modifiche alla guida tramite l'apposita pagina di discussione, in modo da non interferire con il lavoro portato avanti sulla voce. Per altre informazioni si rimanda al template.



Introduzione

Già da un po' di tempo si fa un gran parlare di virtualizzazione, e sono nati già parecchi prodotti software che implementano questo concetto in modi anche molto differenti. Possiamo individuare almeno tre tipi distinti di virtualizzazione:

  • emulazione
  • paravirtualizzazione
  • virtualizzazione nativa


Emulazione

In emulazione, il sistema di virtualizzazione simula tutto l'hardware su cui viene installato il sistema operativo ospite, detto guest: questo sistema ha il vantaggio di poter ospitare in modo relativamente semplice molti tipi di sistemi operativi guest senza la necessità di modificarli, anche differenti dal sistema operativo host (quello di base), a costo di un certo consumo di risorse (overhead) causato dallo strato software aggiuntivo necessario. Software di questo tipo sono Qemu, KVM, VirtualBox, VMware.

Per migliorare le prestazioni di questi sistemi ne sono state pensate tante. Il primo ad aver pubblicato qualcosa di utile, ed è subito diventato famoso per questo, è stato Fabrice Bellard con il suo Qemu, che implementa la cosiddetta dynamic translation. L'idea di fondo è piuttosto semplice: dal momento che nella grande maggioranza dei casi si finisce per emulare la stessa CPU su cui sta girando il sistema host, risulta molto più veloce passare le istruzioni al vero processore e recuperare i risultati, emulando solo quando è strettamente necessario.
In ogni caso, sempre alla ricerca di prestazioni, tutti questi emulatori hanno finito per portare parte del loro codice al livello kernel: questo significa che il sistema host necessita di un kernel leggermente modificato (di solito è sufficiente l'aggiunta di un modulo o due).

Paravirtualizzazione

Se da un lato la virtualizzazione ha subito suscitato un forte interesse in ambito enterprise, soprattutto dal momento che l'hardware disponibile iniziava ad essere sufficientemente potente, dall'altro l'overhead causato dalla virtualizzazione andava ad impattare ancora parecchio sulle performance generali, e questo significa che una fetta della spesa effettuata per acquistare hardware veniva vanificata dal semplice uso della virtualizzazione.

Per migliorare la situazione è stato sviluppato il concetto di paravirtualizzazione, in cui il software di virtualizzazione, detto Hypervisor, non emula completamente l'hardware, ma si limita ad offrire una speciale interfaccia ottimizzata ai sistemi operativi guest. Le prestazioni migliorano, ma per interfacciarsi con l'hypervisor si rendono necessarie modifiche profonde al kernel dei sistemi guest: per risparmiare sull'acquisto di hardware ci si sobbarca una grossa mole di lavoro in termini di programmazione al livello kernel, sia dal lato host che da quello guest.

Xen è il principale prodotto ad utilizzare questo tipo di approccio.

Virtualizzazione nativa

Seguendo ancora la strada del risparmio economico, e quindi la riduzione dell'overhead, la virtualizzazione nativa rinuncia completamente alla possibilità di far funzionare sistemi guest di tipo differente da quello usato per l'host. In pratica, l'hypervisor è sostituito da un vero e proprio kernel, modificato in modo da poter gestire in modo estremamente efficiente diversi sistemi operativi guest semplicemente ospitati in container differenti. Dal punto di vista pratico, i file dei sistemi guest risiedono semplicemente in differenti directory, mentre il loro spazio di memoria viene mantenuto isolato dal kernel. Il kernel e i programmi di base necessari per far funzionare l'host vengono in questo modo condivisi dai guest, e l'overhead viene normalmente limitato all'1-3%.

OpenVZ implementa questo concetto con host e guest Linux.


Scenario

Un cliente ha richiesto l'installazione di un piccolo server per ospitare un'applicazione web di tipo groupware, dedicata ad una rete LAN privata.

Per motivi di scalabilità del sistema è stato deciso, di comune accordo con il cliente, di utilizzare un sistema di virtualizzazione: questo permetterà di effettuare backup e/o upgrade hardware in modo semplice. Inoltre, questa soluzione consente di iniziare l'installazione della macchina virtuale ancora prima di avere il server sotto mano, utilizzando il mio portatile come host.

Sul portatile ho una Debian Squeeze/Sid con un kernel recente non ancora supportato dal progetto, e poi il sistema che ho installato a suo tempo è a 32 bit, mentre ora che devo rinnovare vorrei sfruttare l'architettura x86_64. D'altro canto però ho modo di liberare facilmente una partizione abbastanza grande, quindi installerò il nuovo sistema da zero usando l'installer di Debian Lenny per amd64, versione 5.0.4 (quella attuale).

Ah, il sistema di virtualizzazione scelto, naturalmente, è OpenVZ ;-)

Installazione

Per prima cosa mi serve un'immagine di un cd di installazione da scrivere su un CD: una netinstall o il CD n. 1 vanno benissimo.

Dovendo installare da zero su di un portatile mi sono preoccupato di procurarmi preventivamente il firmware della scheda wifi: l'installer Debian è in grado di caricare il firmware da un archivio posto per es. in una chiavetta USB, come indicato chiaramente nel manuale di installazione.

Partizioni

È fortemente raccomandato di mantenere i file delle macchine virtuali in una partizione separata rispetto alla partizione di root, perchè in certi casi una macchina virtuale potrebbe riempire tutto lo spazio disponibile nella partizione: se questa fosse la root tutto il sistema andrebbe in blocco, e questo non sarebbe bello -_-

In fin dei conti, per questa installazione mi servono 3 partizioni:

  • partizione di root: se fossimo su un server ci dovrebbe entrare solo il sistema di base, quindi 1GB basterebbe ampiamente. Sul mio portatile invece riserverò per la root ~12 GB.
  • partizione per i container: qui staranno i file delle macchine virtuali, quindi più spazio c'è meglio è, tenendo presente che un'installazione di tipo server senza componenti grafici, esclusi i dati utente, solitamente occupa meno di 1 GB
  • partizione di swap: quella che ho già va benissimo, ma in caso si dovesse creare da zero è consigliata una dimensione doppia rispetto a quella della RAM installata
  ATTENZIONE
Per poter disporre delle quote disco, OpenVZ si appoggia alla gestione delle quote del filesystem sottostante: filesystem supportati sono attualmente ext2, ext3 mentre ext4 solo dal kernel 2.6.32


Se le quote disco non interessano si può scegliere il filesystem che si preferisce.
Per la partizione di root invece la scelta è libera: io userò ext3 anche per la root, ma se preferite potete fare diversamente.

Configurazioni iniziali

Dopo aver installato il sistema base, che questo sia un sistema minimale o un sistema desktop, prima di poter iniziare ad utilizzare OpenVZ dovremo installare:

  • un kernel con la patch OpenVZ
  • i necessari programmi per la creazione, la distruzione e il controllo delle macchine virtuali

La patch OpenVZ non è ancora entrata nel kernel Linux (non so se ci entrerà mai) e viene supportato solo un numero molto limitato di kernel.

Kernel stabili

RHEL4
basato sul kernel di Red Hat Enterprise Linux 4, a sua volta basato sul kernel 2.6.9
RHEL5
basato sul kernel di Red Hat Enterprise Linux 5, a sua volta basato sul kernel 2.6.18
2.6.18
basato sul kernel 2.6.18 vanilla, quindi senza i backport e le patch di sicurezza approtati da Red Hat: questo kernel è pensato per distro che mantengono il proprio patchset (insieme di patch) di sicurezza, come Debian

Kernel di sviluppo

2.6.24
basato sul kernel 2.6.24 vanilla
2.6.26
basato sul kernel 2.6.26 vanilla
2.6.27
basato sul kernel 2.6.27 vanilla

Note sulle versioni del kernel

Gli sviluppatori OpenVZ consigliano, per le installazioni server, il kernel RHEL5.

  Nota sul kernel n.1
I kernel utilizzati da distribuzioni diverse, a parità di versione del kernel vanilla da cui derivano possono in genere essere utilizzati su qualunque altra distribuzione.
  Nota sul kernel n.2
Non bisogna però dimenticare che il gestore dei pacchetti, APT nel caso di Debian, conosce esattamente quali versioni di quali pacchetti sono necessari per far funzionare un kernel, ma solo se quest'ultimo è stato precedentemente pacchettizzato per Debian


Di conseguenza, se si decidesse di installare un kernel non Debian è necessario verificare quali sono i pacchetti di cui necessita, e nel caso installarli a mano.

Purtroppo il mio portatile è decisamente più recente del kernel 2.6.18, e molto probabilmente non riuscirei a far funzionare correttamente alcune periferiche, come la scheda video e la scheda WiFi, i cui driver sono stati introdotti in kernel successivi.
D'altro canto, per Debian Lenny 5.0 esiste un kernel 2.6.26 già pacchettizzato pronto da installare, quindi opterò per questa soluzione.

  Nota sul kernel n.3
E' stato da poco annunciato l'inizio dei lavori per il supporto ufficiale del kernel 2.6.32, che sarà anche il kernel di Debian Sqeuuze, e probabilmente anche di RHEL6, quindi: stay tuned ;-)


Installazione dei pacchetti

E' presto fatto:

# aptitude install linux-image-2.6-openvz-$(dpkg --print-architecture) vzctl vzdump vzquota

questo installerà anche alcuni altri pacchetti necessari, come rsync e iproute. Ora non resta che riavviare con il nuovo kernel.

Verifica dell'installazione

1. Kernel:

# uname -r
2.6.26-1-openvz-amd64
#

se avete seguito la procedura descritta e il nome del kernel non contiene "openvz" avete avviato il kernel sbagliato: eventualmente rigenerate il menu di grub con update-grub e riavviate con il kernel giusto ;-)

2. interfaccia OpenVZ in kernel space:

# ps ax | grep vz
2349 ?        S      0:00 [vzmond]

se questo non appare allora il kernel in uso non ha il supporto per OpenVZ attivato: qualcosa non ha funzionato durante l'installazione del kernel.

3. Un'interfaccia di rete per i container:

# ifconfig
venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

anche questa volta, se questo non appare il kernel in uso non ha il supporto per OpenVZ attivato (vedi sopra).


Installazione di una macchina virtuale

Entriamo ora nel vivo della questione: installiamo una macchina virtuale.

Template

Come abbiamo già visto, una macchina virtuale OpenVZ non permette di utilizzare un sistema operativo immodificato, perchè il kernel e le librerie di base vengono installate solo nella macchina fisica, e condivise tra questa e tutte le macchine virtuali. Questo però significa anche che per costruire un sistema operativo in grado di funzionare correttamente in una siffatta macchina virtuale è necessario togliere da esso alcuni pacchetti fondamentali e disattivare alcune funzionalità di base, che saranno appannaggio esclusivo del sistema host. Per semplificarci la vita, però, il team di sviluppo di OpenVZ e la comunità che gravita attorno al progetto, mettono a disposizione una serie di template pronti all'uso.

Un template è in pratica una piccola distribuzione preinstallata, e nella pagina di download ne esistono veramente per tutti i gusti. Io userò un template di Debian 5.0.4 (Lenny), la attuale stable.

$ cd /var/lib/vz
$ wget http://download.openvz.org/template/precreated/debian-5.0-x86.tar.gz
  ATTENZIONE
Non decomprimere il template: verrà decompresso in automatico al momento opportuno.


vzctl create <VE_ID> --ostemplate debian-6.0-amd64-minima --hostname <Hostname> --ipadd <ip_address>




Guida scritta da: Tindal   Debianized 20%
Estesa da:
Verificata da:

Verificare ed estendere la guida | Cos'è una guida Debianized