Heute habe ich mir ein Skript erstelt, dass mir die Gast-Images und XML-Definitionen auf eine USB-Platte wegsichern kann. Das Skript muss natürlich individuell angepasst werden, setzt aber im wesentlichen auf die Cheat-Sheet von gestern auf.
Kleine Anmerkung zum Script: Die Option –quiesce bitte nur verwenden, wenn qemu-guest-agent auf den Gästen installiert ist!
#!/bin/bash set +x exec < /dev/null [[ -f /tmp/backup-running ]] && exit 1 touch /tmp/backup-running # Path, where backups should be stored DST=/mnt # Path, where temporary snapshots should be created SNAP=/var/backups/snapshots # Check and create working directories [[ -d ${DST} ]] || mkdir -p ${DST} [[ -d ${SNAP} ]] || mkdir -p ${SNAP} date=$(date +"%Y%m%d") mount /dev/sda1 ${DST} >/dev/null 2>&1 if [[ "$?" -ne 0 ]]; then echo "Unable to mount backup drive!" exit 1 fi rm -f ${DST}/LATEST_* for VM in $(virsh list --name); do echo "Backup KVM guest ${VM}" # Make sure, snapshot merging was successfull image_path=$(virsh domblklist ${VM} --details | \ grep vda | \ awk '{ print $4; }' | \ cut -d "/" -f -5) if [[ "$image_path" != "/var/lib/libvirt/images" ]]; then continue # Existing snapshot. Skipping fi if [[ ! -f ${SNAP}/backup-snapshot-${VM}.qcow2 ]]; then echo "Create Snapshot..." virsh snapshot-create-as ${VM} "backup-${VM}" \ --diskspec vda,file=${SNAP}/backup-snapshot-${VM}.qcow2 \ --disk-only \ --atomic \ --quiesce \ --no-metadata else continue # Orphaned snapshot. Skipping fi echo "Copy guest image to backup drive..." cp -f --sparse=always /var/lib/libvirt/images/${VM}.img ${DST}/ echo "Merge snapshot with guest image..." virsh blockcommit ${VM} vda --wait --active virsh blockjob ${VM} ${SNAP}/backup-snapshot-${VM}.qcow2 --pivot echo "Copy XML to backup drive..." cp -f /etc/libvirt/qemu/${VM}.xml ${DST}/ # Make sure, snapshot merging was successfull image_path=$(virsh domblklist ${VM} --details | \ grep vda | \ awk '{ print $4; }' | \ cut -d "/" -f -5) if [[ "$image_path" == "/var/lib/libvirt/images" ]]; then echo "Remove snapshot..." rm -f ${SNAP}/backup-snapshot-${VM}.qcow2 fi done touch ${DST}/LATEST_$date echo "Syncing disk..." sync umount ${DST} rm -f /tmp/backup-running exit 0 # vim: expandtab ts=4 sw=4
Angepasst werden kann mount/umount. Jenachdem, ob man eine Platte mounten muss. DST ist das Zielverzeichnis, in dem alle Aktualisierungen laufen.
Snapshots sind bei mir extern. Ich habe mir ein Verzeichnis /var/backups/snapshots erstellt und die Benutzerrechte so angepasst, dass der libvirt-Benutzer darauf Schreibrechte hat.
Danach kann das Skript problemlos in einem Cron-Job laufen.
Bitte auf eigene Gefahr und mit Eigenverantwortung verwenden. Ich kann nicht für Schäden garantieren. Dieser Artikel ist nur eine Idee, wie man es machen kann.
Hinweise aus den Kommentaren
Ich bedanke mich für Kommentare. Ich stelle folgende Info noch bereit:
Das Blockcommit- Feature steht erst mit QEMU 2.1 und libvirt-1.2.9 zur Verfügung.
WICHTIGE ANMERKUNG: In Version 2.3.0 und 2.4.0 bricht das blockcommit-Feature! Ich habe dazu einen Bug-Report eröffnet und bereits Feedback erhalten, dass eventuell ein passender Fix bereits im Master-Branch des Projektes eingefügt wurde. Ich habe den Master-Branch jetzt direkt in einem 24h Test. Bis dahin betrachtet bitte dieses Script als experimental.
Update: Weitere Hinweise hier: http://wiki.libvirt.org/page/Live-disk-backup-with-active-blockcommit
Hi!
Es wäre vielleicht noch erwähnenswert, dass das Blockcommit- Feature erst mit QEMU 2.1 und libvirt-1.2.9 (bei RHEL/CentOS 7 scheint es für die libvirt 1.2.8 zurück portiert worden zu sein) funktioniert.
Um QEMU 2.1 unter CentOS 7 nutzen zu können, kann man sich auch an den RPMs des oViRT Projekts vergreifen, da CentOS 7 Base afaik nur mit QEMU 1.5.3 ausgeliefert wird, welches leider hoffnungslos veraltet ist. Wie es bei anderen LTS Distros aussieht weiß ich nicht, aber man sollte das vielleicht mit den Versions-Voraussetzungen wie gesagt noch erwähnen.
Ganz herzlichen Dank. Daran habe ich gar nicht gedacht. Entwickelt habe ich das Skript auf Debian 8. Ich selbst nutze es unter Gentoo. Da gibt es grundsätzlich keine „zu-alt“ Probleme 🙂 Ich nehme die Infos von dir mit rein. Vielen Dank.
Ich habe das Script noch mal etwas verfeinert.
Hallo noch mal Michael,
ich hatte mit dem Script unter Gentoo Probleme. Derzeit teste ich den Master-Branch aus, weil vermutlich dort ein Bug in Zusammenhang mit dem „virsh blockcommit“ gefixt wurde. Test läuft jetzt (ich lasse das 24h laufen).
Unter Debian stable konnte ich das Problem nicht feststellen.
Hi Christian,
freut mich zu hören, dass das Live-Backup wieder funktioniert.
Da ich primär RHEL bzw eigentlich CentOS mit selbstkompilierten Paketen aus den Enterprise Virtualization Sourcen einsetze, hatte ich diese Probleme jetzt nicht. Das lag aber auch an den etwas älteren Versionen die dort zum Einsatz kommen.
Ich muss mal schauen, ob ich dein Script so auch gefahrlos zur Sicherung meiner VMs nutzen kann.
Wäre vielleicht interessant zwecks Abwärtskompatiblität.
Vielen Dank für das Script! Da ich erst seit kurzem mit KVM experimentiere hat es mir sehr weitergeholfen. Eine Sache möchte ich anmerken: es langt nicht, dass qemu-guest-agent auf den Gästen installiert ist, es muss auch laufen! Unter Debian 8.3 (sowohl Host als auch Gast) habe ich das bisher nicht geschafft. Mit virt-manager 0.9.5 habe ich keinen entsprechenden Channel erstellen können, noch kann ich durch Editieren des XML einen Channel ensprechend https://www.gonzalomarcote.com/2014/qemu-guest-agent/ oder http://dustymabe.com/2013/06/26/enabling-qemu-guest-agent-anddddd-fstrim-again/ hinzufügen. Nach dem Editieren ist die Channeldefinition sofort wieder verschwunden. QEMU 2.1.2 und libvirt 1.2.9. qemu-quest-agent meldet dann „qemu-ga: transport endpoint not found, not starting“. Eine Notlösung wäre „virsh send-key ${VM} KEY_LEFTALT KEY_SYSRQ KEY_S“.
Das ist richtig, der Agent muss laufen und der Channel muss existieren. Ich kann nicht genau sagen, warum die Definition im XML sofort wieder bei dir verschwindet. Bei mir erstellt libvirt nach dem Editieren automatisch einen Block in in dieser Form:
Vielleicht liegt es an einer zu alten Version?
Habe es jetzt hinbekommen. Genau diesen XML-Schnipseln, wie auch von Dir gepostet, sieht man leider nicht an, wohin sie ins XML der VM gehören 😉 Ich hatte es einfach an der falschen Stelle. Die Channel-Definition muss innerhalb von . Dann funktioniert auch der Channel.
Ich habe Dein Skript um die Fähigkeit erweitert, auch mit mehreren Platten pro Gast umzugehen. Ich werde das noch weiter überarbeiten und fitt für die Veröffentlichung machen. Vielen Dank nochmal für die Anregung.
Gern geschehen 😊
Hallo zusammen,
was passiert eigentlich, wenn ich den Parameter: -quiesce weg lasse? Wird
das Backup dann inkonsistent oder macht libvirt etwas anders/schlechter?
Viele Grüße
Tim
Hallo, das ist schon eine Weile her, dass ich das geschrieben haabe. Von daher kann ich keine absolut sichere Antwort geben.
So, wie ich es in Erinnerung habe, soll ja ein Snapshot angelegt werden und ab diesem Zeitpunkt sollen Änderungen ins Snapshot laufen. Ich glaube, –quiesce teilt über den qemu-Guest-Agent dem System mit, dass es zum Erstellungszeitpunkt keine Daten mehr schreibt.
Aber wie gesagt, so ganz genau weiß ich das nicht mehr. Sollte theoretisch auch ohne diesen Parameter gehen. Bei Systemen ohne dem qemu-Guest-Agent muss es ja auch laufen. Kann dann halt wahrscheinlich sein, dass u.U. noch paar Daten ins echte Disk-Image laufen und nicht ins Snapshot. Aber inkonsistent dürfte es trotzdem nicht werden.
Keine Garaneite 🙂