Quando ero ragazzo, se volevo studiare un sistema operativo, dovevo installarlo nel computer e probabilmente distruggere tutti i miei dati finché non capivo come funzionava.
Ricordo una legge di Murphy che diceva: “La preparazione tecnica di un sistemista è direttamente proporzionale ai danni subiti dal suo sistema”.
Oggi per fortuna è possibile simulare praticamente qualunque cosa.
Per esempio, puoi creare quattro macchine virtuali in un computer, quattro in un altro e farle comunicare tra loro, simulando uno scambio di dati tra due data-center.
Questi sistemi ormai sono talmente affidabili, che l'unica differenza apprezzabile rispetto ad una macchina reale, è nelle prestazioni. Non è un caso che Cloud e Cluster ormai sono strettamente connessi con le virtualizzazioni e le containerizzazioni.
Per quanto riguarda le implementazioni, esistono molte soluzioni e la maggioranza possono essere usate a livello professionale. Io ne ho installate diverse, ma la mia preferita, quando devo studiare o testare qualcosa, è KVM (Kernel-based Virtual Machine). KVM, è un'infrastruttura che si innesta nel kernel di Linux e permette di implementare la virtualizzazione da parte di altri software.
Per ottenere questo risultato sfrutta Intel VT (Intel Virtualization Technology) o AMD-V (AMD Virtualization).
KVM ha, in diversi casi, anche il supporto alla paravirtualizzazione, che non è una vera e propria virtualizzazione, ma è un sistema di condivisione dell'hardware gestito dal kernel ed è molto usato ad esempio per le schede di rete, migliorando le prestazioni del sistema virtualizzato.
Per contro, il crash di un dispositivo paravirtualizzato in una macchina virtuale può provocare crash anche nelle altre. Per implementare questo tipo di soluzione il kernel ospitante deve essere modificato, da qui la necessità di un'infrastruttura a livello kernel.
Naturalmente, non esiste solo KVM, esistono anche altre soluzioni e tra le più famose ci sono: LXC, OpenVZ, Xen. Queste seguono gli stessi principi, per poi dividersi nei dettagli e nelle implementazioni, a volte per ragioni storiche a volte per esigenze e obiettivi diversi.
Come dicevo, questa infrastruttura si trova a livello del kernel e per usarla bisogna “mandare qualcuno a parlarci”. Ossia ci vuole un software specifico, e di solito quando ci vuole un software ci vogliono anche delle librerie. Sto parlando di Libvirt.
Esistendo diverse implementazioni a livello kernel, esistono anche specifiche chiamate di sistema per ogni implementazione.
I programmatori si troverebbero quindi, costretti ad imparare ogni chiamata di KVM o di OpenVZ, o di qualunque altra implementazione. Libvirt risolve questo problema unificando queste chiamate e creando astrazione. Il programmatore può in questo modo disinteressarsi della specifica implementazione, concentrandosi sul suo progetto.
Libvirt è composta di un'API (Advanced Programming Interface), un daemon e un tool di management, così come dei wrapper, che permettono di comunicare con la libreria attraverso linguaggi ad alto livello come Python, Perl, Ocaml, Ruby, Java, Javacript (via Node.js) e PHP.
I tool di management più famosi sono virsh (a linea di comando) e virtual machine manager (grafico).
Veniamo all'ultimo pezzo del nostro puzzle: abbiamo bisogno di un componente software che attraverso la libreria libvirt vada a parlare per nostro conto con KVM; questo pezzo si chiama hypervisor e si trova tra il tool di management e KVM.
Ossia: noi parliamo col tool di management, il tool parla con l'hypervisor e l'hypervisor attraverso le libreria comunica con KVM; il nostro stack è così completo.
Nomi di hypervisor comunemente utilizzati sono: LXC, OpenVZ, QEMU, Xen, Virtualbox, VMWare. Quello che uso io, per i miei test nel portatile è QEMU.
Dopo tutta questa prosopopea, possiamo finalmente fare un elenco delle funzionalità di KVM:
  • Over-committing: il sistema può allocare più CPU virtualizzate di quelle realmente esistenti.
  • Thin provisioning: permette di allocare lo spazio in modo flessibile per ogni virtual machine.
  • Disk I/O throttling: permette di impostare un limite alle richieste di I/O del disco mandate dalle VM alla macchina ospitante.
  • Virtual CPU hot add capability: permette di aumentare la potenza del processore    “a caldo” cioè mentre la virtual machine è in funzione.
  • Automatic NUMA balancing: aumenta le prestazioni delle applicazioni che girano su sistemi di tipo NUMA.
Per chi se lo stesse chiedendo, non stiamo parlando di Mauro Numa, campione italiano di fioretto, né di Shozo Numa, famoso scrittore giapponese di fantascienza autore del libro Kachikujin yapū, da cui è stato tratto il manga “Yapoo – Il bestiame umano”, racconto con sfumature sadomaso del quale immagino l'umanità non potesse fare a meno. No! Parliamo della “Non-Uniform Access Memory”, architettura di memoria sviluppata per sistemi multiprocessore studiata appositamente per velocizzare l'apporto di dati ai processori da parte delle memorie.
Una curiosità: questa tecnologia venne sviluppata in Italia negli anni '80, quando ci si occupava ancora di informatica e in Italia si trovavano tra i computer più veloci del pianeta. So che fa caldo, ma non divaghiamo!
Per installare tutto questo popò di roba dovete innanzitutto verificare che il vostro processore abbia “competenze virtuali”, cioè le tecnologie di virtualizzazione di cui sopra:
per sistemi intel: grep --color 'vmx' /proc/cpuinfo, mentre per sistemi amd: grep –color 'svm' /proc/cpuinfo
Se non appare niente, potrebbe darsi che queste estensioni siano disabilitate nel bios o che il vostro processore non supporti la virtualizzazione. lsmod | grep kvm vi informa se il modulo kvm è stato caricato. Deve mostrare kvm, kvm_intel o kvm_amd.
I nomi dei pacchetti cambiano a seconda della distribuzione, su internet è abbastanza facile trovare l'elenco, in generale dovete installare quelli concernenti virt-manager, libvirt, qemu e avviare il daemon libvirtd se non è già attivo.
Per una spiegazione dettagliata su questi software è necessario un articolo specifico. Magari la prossima volta.