Při nasazení virtualizace postavené na Red Hat Enterprise Linux kompatibilních distribucí (kombinace KVM a QEMU) jsme narazili na problém zálohování. Systém vypnutí VM, zálohy a zapnutí VM není příliš komfortní a často nejde vůbec použít kvůli potřebě běhu VM v režimu 7×24.
Naštěstí existuje možnost zálohy pomocí vestavěných nástrojů. V tomto článku zatím budu prezentovat plné zálohy (full backup) VM do jejich konzistentní kopie. Popsaná metoda vyžaduje libvirt-7.2.0 a QEMU-4.2 nebo vyšší.
Nejprve si vyberte VM, který chcete zálohovat a zjistěte, jaké disky používá.
[root@kraken ~]# virsh domblklist domino-linux
Target Source
--------------------------------------------------
sda CentOS-Stream-9-latest-x86_64-dvd1.iso
sdb domino-linux-notesdata.qcow2
vda domino-linux.qcow2
Z výpisu vidíme, že disk sda je virtuální DVD, to zálohovat nechceme, zbývají disky vda a sdb. Připravíme si konfigurační soubor XML s definicí, co chceme zálohovat.
<domainbackup>
<disks>
<disk name='sdb' backup="yes" type='file'>
<target file='/local/kvm/backup/domino-linux.qcow2'/>
<driver type='qcow2'/>
</disk>
<disk name='vda' backup="yes" type='file'>
<target file='/local/kvm/backup/domino-linux-notesdata.qcow2'/>
<driver type='qcow2'/>
</disk>
</disks>
Zálohy směrujeme do adresáře /local/kvm/backup. Jako první zazálohujeme konfiguraci VM příkazem:
virsh dumpxml domino-linux > /local/kvm/backup/domino-linux.xml
Tím máme kompletní konfiguraci VM pro případnou obnovu. Nyní spustíme samotnou zálohu disků VM podle dříve připravené konfigurace v XML.
virsh backup-begin domino-linux --backupxml domino-linux.xml
Počkejte, dokud nedostanete výstup z následujícího příkazu o backup jobu jako „completed“.
[root@kraken ~]# virsh domjobinfo domino-linux --keep-completed --completed
Job type: Completed
Operation: Backup
Time elapsed: 7611 ms
File processed: 160.000 GiB
File remaining: 0.000 B
File total: 160.000 GiB
Nyní máte k dispozici zálohu VM (disky a konfiguraci). Zálohu můžete importovat jako nový VM a jednoduše spustit.
Srovnání tohoto způsobu a staršího přístupu přes snapshoty popisuje tento článek.
Na závěr uvádím jednoduchý skript, který zálohy automatizuje. Umístění VM je zde předpokládáano v adresáři /local/kvm. Zálohy jsou směrovány do /local/kvm/backup. Skript hledá konf. soubory záloh v XML v /local/kcm/backup/cfg. XML soubor se musí jmenovat stejně jako VM samotný. Skript obsahuje nedokončené části pro mailování výsledků záloh a zaslání logu. Na konci skriptu je volán Backup Archive klient sysétmu IBM Spectrum Protect (dříve Tivoli Storage Manager), který vytvořené zálohy VM uloží na backup server a díky verzování udržuje definovaou historii těchto souborů pro možno obnovy nejen poslední zálohy.
#!/bin/bash
# Default base backup path -- this directory will be created if it does not already exist
BACKUPPATH="/local/kvm/backup"
# String to match in list of VM block devices
VMDATAMATCH="qcow2"
# Path to XML backup config files
XMLBACKUPCFGPATH=/local/kvm/backup/cfg
# Maximum history of VM backups allowed (e.g. 2 means keep the current backup and one previous backup)
MAXBACKUP=2
# Default email (an empty string means no e-mail will be sent)
TARGET_EMAIL=""
# Logfile
LOGFILE=/var/log/kvmbackup.log
# Default sender email
SENDER_NAME="VM Backup"
SENDER_EMAIL="noreply@exterra-services.cz"
MAIL_FROM="noreply@exterra-services.cz"
MAIL_SUBJECT="KVM backup report - $HOSTNAME"
MAIL_ATTACHMENT=$LOGFILE
MAIL_BODY="Backup report for hypervizor $HOSTNAME"
########################################
export DSM_DIR=/opt/tivoli/tsm/client/ba/bin
export DSM_CONFIG=/opt/tivoli/tsm/client/ba/bin/dsm.opt
echo "Backup started at " $(date) > $LOGFILE;
for VM in $(virsh list --state-running --name); do
if [ -f "$XMLBACKUPCFGPATH/$VM.xml" ]; then
echo "Starting backup for VM: $VM" >> $LOGFILE;
virsh dumpxml $VM > $BACKUPPATH/$VM.xml
virsh backup-begin $VM --backupxml $XMLBACKUPCFGPATH/$VM.xml --reuse-external >>$LOGFILE;
ret_code=$?;
# echo "Error code $?";
if [ $ret_code -ne 0 ]; then
echo "Backing up VM: $VM";
virsh backup-begin $VM --backupxml $XMLBACKUPCFGPATH/$VM.xml >> $LOGFILE;
else
echo "Local dump file missing for $VM" >> $LOGFILE;
fi
# Wait until backup job is completed
while [ "$(virsh domjobinfo "${VM}" | grep 'Job type:' | awk '{ print $3 }')" != "None" ]; do sleep 5; done
virsh domjobinfo $VM --keep-completed --completed >> $LOGFILE;
echo "Finished backup for VM $VM" >> $LOGFILE;
else
echo "Backup config file $XMLBACKUPCFGPATH/$VM.xml does not exist! Backup for $VM skipped!" >> $LOGFILE;
fi
done
cd $DSM_DIR
$DSM_DIR/dsmc incr "$BACKUPPATH/*" -sub=yes >> $LOGFILE;
echo "Backup completed at " $(date) >> $LOGFILE;