KVM Full backups de virtual disks (qcow2) con virsh + rsync
Cuando utilizamos KVM (qemu + libvirt) para virtualizar podemos utilizar diferentes métodos para los discos virtuales de las VMs (LVM, Raw, QCow2, etc) mi preferencia pasa por utilizar qcow2 como formato de disco virtual.
Por defecto, todos los archivos de discos virtuales se guardan en /var/lib/libvirt/images
En el ejemplo vemos una infraestructura de 3 servidores (Ardenas, Siracusa, Zama) que virtualizan con KVM y tienen N cantidad de VMs.
BKPServer es un servidor dedicado exclusivamente a tareas de backups el cual tiene (vamos a suponer) un partición con espacio suficiente para alojar todos los archivos de los discos virtuales que existen en Ardenas, Siracusa & Zama. El objetivo obviamente es disponer de un backup full de todas las VMs una vez a la semana y hacerlo de forma centralizada. Para ello BKPServer debe conectarse a cada uno de los servidores, suspender las VMs , transferir desde los servidores a BKPServer los archivos *.img, conectarse a los servidores y hacer un virsh resume a las VMs.
Requisitos
- red gigabit
- rsync en modo daemon en cada server KVM
- acceso mediante ssh-key desde bkpserver a cada server KVM
- crontab en bkpserver
/etc/rsyncd.conf
Este es el archivo de configuración /etc/rsyncd.conf a modo de ejemplo que vamos a usar en los servidores KVM. Les recuerdo que en Debian para iniciar rsync en modo daemon además de instalarlo deben editar el archivo /etc/default/rsync
No pretendo explicar cómo se configura rsync, solamente aclaro que el share “libvirt” permite sólo lectura y conexión desde la IP 172.16.10.234 que en este caso es el server BKPServer.
#motd file=/etc/motd
#log file=/var/log/rsyncd
# for pid file, do not use /var/run/rsync.pid if
# you are going to run rsync out of the init.d script.
# pid file=/var/run/rsyncd.pid
#syslog facility=daemon
#socket options=
use chroot = yes
max connections = 10
lock file = /var/lock/rsyncd
transfer logging = no
timeout = 600
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz *.jpg *.png *.gif *.swf *.img
[libvirt]
comment = /var/lib/libvirt
path = /var/lib/libvirt
uid = root
gid = root
hosts allow = 172.16.10.234
hosts deny = *
read only = yes
list = yes
strict modes = yes
ignore errors = yes
ignore nonreadable = yes
SSH keys
Para que desde BKPServer se pueda hacer suspend & resume remotamente de las VMs vamos a generar un juego de ssh keys y agregarlas al ~/authorized_keys del usuario root en Ardenas, Siracusa & Zama. Tampoco voy a explicar cómo generar un juego de llaves ssh, aunque pueden ver cómo hacerlo en este link: how generate ssh-keys
Dado que vamos a usar el usuario root para conectarnos, como medida de seguridad extra haremos 2 cambios.
Editaremos el archivo /root/.ssh/authorized_keys y agregaremos al comienzo de la key ssh un from=”172.16.10.234″ tal como se muestra a continuación para limitar el acceso con esa ssh key solamente desde BKPServer.
root@ardenas:~# cat .ssh/authorized_keys
from="172.16.10.234" ssh-rsa AAAAB3NzaC1yc2EAAAADA................... root@bkpserver
También pueden editar el archivo /etc/ssh/sshd_config y cambiar a “no” la opción PasswordAuthentication, pero mucho cuidado que no podrán acceder con usuario y password, si o si deberán hacerlo con ssh-keys y obviamente deben estar agregadas (previamente) a los ~/.ssh/authorized_keys de los usuarios con los que necesiten hacer login.
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no
/usr/local/bin/virsh-snapshot.sh
Este es el script que realiza los backups y debe estar ubicado en BKPServer. Lo que hace es conectarse mediante con virsh -c qemu+ssh, suspende cada una de las VMs, hace un rsync desde alguno de los servidores KVM a (en este caso) /var/lib/bulk/libvirt/public/img/, se vuelve a conectar con virsh -c qemu+ssh y hace un resume de la VM, dependiendo del tamaño que ocupe el *.img puede demorar unos pocos minutos a un par de horas.
En el script se considera que los archivos *.img se llaman exactamente igual que el nombre de la VM, que podemos ver con virsh -c qemu+ssh://172.16.10.200/system list –all
#! /bin/bash
# Usage suspendCopyResume IP VM
function suspendCopyResume {
virsh -c qemu+ssh://root@$1/system suspend $2
rsync -avrp --partial --progress rsync://$1/libvirt/images/$2.img /var/lib/bulk/libvirt/images/
virsh -c qemu+ssh://root@$1/system resume $2
}
suspendCopyResume "172.16.10.200" "KDDServer"
suspendCopyResume "172.16.10.200" "Bejerman"
suspendCopyResume "172.16.10.200" "DBMaster01"
suspendCopyResume "172.16.10.200" "Lepanto"
suspendCopyResume "172.16.10.200" "ADServer"
suspendCopyResume "172.16.10.202" "SSAS01"
suspendCopyResume "172.16.10.200" "Trafalgar"
suspendCopyResume "172.16.10.202" "Arauco"
crontab
Y por último necesitamos automatizar todo este proceso en BKPServer, que por supuesto lo haremos en el cron de root.
Tal como se muestra a continuación, se hacen 3 cosas.
- Se borran de /var/lib/bulk/libvirt/public/img/ todos los *.img copiados previamente
- A pesar de que usamos ssh-keys, cron no toma el path /root/.ssh/ por lo que debemos agregar la ssh private key con ssh-agent & ssh-add
- Ejecutamos /usr/local/bin/virsh-snapshot.sh propiamente dicho que realiza toda la tarea
MAILTO=""
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
25 23 * * 5 /bin/rm /var/lib/bulk/libvirt/images/*.img
30 23 * * 5 /bin/bash /usr/bin/ssh-agent;/usr/bin/ssh-add;/usr/local/bin/virsh-snapshot.sh
Se entiende que si en los servidores KVM agregan/quitan VMs, deben editar el script /usr/local/bin/virsh-snapshot.sh para asegurarse de que backupean correctamente todas sus VMs. Tambien se aclara que este script sólo copia los *.img, no los *.xml que contienen la configuración de cada VM aunque fácilmente pueden agregar los cambios necesarios para guardar también los *.xml.
Para una completa referencia sobre el comando virsh, pueden consultar la documentación online: http://libvirt.org/sources/virshcmdref/html/