Virtualizzazione a livello di sistema operativo
# Virtualizzazione a livello di sistema operativo

Virtualizzazione a livello di sistema operativo (detta anche OS-level virtualization o anche containerization) è un termine preso in prestito dai sistemi di virtualizzazione per indicare un metodo di esecuzione delle applicazioni che isola le risorse hardware e software in uso da ognuna di esse, pur sempre all'interno di un solo e unico sistema operativo. Più precisamente questo viene realizzato mediante la creazione di container, cioè più istanze user space isolate tra di loro. Rispetto alla tradizionale virtualizzazione, qui si osserva la completa assenza delle cosiddette macchine virtuali e dei rispettivi sistemi operativi guest.

## Descrizione

Un programma in esecuzione in un tradizionale sistema operativo può vedere tutte le risorse hardware e software disponibili (CPU, periferiche, cartelle, file, ecc.), mentre un programma in esecuzione all'interno di un container è "isolato" nel senso che può vedere solo le risorse che sono state assegnate a quel container. Sui sistemi operativi Unix-like questa funzione può essere vista come un'implementazione avanzata del meccanismo chroot, utilizzato comunemente per modificare la cartella root per il processo attualmente in esecuzione e i suoi figli. Il kernel fornisce inoltre una funzione di isolamento che limita le interferenze tra le attività che si svolgono un container e l'altro. Spesso le istanze user space sono chiamate container (in Docker), ma ogni sistema può specificare dei nomi diversi, come:

* Zone (in Solaris)
* Virtual Environment (VE)
* Virtual Kernel (in Dragonfly BSD)
* Jail (in FreeBSD)

Purtroppo in alcuni casi il termine "container" viene usato in modo ambiguo per indicare anche ambienti di virtualizzazione completa e tradizionale, all'interno di un sistema operativo host, come i cosiddetti "Hyper-V Containers" di Microsoft.

## Vantaggi nelle prestazioni

Rispetto alla tradizionale virtualizzazione completa (full-virtualization) si può osservare:

* Avvio più rapido delle applicazioni, per assenza della macchina virtuale e del sistema operativo guest.
* Maggiore efficienza e minore carico di lavoro per la CPU (overhead) per assenza di un software hypervisor e dei sistemi operativi guest.

## Gestione delle risorse

Le risorse disponibili su un sistema operativo tradizionale sono:

* Hardware (come la CPU, le periferiche, ecc.)
* Software (come file, cartelle, ecc.)

Normalmente, sui sistemi operativi l'accesso a queste risorse è consentito ad ogni programma, in base al tipo di processo e in base all'utente che ha avviato il processo. All'interno di un container, invece, si può limitare ulteriormente la visibilità delle risorse solo ai processi eseguiti al suo interno. Ogni container può essere quindi un ambiente di esecuzione isolato, ed inoltre al suo interno possono essere eseguiti più processi che possono eventualmente interagire tra loro

## Flessibilità

Le diverse istanze di container devono essere create all'interno di un sistema operativo, il quale fornisce il kernel, che viene condiviso con tutti i container. Questo significa che, ad esempio, se si utilizza un sistema con kernel Linux, allora si potranno eseguire nei container esclusivamente programmi compatibili con il kernel Linux. Vi sono alcune eccezioni a questa limitazione, come nel kernel Illumos che dispone di una funzione Branded Zone, che permette di eseguire anche lo user space Linux.

## Archiviazione dei dati

Il file system è quella risorsa che permette di organizzare e gestire i dati sotto forma di file e cartelle. Questo può essere condiviso da tutte le applicazioni (anche quelle che si trovano in diversi container) e in tal caso, se un'applicazione modifica un file, in realtà se ne crea una copia e si modifica solo quella (strategia copy-on-write). Questo sistema che si rivela più efficiente rispetto alla creazione di un nuovo file system, come avviene in una tradizionale macchina virtuale (full-virtualization). Rimane comunque la limitazione simile a quella vista sul kernel, per cui usando i container può lavorare solo sullo stesso tipo di file system presente nel sistema operativo della macchina fisica. Una buona regola è quella di consentire ad ogni container di avere accesso solo ad una sottocartella, invece che all'intero file system.

## Implementazioni

Per ottenere la virtualizzazione a livello di sistema operativo si possono utilizzare diverse applicazioni, come:

* chroot
* Docker
* LXC
* OpenVZ
* Virtuozzo
* Singularity
* Solaris Containers
* FreeBSD Jail
* vkernel
