Una Macchina Virtuale Completa all'Interno di Docker con un'Interfaccia Web
A volte hai bisogno di verificare rapidamente uno script dubbio, testare l'installazione di un software su una distribuzione pulita o distribuire un ambiente con un kernel specifico. Avviare VirtualBox per questo è troppo complicato, configurare Proxmox su un laptop da lavoro è eccessivo e un container Docker normale non fornisce isolamento a livello di kernel.
Recentemente mi sono imbattuto in un repository qemus/qemu. Il progetto raggruppa QEMU con accelerazione KVM all'interno di un container Docker normale ed espone la gestione delle VM direttamente nel browser.
Come Funziona il Progetto
In sostanza, si tratta di un wrapper attorno a QEMU che gestisce tutta la configurazione tediosa dell'emulatore, del networking, dei dischi e del client noVNC. Non devi scrivere manualmente lunghe flag da riga di comando o armeggiare con file di configurazione XML libvirt.
L'intera gestione si riduce a passare variabili d'ambiente a docker-compose.yml. L'immagine scarica automaticamente la distribuzione Linux richiesta, crea un disco virtuale, connette KVM per prestazioni quasi native e apre l'interfaccia web sulla porta 8006.
Il container è adatto sia per lo sviluppo locale che per l'esecuzione di VM in Kubernetes o GitHub Codespaces.
Avvio Rapido
Per avviarlo, ti serve solo un file compose minimale. Ad esempio, distribuiamo Linux Mint:
services:
qemu:
image: qemux/qemu
container_name: qemu
environment:
BOOT: "mint"
RAM_SIZE: "4G"
CPU_CORES: "2"
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 8006:8006
volumes:
- ./qemu_data:/storage
restart: always
stop_grace_period: 2m
Dopo aver eseguito docker compose up -d, il servizio scarica automaticamente l'ISO di Mint e avvia la virtualizzazione.
Vai a http://localhost:8006 nel tuo browser e vedrai la schermata di installazione del sistema operativo. Non serve installare client VNC aggiuntivi.
# Если вы предпочитаете чистый Docker CLI:
docker run -it --rm --name qemu \
-e "BOOT=alpine" \
-p 8006:8006 \
--device=/dev/kvm \
--device=/dev/net/tun \
--cap-add NET_ADMIN \
-v "${PWD}/qemu_data:/storage" \
--stop-timeout 120 \
docker.io/qemux/qemu
Cosa può Fare il Container
Download Automatici delle Distribuzioni
Nella variabile BOOT puoi specificare un nome breve di una distribuzione popolare. Lo script sa dove recuperare le immagini più recenti:
arch,debian,fedora,ubuntu,alpinekali,nixos,gentoo,mint,manjarorocky,alma,cachy,tails
Se il sistema di cui hai bisogno non è nell'elenco predefinito, puoi passare un link diretto a qualsiasi immagine:
environment:
BOOT: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-virt-3.19.1-x86_64.iso"
Il container decomprime gli archivi al volo e supporta immagini nei formati .iso, .qcow2, .vmdk, .vhdx e 32. Puoi anche montare un file locale direttamente nella root del container come 33.
Gestione di Dischi e Memoria
Per impostazione predefinita, la VM ottiene un disco da 64 GB in formato qcow2 all'interno della directory 34. Puoi modificare le dimensioni in qualsiasi momento tramite la variabile 35.
Se l'host esaurisce la RAM, il container supporta il memory ballooning. Questo aiuta a restituire dinamicamente la memoria guest inutilizzata all'host.
Condivisione File con l'Host
Per trasferire file tra l'host e la VM, viene utilizzato il protocollo 9pfs:
volumes:
- ./my_host_folder:/shared
All'interno del sistema guest in esecuzione, devi solo montare la directory:
mount -t 9p -o trans=virtio shared /mnt/shared
Port Forwarding e Networking Completo
Con la modalità bridge standard di Docker, il port forwarding viene configurato tramite il familiare blocco 36. Per inoltrare SSH esternamente:
ports:
- 8006:8006
- 2222:22
Se la VM ha bisogno di un indirizzo IP dedicato sulla rete locale (così che il router di casa gli assegni un indirizzo separato tramite DHCP), il container può essere connesso tramite 37. In questo caso non serve il mapping costante delle porte.
Passthrough dell'Hardware Reale
Tramite il file compose, puoi passare dischi fisici reali (38) o dispositivi USB passando i loro identificatori a QEMU:
environment:
ARGUMENTS: "-device usb-host,vendorid=0x1234,productid=0x5678"
devices:
- /dev/bus/usb
Requisiti di Sistema e Limitazioni
La principale limitazione riguarda il supporto KVM.
Senza accesso diretto al dispositivo 39, l'accelerazione hardware non funzionerà e l'emulazione software pura della CPU renderà le prestazioni insopportabilmente lente.
Dove funziona senza problemi:
- Host Linux con supporto di virtualizzazione hardware (Intel VT-x / AMD-V).
- Windows 11 con Docker Desktop o Podman Desktop con virtualizzazione nidificata abilitata.
Docker Desktop su macOS e Windows 10 attualmente non passa 40 nei container, quindi non potrai eseguire il progetto lì.
Puoi verificare la disponibilità di KVM su Linux con l'utility standard:
sudo apt install cpu-checker
sudo kvm-ok
Se il comando restituisce 41, il container si avvierà senza problemi.
Per cosa Puoi Usarlo
- Test di scenari di automazione. Eseguire installazioni pulite di Ansible o script bash in una VM isolata senza rischiare di rompere il sistema di lavoro.
- Esecuzione sicura di software. Verificare pacchetti o binari sospetti in un ambiente isolato che può essere ricreato con un singolo comando.
- Apprendimento ed esperimenti. Esplorare nuove distribuzioni (ad esempio, NixOS o Alpine) direttamente nella finestra del browser senza dover gestire chiavette USB.
- Pipeline CI/CD. Compilare pacchetti kernel o testare software di sistema all'interno di macchine virtuali complete sui runner Kubernetes.
Riepilogo
Il progetto 42 colma perfettamente la nicchia tra container leggeri e hypervisor pesanti. Se hai regolarmente bisogno di macchine virtuali isolate per testare su una macchina Linux o un server di casa, questa immagine fa risparmiare molto tempo sulla preparazione dell'immagine e sulla configurazione di rete.
Il repository è mantenuto attivamente dall'organizzazione qemus, che ha anche build separate adattate per ARM64, Windows e macOS.
Progetti correlati