Backup di virtual machines Xen senza interruzione
E’ passato parecchio tempo dal mio ultimo post sul blog: quell’ultimo post ribadiva la disponibilità gratuita di VMWare ESXi.
Dopo quella mossa di VMWare, anche Citrix ha pensato di dover fare qualcosa per poter guadagnare un po’ terreno nel tentativo di raggiungere la concorrenza e la mossa è stata quella di rilasciare XenServer 5 gratuitamente con tanto di tool utilissimi per la gestione di più server fisici e, soprattutto, il supporto per la migrazione delle macchine virtuali da un server fisico ad un altro.
L’ultima versione (XenServer 5.5) introduce anche il supporto per gli snapshot delle macchine virtuali ed offre la possibilità di convertire questi snapshot in altre macchine virtuali che risulteranno, alla fine, dei perfetti cloni della macchina di origine.
L’operazione di snapshotting richiede alcuni secondi e non blocca in alcun modo le operazioni della macchina virtuale.
Da qui è nata l’idea di Jeremy Tirrel per un “0 downtime snapshot based XENServer 5.5 backup script“.
Questo script in Perl esegue proprio questa serie di operazioni:
- Snapshot della macchina virtuale
- Conversione dello snapshot in una nuova macchina virtuale
- Esportazione della nuova macchina virtuale come backup in formato XVA
- Cancellazione della macchina virtuale derivata dallo snapshot
- Cancellazione dello snapshot
Jeremy fornisce anche uno script in PHP per la rotazione dei backup in modo da poter tenere alcune versioni dei backup.
Personalmente ho utilizzato il suo script con alcune piccole modifiche ed evitando l’uso dello script PHP per la rotazione dei backup ma affidandomi ad una soluzione leggermente diversa.
La mia attuale configurazione è questa:
- 3 x HP ProLiant DL360G5, 10GB RAM
- 16 virtual machines
- 1 storage condiviso iSCSI (http://www.starwindsoftware.com/)
- 1 vecchio server utilizzato come “staging”
- software di backup CrashPlan Pro
Lo script di backup viene lanciato sul master del pool di server che gestiscono le virtual machines alle 17.30 di ogni giorno ed esporta le singole VM dallo storage condiviso al server di staging. L’operazione di snapshotting/backup impiega circa 8 ore.
Lo script esporta le singole VM su un file con estensione .xvatmp; non appena l’operazione di esportazione è completata, rinomina il file da .xvatmp in .xva, sovrascrivendo il precedente.
CrashPlan Pro (http://www.crashplanpro.com) è un ottimo software di backup remoto scritto in Java che utilizza il consolidato approccio rsync-like per ottimizzare l’uso della linea. Essendo pensato per operare via Internet, in rete locale funziona che è un piacere! Il client di CrashPlanPro è installato sul server di “staging” ed è impostato per non salvare i file con estensione .xvatmp (sarebbe inutile, dato che sono dei work-in-progress) e in poche ore:
Completed backup to BackupSGR S in 3 hours: 16 files (269.09 GB) backed up, 21.64 GB encrypted and sent @ 16 66.41 KB/s (Effective rate: 32699.14 KB/s)
A gestire il numero di backup che ho a disposizione per un eventuale rollback è CrashPlan e quindi non ho alcun bisogno dello script in PHP proposto da Jeremy.
Ovviamente è possibile sottoscrivere un piano di backup remoto anche con altri gestori che usino altri software, a patto che il software supporti la piattaforma dove vengono salvati i file. Se, come me, volete usare CrashPlan, suggerisco ProntoBackup
Qui sotto riporto il codice Perl con le mie poche modifiche:
backup.pl
#!/usr/bin/perl
#
#XEN Server machine back, Jeremy Tirrell for Commercial Solutions INC 2009
#minor changes by Roberto Cespa
$backupdir = "/mnt/offsite/XenBackup/"; #Directory to backup to, this should be nfs share or something large.
#mail notification setup
$mailNotification = true; #false for no notifcaiton
$mailScript = "/usr/local/scripts/sendEmail"; #Brandon Zehm - Change "server" to point to smtp server
$MailTo = "address\@example.com"; #mail to
$MailFrom = "SomeOtherAddress\@example.com"; #mail from
$host = "Xen1 XenServer"; #Descriptive name
#Setup Strings
$Message = " \"XEN Backup Notification\n"; #header of message
$MailString = $mailScript . " -f " . $MailFrom . " -t " . $MailTo; #mail string to control string passed to sendEmail
$TopicHeader = "[".$host ." XEN Server Backup Script] "; #Subject.
$Topic = "";
#add chunks of uuid to skip backing up of a specifc vm
#control domain (dom0) should be added to this list!!
@skip = ('3a720810-a2fc-4025-97f1-860a1c9b6357','77822415-4e6b-46f6-bd82-821b2c1401c3','dce8ea94-c7d8-41e6-9232-630a27ab3b16');
$vmlist = `xe vm-list`; #Get the formatted list of guests
@lineList = split(/\n/,$vmlist); #Split the list of guests into and array of lines
@uuid = (); #Array to store uuid's in
foreach $line(@lineList){ #for each line in the array
if (substr($line,0,4) eq "uuid"){ #look for the word uuid at the beginning of the line
push(@uuid, substr($line,23,36)); #if its there add the uuid to the array
}
}
#@uuid=('116409d7-61b0-67a0-dbff-709e93053e00');
$tcurrent = `date`; #get the current date
print("Beginning backup of virtual machines at ". $tcurrent);
$Message .= "Beginning backup of virtual machines at ". $tcurrent."\n";
foreach $guest(@uuid){ #for each guest listed in the uuid list
if (grep $_ eq $guest, @skip){ #is guest on the skip list?
print("Skipping backup of: ".$guest ."\n"); #yes so just let it be known it is being skipped
$Message .= "Skipping backup of: ".$guest ."\n";
} else { #otherwise
$tcurrent = `date`; #get the current date
$VMName = `xe vm-list uuid=$guest | grep name-label | cut -b24-`;
$VMName=~ s/\n//g;
$VMName=~ s/\r//g;
$VMName =~ s/ /_/g;
print("Beginning backup of ".$guest ." @ ". $tcurrent);
$Message .= "Beginning backup of ".$guest ." @ ". $tcurrent."\n";
print("Taking a snapshot of: ".$guest ."\n"); #Snapshot the VM
$Message .= "Taking a snapshot of: ". $guest ."\n";
$snapshotUUID= `xe vm-snapshot vm=$guest new-name-label=$VMName-backup_vm`;
$snapshotUUID=~ s/\n//g; #remove the carrier return/linefeed
$snapshotUUID=~ s/\r//g;
print("Snapshot: ".$snapshotUUID." created\n");
$Message .= "Snapshot: ".$snapshotUUID." created\n";
print("turning ".$snapshotUUID ." snapshot into a vm\n"); #Turn snapshot into a VM
$Message .= "turning ".$snapshotUUID ." snapshot into a vm\n";
$status= `xe template-param-set is-a-template=false ha-always-run=false uuid=$snapshotUUID`;
print($status."\n");
$Message .= $status."\n";
$fdate = `date +%y%m%d-%H%M`;
$fdate=~ s/\n//g; #get the current date in a format we can write
$fdate=~ s/\r//g; #get the current date in a format we can write
print("Exporting: ".$snapshotUUID."\n"); #export the snapshot
$Message .= "Exporting: ".$snapshotUUID."\n";
$exportstring = $backupdir.$VMName."-".$fdate.".xvatmp";
$finalname = $backupdir.$VMName.".xva";
print("Name: $exportstring - $finalname\n");
$status= `xe vm-export vm=$snapshotUUID filename=$exportstring`;
print($status."\n");
$Message .= $status."\n";
print("Renaming backup file so that CrashPlan can backup it\n");
$status= `mv -vf $exportstring $finalname`;
print($status."\n");
$Message .= $status."\n";
print("Done, Removing snapshot: ".$snapshotUUID."\n"); #Done, remove the snapshot
$Message .= "Done, Removing snapshot: ".$snapshotUUID."\n";
$status= `xe vm-uninstall uuid=$snapshotUUID force=true`;
print($status."\n");
$Message .= $status."\n";
$tcurrent = `date`; #get the current date
print("Completed backup of ".$guest ." @ ". $tcurrent);
$Message .= "Completed backup of ".$guest ." @ ". $tcurrent."\n";
}
}
$tfinished = `date`;
print("Backup completed at ".$tfinished);
$Message .= "Backup completed at ".$tfinished."\n\"";
if ($mailNotification){
system($MailString . " -u " . $TopicHeader . $Topic ." -m " . $Message);
}
Interessante, avevo visto e “giocato” anch’io con quello script ma ho incontrato dei problemi sia di funzionamento che di “logica”:
Lo snapshot di una VM accesa non è consistente,
la macchina virtuale potrebbe avere più dischi virtuali (tipicamente sistema operativo/applicativi e area dati) e l’area dati potrebbe essere gigantesca e da gestire con un backup a livello applicativo (es. Exchange o SQL server),
quindi è piuttosto pesante (oltre che lento) effettuare un backup dell’intera macchina.
L’alternativa, che sto mettendo a punto proprio in questi giorni, è quella di effettuare uno snapshot delle singole VDI (singoli dischi collegati alle macchine virtuali) consentendo un backup “selettivo”. Resta sempre il fatto che la macchina accesa potrebbe generare un backup inconsistente (nel caso di snapshot di LUN su storage NETAPP o DELL giurano di no…) ma la soluzione di mettere in pausa o di spegnere la VM potrebbe risultare improponibile, e lo snapshot “quiesced” (xe vm-snapshot-with-quiesce) mi ha dato GROSSI problemi (intero volume marcato R/O e Hidden dal VSS).
Riguardo alla consistenza degli snapshot di una VM accesa ho anche io qualche dubbio, ma forse il mio caso è un po’ più semplice perché le 16 VM di cui parlo nell’articolo sono tutti desktop virtuali Windows XP; in linea di massima, quindi, lo snapshot inconsistente dovrebbe avere gli stessi effetti di una perdita di elettricità.
L’unico vero server (SQL Server) è in conversione da VMWare in questi minuti ma per quello è prevista la procedura di backup e manutenzione di SQL Server; i file risultanti vengono poi spostati su un file server fisico.
Personalmente ho fatto delle prove di recovery delle VM e nessuna di queste ha dato alcun problema né ha richiesto un chkdsk.
Sarebbe interessante sapere cosa fa Xen quando converte lo snapshot in una VM: dubito che possa chiudere i vari handle delle applicazioni, ma in fondo mi chiedo ancora come funzioni l’idea di Citrix dei vari layers per i desktop virtuali in XenDesktop.
Nella documentazione Citrix sostiene che uno snapshot sia “crash consistent” (http://docs.vmd.citrix.com/XenServer/5.5.0/1.0/en_gb/reference.html#id2584931) ma sarei curioso di capire bene cosa intendano per crash consistent.
Un avviso importante: se è abilitata l’HA e la macchina che deve essere esportata è protetta dall’HA non appena lo script imposta “is-a-template” a false XenServer avvia tale macchina, e questo è un problema, perché si tratta di una macchina “clone” senza più poterla gestire (spegnere, modificare ecc. ecc.).
Per risolvere bisogna modificare la riga:
$status= `xe template-param-set is-a-template=false uuid=$snapshotUUID`;
in
$status= `xe template-param-set is-a-template=false ha-always-run=false uuid=$snapshotUUID`;
Grazie per l’avviso.
Mi sono permesso di tradurlo e di riportarlo anche sulla pagina del forum di Citrix: http://community.citrix.com/display/xs/0+downtime+snapshot+based+XENServer+5.5+backup+script.?focusedCommentId=79462767comment-79462767
E’ un tipo di problematica che non ho assolutamente considerato, dato che uso la versione free di XenServer.
@P. Nacci
Da quanto ho potuto capire per Crash Consistent si intende quello che immaginavo: è come se al computer togliessimo la corrente.
Quindi rimane il problema dell’integrità dei dati tipica dei database o di Exchange.
Citrix, comunque, insiste sul VSS anche in questo articolo: http://support.citrix.com/article/CTX122191
Sembrebbe la soluzione più ovvia, ma tu hai detto di aver avuto parecchi problemi…
@Roberto Cespa
I problemi li ho avuti con Xen 5.0 (su cui gira anche Marathon everRun VM), non so se siano risolti, comunque il problema era che lo snapshot partiva e dopo pochi secondi terminava con un errore che in taluni casi (VM Windows 2003 32 Bit) portava a una inaccessibilità dei volumi (=niente più boot!).
Siccome sto parlando di un sistema “in produzione” e le coronarie quella volta hanno sobbalzato parecchio ho deciso di non fare più esperimenti con VSS, passando a backup applicativo per i dati (SQL, Exchange) e allo snapshot dei singoli dischi (snapshot VDI + LUN Clone) che è rapidissimo, ma resta sullo storage.
Purtroppo il mio storage non è né NetApp né niente di fascia alta; ho utilizzato un server con Win2K3 e il target iSCSI della StarWind.
Sto cercando di fare il tutto spendendo il meno possibile (al limite anche zero).
Nella sua incarnazione free, il target di StarWind non permette lo snapshotting.
Tutto questo, inoltre, ha il grosso difetto legato ad un bug (secondo gli utenti) / feature (secondo Citrix) relativo agli snapshot su shared SR e LVM: http://forums.citrix.com/thread.jspa?threadID=249121&tstart=75 .
Praticamente se faccio uno snapshot di un disco da 20GB e lo converto in una nuova VM per il backup (occupando 20GB+ x MB +20GB), poi non c’è più modo di riavere indietro quello spazio, nemmeno cancellando lo snapshot e la macchina da esso derivata.
L’unica soluzione è di cancellare la macchina originaria (quella di cui è stato fatto lo snapshot) e reimportarla dal backup
Quindi con uno storage da 800GB, puoi più o meno usare 380GB per le VM: altrettanti saranno necessari per i cloni e un po’ me li tengo di riserva per qualsiasi evenienza.
Questa cosa, abbastanza fastidiosa quando hai dei vincoli economici, mi sta portando a valutare l’idea di farmi un file server NFS con 4 o 6 dischi SATA e metterci sopra Linux: NFS sotto Windows non ne vuole sapere di andare con performance decenti, almeno non con i file delle dimensioni di quelli usati per i VHD.
I’ve not worked with Xenserver at this point so bear with me. Nothing in this discussion has talked about how you go about restoring the snapshot should the need arrise. Is it as simple as copying the .xva back up to the Xenserver data store?
Thanks
Steve
Hi, Steve
Recovering a VM from an .xva file is a simple operation that you can start from XenCenter console; the whole operation is wizard driven and it’s point’n'click.
I have not access to a XenCenter in this very moment (I’m out of office) but, as far as I can remember, is something like “File -> Import VM” from the menu to start the wizard.
Then you have to browse your computer (or a network share) to find the .xva file, select the home server (in case of server pools), select the Storage Repository and click the finish button.
I tested recovery several times and it needed something like 30 to 45 minute each time to bring back the VM to life.
If you don’t want to set up Windows networking again you should manually set the network adater MAC address to the same value of the initial machine.
If you do the recovery by CLI, you should have an option to preserve the MAC (as “Anonymous” says
here: )
Ciao,
Roberto
Su questo blog c’è qualche linea guida per fare gli script di backup da windows e la cosa carina è che funziona anche quando cambia il master del pool con winscp…
http://virtualgreen.wordpress.com/2009/09/22/uno-xen-virtual-consolidated-backup-server-artigianale/
Ho provato lo script e non mi parte, per farlo funzionare ho dovuto usare perl5.8.8 ( sia sostituendolo sulla prima riga dello script, che per farlo runnare perl5.8.8 backup.pl), usando il comadno perl backup.pl non mi restituiva nessun output..non so perche’ essendo abbastanza ignorante in ambito linux
Hi Roberto,
I ran your script (slightly adjusted) on XenServer 5.5.0 Update 2 and it ran fine! Many thankz! I updated to XenServer 5.6.0 (grr, lot’s of issues) and now i try to get the backup script running again. It seems i’ve got a few issues:
- @ snapshot, error: ^CFatal error: exception Unix.Unix_error(13, “tcsetattr”, “”)
- i added coalesce-leaf, this isn’t supported anymore.
I could sent you my backup script if needed.
Hi Jan,
I’m happy you found the script useful.
Unfortunaley, I moved to from Xen to KVM mainly for two reasons:
Now I’m focusing my attention on KVM (mainly using Proxmox VE distro: you can really be up and running in 10 minutes) and I hope to find some spare time to post something about VM migration from Xen to KVM.
I’m also starting to use MongoDB, a document database, and I hope to write something about MongoDB + PHP ( + Lithium PHP framework).
I’ll be glad to publish your script in this post once debugged!
Ciao,
Roberto