▤ Homelab

Template e cloud-init: creare macchine virtuali in pochi secondi

Come usare template e cloud-init nell'homelab per creare macchine virtuali Linux configurate, con utente, chiavi SSH, rete e pacchetti in pochi secondi.

Installare una macchina virtuale Linux dall'immagine ISO richiede ogni volta gli stessi passaggi: scegliere la lingua, partizionare il disco, creare l'utente, configurare la rete, aggiornare i pacchetti, copiare la chiave SSH. Fatto una volta è istruttivo, fatto per la decima volta è solo una perdita di tempo, e ogni installazione manuale rischia di essere leggermente diversa dalle altre.

La soluzione usata nei cloud pubblici funziona benissimo anche in casa: immagini cloud, template e cloud-init.

Cos'è cloud-init

cloud-init è un programma presente nelle immagini cloud di quasi tutte le principali distribuzioni Linux. Al primo avvio della macchina legge una configurazione fornita dall'esterno e la applica: crea utenti, installa chiavi SSH, imposta il nome host, configura la rete, installa pacchetti, esegue comandi.

La configurazione può arrivare da diverse "fonti di dati": un servizio di metadati nei cloud pubblici, oppure, negli hypervisor domestici, un piccolo disco virtuale collegato alla macchina che contiene i file di configurazione. Proxmox, per esempio, genera automaticamente questo disco a partire dai campi compilati nell'interfaccia.

Immagini cloud: il punto di partenza

Le distribuzioni pubblicano immagini già installate e pronte, pensate proprio per essere avviate con cloud-init. Sono di solito in formato qcow2 o img, occupano poche centinaia di megabyte e contengono un sistema minimo.

Rispetto a una ISO hanno due vantaggi: non richiedono installazione e sono pensate per essere clonate, perché al primo avvio generano nuove chiavi host SSH e un nuovo identificativo di macchina.

Creare un template su Proxmox

Il procedimento tipico, eseguito dalla shell dell'host, è il seguente. I numeri e i nomi sono esempi.

qm create 9000 --name debian-template --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single
qm importdisk 9000 debian-cloud.qcow2 local-lvm
qm set 9000 --scsi0 local-lvm:vm-9000-disk-0
qm set 9000 --ide2 local-lvm:cloudinit
qm set 9000 --boot order=scsi0 --serial0 socket --vga serial0
qm set 9000 --agent enabled=1
qm template 9000

I passaggi, in ordine:

  1. si crea una macchina virtuale vuota con memoria, core e scheda di rete;
  2. si importa l'immagine cloud come disco;
  3. si collega il disco e si aggiunge l'unità cloud-init;
  4. si imposta l'avvio dal disco e una console seriale, che molte immagini cloud usano al posto dello schermo;
  5. si attiva l'agente ospite;
  6. si converte la macchina in template.

Un template non si avvia: serve solo come modello da clonare.

Clonare e personalizzare

Da quel momento, una nuova macchina virtuale si crea con un clone:

qm clone 9000 120 --name web01 --full
qm set 120 --ciuser marco --sshkeys ~/.ssh/id_ed25519.pub
qm set 120 --ipconfig0 ip=192.168.10.120/24,gw=192.168.10.1
qm resize 120 scsi0 +18G
qm start 120

Dopo pochi secondi la macchina è accesa, con l'utente creato, la chiave SSH installata e l'indirizzo IP impostato. Il disco dell'immagine cloud è piccolo, quindi conviene ingrandirlo prima del primo avvio: molte immagini estendono automaticamente la partizione allo spazio disponibile.

Clone completo o collegato

Un clone completo copia l'intero disco ed è indipendente dal template. Un clone collegato condivide i dati del template e salva solo le differenze: si crea all'istante e occupa poco spazio, ma dipende dal template, che non può essere eliminato finché esistono cloni collegati. Per macchine di test usa e getta il clone collegato è ideale; per servizi destinati a durare è più prudente quello completo.

Configurazioni più ricche

Oltre ai campi di base, cloud-init accetta file di configurazione completi in formato YAML, detti "user data". Un esempio minimo:

#cloud-config
package_update: true
packages:
  - qemu-guest-agent
  - htop
runcmd:
  - systemctl enable --now qemu-guest-agent
timezone: Europe/Rome

Su Proxmox questi file si salvano in un archivio abilitato ai "snippet" e si collegano alla macchina con l'opzione --cicustom. In questo modo ogni nuova macchina nasce già con l'agente ospite, il fuso orario corretto e gli strumenti preferiti.

Tenere aggiornato il template

Un template creato un anno prima produce macchine con un anno di aggiornamenti da recuperare. Conviene:

  • ricrearlo periodicamente da un'immagine cloud recente;
  • oppure far eseguire gli aggiornamenti dal user data al primo avvio, accettando qualche minuto in più;
  • tenere uno script con tutti i comandi di creazione, così rifarlo richiede pochi secondi.

Lo script stesso diventa documentazione: chiunque, compreso il sé stesso di sei mesi dopo, capisce subito come è stato costruito il modello.

Il passo successivo

Una volta abituati ai template, il passo naturale è affidare la creazione delle macchine a strumenti di infrastruttura come codice e la loro configurazione a strumenti di gestione delle configurazioni. cloud-init resta il ponte tra i due: porta la macchina appena nata nello stato minimo necessario per essere raggiunta e configurata.

In sintesi

  • cloud-init applica al primo avvio utenti, chiavi SSH, rete, pacchetti e comandi.
  • Le immagini cloud delle distribuzioni sono piccole, già installate e pensate per essere clonate.
  • Un template si crea una volta e si clona in pochi secondi; il clone collegato è ideale per i test.
  • Il disco delle immagini cloud va ingrandito prima del primo avvio.
  • Il template va ricreato periodicamente, meglio se tramite uno script che ne documenta i passaggi.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche