Ottenere l'immagine del sistema operativo è la parte forse più interessante dell'intera operazione.
C'è il metodo "facile" che consiste nello spegnere il server e copiare il disco "offline" ed il metodo "figo" che permette di salvare su un altro computer della rete un'immagine funzionante di un sistema operativo “live & running”, senza spegnerlo ne fermare i servizi in esecuzione.
Dato che il metodo facile non presenta alcun difficoltà, mi sono messo a cercare qualche guida che permetta di eseguire il secondo metodo. Il problema principale è che ho utilizzato una schema di partizionamento che non permette la realizzazione di snapshot live del filesystem, altrimenti si poteva usare quello.
Mi sono messo alla ricerca ed ho trovato questo articolo in cui l'autore spiega come ottenere l'immagine consistente di un sistema avviato attraverso una connessione di rete. Questa strada può essere seguita (è il caso del post) anche per effettuare l'immagine di un sistema attraverso internet, con le limitazioni derivanti dalla banda disponibile, ma è sicuramente estremamente interessante:
Copy the disc
At the destination server start netcat listening to a port (in this example 43333), redirecting all its input to a file. If you connect using SSH do it in a screen so you can close the session.
nc -nvv -w30 -l 43333 | gzip -dc > disk.raw
At the origin server use dd to dump its disk. It is then compressed and sent to the netcat at port 43333 waiting with the command above. Gzip compresses the stream and reduces the amount of data to be transferred over the net. Our disk was 72 GB and took 4 hours to 10 Mbps, via the Internet.
dd if=/dev/cciss/c0d0 | gzip -c | nc -w30 -vvn your_server_address 43333
L'operazione non è esente da rischi: Fare l'immagine a sistema acceso senza ricorrere agli snapshoot, comporta elevate possibilità che l'immagine risultante abbia qualche problema. Per minimizzare questi rischi e velocizzare le operazioni è utile ridurre al minimo le attività del server, arrestando i servizi non indispensabili prima di procedere alla copia.
La guida linkata concatena il comando netcat (nc) utilizzato per trasmettere i dati via rete (ricordarsi di aprire le porte utilizzate nei firewall!!!) con il comando “gzip” per comprimere il flusso dei dati in realtime sul server sorgente prima di trasmetterlo e decomprimerlo, sempre realtime, sul server di destinazione:
codice:
nc -nvv -w30 -l 43333 | gzip -dc > disk.raw
dd if=/dev/cciss/c0d0 | gzip -c | nc -w30 -vvn your_server_address 43333
A differenza dell'autore dell'articolo che ha a disposizione molta cpu e poca banda (un server vero, probabilmente HP, ed una connessione 10Mbps) io ho molta banda e pochissima cpu (scheda madre con processore Atom su rete LAN Gigabit). Non è quindi utile utilizzare la compressione, perchè il carico di lavoro aggiuntivo finirebbe per essere controproducente.
Ho fatto comunque un prova per dimostrarlo e la differenza è abissale: Lo screen sulla sinistra mostra la velocità dell'operazione di clone usando la compressione del flusso dati, nel secondo la stessa operazione senza la compressione.
Nel primo caso il processo di compressione cappotta il mio serverino: il processo gzip usa un core al 100% ma ottengo una velocità di trasferimento ridicola. Rimuovendo invece la compressione realtime (sia dalla trasmissione che dalla ricezione, ovviamente) la velocità di trasferimento migliora decisamente, il carico sulla CPU è elevato ma la velocità di trasferimento è rispettabile e arrivo vicino a saturare la banda della Gigabit. Qui credo che il limite sia il controller dei dischi, un vecchissimo ICH6:
codice:
nc -nvv -w30 -l 43333 > /var/lib/libvirt/images/debian_nc.img
dd if=/dev/sdb bs=4096 | nc -nvv -w30 192.168.200.208 43333
Per informazione, netcat non è l'unico strumento che permette di ottenere lo stesso risultato: E' possibile, anzi, incapsulare il flusso dei dati attraverso un tunnel criptato per effettuare, ad esempio, il trasferimento attraverso internet in massima sicurezza sfruttando ssh:
codice:
dd if=/dev/sdb bs=4096 | ssh root@192.168.200.50 'cat > /var/lib/libvirt/images/debian_ssh.img'
Questa modalità permette anche di non dover avviare un processo in ricezione sulla macchina di destinazione ma permette di fare tutto dal sistema di cui si stà facendo l'immagine. Anche in questo caso, però, l'overhead dato dall'attività di cifra del dato in uscita è proibitivo per il mio serverino:
Sicuramente, in presenza di una connessione più lenta attraverso una rete pubblica questo metodo è una validissima soluzione.
Il trasferimento in rete locale di un'immagine da 32Gb perfettamente funzionante ha richiesto circa 22 minuti:
codice:
root@server:/home/matteo# dd if=/dev/sdb bs=4096 | ssh root@192.168.200.50 'cat > /var/lib/libvirt/images/debian_ssh.img'
root@192.168.200.50's password:
7816662+0 records in
7816662+0 records out
32017047552 bytes (32 GB) copied, 1304.66 s, 24.5 MB/s
Netcat senza compressione è quindi la mia scelta per l'operazione. Tempo stimato per il completamento: Poco più di 7 minuti per fare l'immagine del disco da 32Gb, meno di 50 minuti per fare l'immagine completa di un disco da 250Gb:
codice:
root@server:/home/matteo# dd if=/dev/sda bs=4096 | nc -nvv -w30 192.168.200.50 43333
(UNKNOWN) [192.168.200.50] 43333 (?) open
61049646+0 records in
61049646+0 records out
250059350016 bytes (250 GB) copied, 2938.98 s, 85.1 MB/s
sent 951246848, rcvd 0
La comparsa sulla macchina sorgente in fase di avvio della copia del seguente messaggio di errore indica semplicemente che non è stata aperta nel firewall della macchina di destinazione la porta indicata per il trasferimento dati:
codice:
(UNKNOWN) [192.168.200.50] 4333 (?) : No route to host
sent 0, rcvd 0