# Virtualizzazione

La virtualizzazione è una tecnologia che consente a un software, denominato `hypervisor`, di eseguire processi che emulano un sistema informatico completo. Questo software crea e gestisce VM (VM), definite *guest* dell'hypervisor. Le VM sono ambienti isolati in grado di eseguire sistemi operativi e applicazioni come se fossero computer fisici separati.

Esistono due categorie principali di hypervisor:

- `HV di tipo 1` (`bare-metal`) vengono eseguiti direttamente sull'hardware fisico, senza la necessità di un sistema operativo sottostante. Questi hypervisor gestiscono direttamente le risorse hardware, offrendo prestazioni superiori e una maggiore efficienza. Esempi di hypervisor di tipo 1 includono VMware ESXi, Microsoft Hyper-V e Proxmox
- `HV di tipo 2` (`hosted`): operano su un sistema operativo esistente. Esempi di hypervisor di tipo 2 includono VMware Workstation, VirtualBox. ecc

Tra gli hypervisor più diffusi nel contesto Linux, si possono citare:

- `Xen`, un hypervisor di tipo 1 ampiamente utilizzato in ambienti di cloud computing
- `KVM` (*Kernel Virtual Machine*), un modulo del kernel Linux che permette la virtualizzazione. KVM può essere considerato sia un hypervisor di tipo 1 che di tipo 2, a seconda della configurazione. Le VM create tramite KVM utilizzano il demone *libvirt* per la loro gestione. `qemu` è il software su cui si basano le VM gestite da KVM, che all'hypervisor gli strumenti necessari per emulare i dispositivi hardware utilizzati dalle VM

## VM

Le VM possono essere classificate in tre categorie principali:

- `completamente virtualizzate`: sono quelle VM in cui il sistema operativo guest non è consapevole di essere un'istanza virtuale in esecuzione. In questo scenario, l'hypervisor emula completamente l'hardware, consentendo al guest di operare come se fosse installato su un computer fisico. Per le CPU x86, è necessario abilitare le estensioni di virtualizzazione, come VT-x per le CPU Intel e AMD-V per le CPU AMD, affinché la virtualizzazione funzioni correttamente
- `paravirtualizzate`: al contrario, sono progettate in modo tale che il sistema operativo guest sia consapevole della sua esecuzione in un ambiente virtuale. Questi guest utilizzano driver speciali, noti come *guest driver*, per interagire con le risorse hardware e software dell'hypervisor
- `ibride`: combinano elementi delle due precedenti tipologie. In un ambiente ibrido, alcune parti del sistema operativo guest possono essere paravirtualizzate, mentre altre possono essere completamente virtualizzate

### Immagini disco

I tipi principali di immagini disco utilizzate dalle VM sono:

- `COW` (`copy-on-write`): un metodo che crea un file con un limite di dimensione predefinito. In questo caso, la dimensione dell'immagine sul disco aumenta solo quando i dati vengono effettivamente scritti, senza superare il limite stabilito. Questo approccio consente di risparmiare spazio su disco, poiché inizialmente non viene allocato spazio per i dati che non sono stati ancora scritti. Il formato comunemente utilizzato per le immagini disco COW è `qcow2`
- `RAW`: sono file che hanno tutto il loro spazio pre-allocato al momento della creazione. Ad esempio, un file di immagine disco RAW da 10 GB occuperà esattamente 10 GB sull'hypervisor, indipendentemente dal fatto che i dati siano stati scritti o meno

### D-BUS Machine ID

Il D-BUS Machine ID è un identificatore univoco assegnato a un sistema Linux al momento della sua creazione.

Per verificare se un D-BUS Machine ID esiste già, è possibile utilizzare il seguente comando:

```bash
dbus-uuidgen --ensure
```

Se il comando non restituisce errori, significa che esiste già un ID per il sistema. Per visualizzare l'ID attuale, si può utilizzare il comando:

```bash
dbus-uuidgen --get
```

Il D-BUS Machine ID è memorizzato nel file `/var/lib/dbus/machine-id`, che è un collegamento simbolico a `/etc/machine-id`.

#### Generazione di un nuovo ID

Se è necessario generare un nuovoe ID, è possibile farlo seguendo questi passaggi:

```bash
rm -rf /etc/machine-id

# Generare un nuovo ID
dbus-uuidgen --ensure=/etc/machine-id
```

## Container

I container rappresentano una tecnologia di virtualizzazione leggera che differisce dalle VM. La principale distinzione risiede nel fatto che i container condividono lo stesso kernel del sistema operativo host, mentre le VM eseguono un sistema operativo completo e indipendente.

### Differenze con le VM

I container contengono solo le librerie e le dipendenze necessarie per l'esecuzione dell'applicazione, senza includere l'intero sistema operativo. Vengono eseguiti direttamente sull'host, eliminando la necessità di un hypervisor per la gestione delle risorse hardware.

Al contrario, ogni macchina virtuale esegue un sistema operativo completo, comprensivo del proprio kernel, librerie e applicazioni. Ogni VM ha un sistema operativo guest installato, che può differire dal sistema operativo host. Le VM richiedono un hypervisor per gestire l'allocazione delle risorse hardware, il che comporta un sovraccarico maggiore rispetto ai container.

| Caratteristica                | Container                                     | VM                                    |
|-------------------------------|-----------------------------------------------|---------------------------------------|
| Kernel                        | Condivide il kernel dell'host                 | Esegue un proprio kernel              |
| Dimensione                    | Leggeri, solo librerie e dipendenze           | Più pesanti, includono un OS completo |
| Avvio                         | Rapido, senza hypervisor                      | Più lento, richiede un hypervisor     |
| Isolamento                    | Minore isolamento, solo a livello di processo | Isolamento completo                   |

![container_vs_vm](asset/image/container_vs_vm.png)
