Su piattaforme come Proxmox VE, ogni volta che si crea un nuovo servizio si presenta la stessa domanda: macchina virtuale o container LXC? Entrambi sembrano piccoli computer indipendenti, con un proprio indirizzo IP e un proprio sistema, ma funzionano in modo molto diverso. Capire la differenza evita sprechi di risorse e brutte sorprese.
Due modi diversi di isolare
Una macchina virtuale emula un intero computer: processore virtuale, memoria, disco, scheda di rete, firmware. Al suo interno gira un sistema operativo completo, con il proprio kernel. L'hypervisor, aiutato dalle estensioni hardware del processore, la separa dall'host e dalle altre macchine virtuali.
Un container LXC non emula nulla. È un insieme di processi che girano direttamente sul kernel dell'host, isolati tramite meccanismi del kernel Linux come i namespace (che danno al container una propria vista di processi, rete, utenti e filesystem) e i cgroup (che ne limitano l'uso di CPU e memoria). Dall'interno sembra un sistema Linux completo, ma il kernel è quello dell'host.
LXC si chiamano anche "container di sistema", per distinguerli dai container applicativi come quelli di Docker: un container LXC ospita un'intera distribuzione con il suo sistema di init, servizi e gestore di pacchetti, mentre un container applicativo di solito esegue un singolo processo.
Confronto pratico
| Aspetto | Macchina virtuale | Container LXC |
|---|---|---|
| Kernel | proprio | condiviso con l'host |
| Sistemi supportati | Linux, Windows, BSD e altri | solo Linux |
| Avvio | decine di secondi | pochi secondi |
| Memoria | riservata in blocco | usata secondo necessità |
| Isolamento | forte | buono, ma più sottile |
| Accesso all'hardware | passthrough di dispositivi PCIe | condivisione di dispositivi dell'host |
| Migrazione a caldo | supportata | di solito con riavvio |
Quando scegliere un container LXC
I container sono ideali per servizi Linux leggeri che non richiedono un kernel particolare:
- un server DNS locale o un filtro pubblicitario;
- un reverse proxy;
- un database di prova;
- piccoli servizi web e strumenti di monitoraggio.
Il vantaggio principale è l'efficienza. Un container che fa poco usa poca memoria, perché non deve mantenere un sistema operativo intero con la sua cache e i suoi servizi di base. Su una macchina con 16 GB di RAM si possono far girare molti più container che macchine virtuali.
Un altro vantaggio è la condivisione dell'hardware: per esempio, la grafica integrata dell'host può essere resa disponibile a più container contemporaneamente per la transcodifica video, cosa che con le macchine virtuali richiede il passthrough esclusivo o tecnologie di virtualizzazione della GPU.
Quando scegliere una macchina virtuale
La macchina virtuale è la scelta giusta quando:
- serve un sistema non Linux, come Windows o un firewall basato su BSD;
- serve un kernel specifico, con moduli particolari o versioni diverse da quella dell'host;
- si vuole far girare Docker in modo semplice e pienamente supportato;
- si ospitano servizi esposti su Internet o software di cui ci si fida poco, dove conviene l'isolamento più forte;
- serve il passthrough esclusivo di un dispositivo, come un controller dischi o una scheda di rete.
Su Docker dentro LXC conviene una precisazione: è possibile, attivando l'annidamento e alcune opzioni, ma è una configurazione più fragile, che può rompersi con gli aggiornamenti. In molti preferiscono una piccola macchina virtuale dedicata a Docker, che ospita tutti i container applicativi.
Container privilegiati e non privilegiati
Proxmox crea per impostazione predefinita container non privilegiati: l'utente root dentro il container corrisponde, sull'host, a un utente senza privilegi, grazie alla mappatura degli identificativi utente. Se un processo riuscisse a uscire dal container, si troverebbe con permessi molto limitati.
I container privilegiati fanno coincidere root interno e root dell'host. Sono talvolta più comodi, per esempio per montare condivisioni di rete, ma riducono molto l'isolamento. La regola prudente è usare container non privilegiati salvo motivi precisi, e risolvere i problemi di permessi con la mappatura degli utenti invece di passare ai privilegiati.
Un esempio di suddivisione
In un homelab tipico una divisione ragionevole potrebbe essere:
- LXC: DNS locale, reverse proxy, server di monitoraggio, database di sviluppo;
- VM: firewall o router virtuale, macchina con Docker per i servizi applicativi, macchina Windows di test, servizi esposti verso l'esterno.
Nel mio lavoro preferisco partire da un container e passare a una macchina virtuale solo quando emerge un motivo concreto: è il modo più semplice per non riempire la memoria di sistemi operativi che non fanno quasi nulla.
In sintesi
- La macchina virtuale emula un computer completo con il proprio kernel; il container LXC condivide il kernel dell'host.
- I container sono più leggeri, si avviano in pochi secondi e usano la memoria solo quando serve.
- Per Windows, kernel particolari, passthrough, Docker e servizi esposti conviene la macchina virtuale.
- I container non privilegiati sono la scelta predefinita più sicura.
- Partire dal container e passare alla macchina virtuale solo per motivi concreti evita sprechi di RAM.