blog.bressure.net

Carnet professionnel d'un informaticien

Sauvegarde à chaud de VM

admin

Avoir du RAID redondé c’est bien pour éviter la coupure de service en cas de panne matériel mais cela ne protège pas des effacements par erreur. Il faut des sauvegardes.

Comme ce que je recherche c’est de pouvoir revenir à  un l’état de mes données dans le passé, je laissz dz côté la sauvegarde de la définition des VM.

Un script glané sur le site de Debian me sert de base https://wiki.debian.org/fr/RsyncSnapshots. Il utilise rsync avec des liaison dur avec la précédente sauvegarde. Un peu inutile quand les VM sont allumée en permanence mais trouve son intérêt quand les fichiers ne changent pas d’une sauvegarde à l’autre.

Voici le script:

#!/bin/sh
##==========================================================================
## Auteur      : Thierry BRESSURE
## Licence     : GNU GPL v3 – http://www.gnu.org/licenses/gpl.html
## Description : Script de sauvegarde disques des VM
##============================================================================
## Parametres d’entree : liste des profils a sauvegarder.
## Exemple d’appel     : rsync.sh blog kitejust4fun
## Code de retour      :
##  0 – La sauvegarde des disques s’est correctement terminee.
##============================================================================

ROOT_BACKUP=/media/backup
DEVICE_BACKUP=/dev/sdc1

#####################################
# GESTION DE L’APPEL DE LA COMMANDE #
#####################################

# Recuperation des profils passes en parametre.
if [ $# -ne 0 ]
then
    while [ $# -ne 0 ]
    do
        domains= »$domains $1  »
        shift
    done
# Aucun domain n’est passe en parametre, on fait donc la sauvegarde pour tout
# le monde.
else
    # lister les vm
    domains=`virsh list | sed 1,2d | awk ‘{print $2}’`   
fi

###################################
# MONTAGE DU DISQUE DE SAUVEGARDE #
###################################

if [ ! -d $ROOT_BACKUP ]
then
   rm -rf $ROOT_BACKUP
   mkdir $ROOT_BACKUP
fi

montage=0

mount | grep « $ROOT_BACKUP » 2>/dev/null
if [ $? -ne 0 ]
then
mount -t ext4 $DEVICE_BACKUP $ROOT_BACKUP && montage=1

fi

####################################
# BOUCLE DE SAUVEGARDE DES PROFILS #
####################################

for un_domain in $domains
do

date_sauvegarde=$(date « +%Y%m%d_%H%M%S »)

echo
echo « ${date_sauvegarde} – sauvegarde de la VM ${un_domain} »
        echo « —————————————– »
     

nombre_de_sauvegardes=2
# Creation d’un fichier temporaire pour y ecrire les fichiers et
# repertoires a ne pas sauvegarder (pour ne mettre que le fichier
# temporaire en parametre de la commande rsync)
ce_quil_ne_faut_pas_sauvegarder=$(tempfile)
:>$ce_quil_ne_faut_pas_sauvegarder
# Exclusions generales
echo « *~ » >> $ce_quil_ne_faut_pas_sauvegarder

## DECOUVRIR LES DISQUES DE LA VM

        les_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`
               
       

## CREER UN SNAPSHOT
    virsh snapshot-create-as –domain ${un_domain} « ${date_sauvegarde} » –atomic –disk-only

        ## garder en memoire les disques temporaires de la VM

        les_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $3}’`
        les_images_disques_temp=`virsh domblklist ${un_domain} –details | sed 1,2d | grep ^file | awk ‘{print $4}’`

## SAUVEGARDE

  # Si le repertoire de sauvegarde n’existe pas, je le cree.
    if [ ! -d $ROOT_BACKUP/vm_ »${un_domain} » ]
    then
        echo « L’emplacement de la sauvegarde n’existait pas. »
        mkdir $ROOT_BACKUP/vm_ »${un_domain} »
    fi

    ##############
    # SAUVEGARDE #
    ##############
   
    #il peut avoir plus d’un disque à sauvegarder
    for ce_quil_faut_sauvegarder in ${les_images_disques}
    do
    if [ -L $ROOT_BACKUP/vm_ »${un_domain} »/current ] \
        && [ -d $ROOT_BACKUP/vm_ »${un_domain} »/current ]
   then
        # Si une precedente sauvegarde existe, on la lie en dur.
        rsync  –delete-excluded –partial \
       –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
       –link-dest=$ROOT_BACKUP/vm_ »${un_domain} »/current \
–exclude-from « ${ce_quil_ne_faut_pas_sauvegarder} » \
« ${ce_quil_faut_sauvegarder} » \
      $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
else
        # Sinon, on en cree une toute neuve !
      rsync –delete-excluded –partial \
      –skip-compress=gz/jpg/mp[34]/7z/bz2 –stats -rlpthz \
–exclude-from « ${ce_quil_ne_faut_pas_sauvegarder} » \
       « ${ce_quil_faut_sauvegarder} » \
       $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
    fi

    retour_rsync=$?
if [ $retour_rsync -ne 0 ]
then
echo « le disque ${ce_quil_faut_sauvegarder} n’a pas pu etre sauvegarder, on annule le reste »
break
fi      
echo # Pour passer une ligne 🙂

    done

    # Suppression du fichier temporaire qui stocke les repertoires a exclure
    rm $ce_quil_ne_faut_pas_sauvegarder

    #######################
    # GESTION DES ERREURS #
    #######################

    # Pas d’erreur
    if [ $retour_rsync -eq 0 ]
    then
        # La sauvegarde a reussit, on cree un lien « current » pour retenir la
        # derniere.
        rm -f $ROOT_BACKUP/vm_ »${un_domain} »/current 2>/dev/null
        ln -s $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/ \
            $ROOT_BACKUP/vm_ »${un_domain} »/current

        # Si le nombre de snapshots depasse nombre_de_sauvegardes, je purge.
        nombre_snapshots=$((`ls $ROOT_BACKUP/vm_ »${un_domain} » | wc -l` – 1))
        if [ ${nombre_snapshots} -gt $nombre_de_sauvegardes ]
        then
            # On supprime la plus vieille des sauvegardes
            plus_ancienne= »$(ls $ROOT_BACKUP/vm_ »${un_domain} » | head -n 1) »
            rm -rf $ROOT_BACKUP/vm_ »${un_domain} »/ »${plus_ancienne} »
            echo « Purge de la plus ancienne sauvegarde : ${plus_ancienne}. »
        else
            echo « Aucune sauvegarde anterieure ne doit etre supprimee. »
        fi
    # Probleme lors de la sauvegarde rsync
    else
        # La sauvegarde a echouee, on affiche une erreur et on supprime la
        # tentative.
        echo « La commande rsync a echouee pour l’utilisateur ${un_domain}. »
        echo « Suppression de la sauvegarde en erreur : ${date_sauvegarde}. »
        rm -rf $ROOT_BACKUP/vm_ »${un_domain} »/ »${date_sauvegarde} »/
    fi
   

## REBASCULER LA VM VERS CHAQUE DISQUE ORIGINAL
    for un_disque in $les_disques
do
    virsh blockcommit ${un_domain} ${un_disque} –active –verbose –pivot
done
   
## SUPPRIMER LE SNAPSHOT DEVENU INUTILE
        virsh snapshot-delete –domain ${un_domain} –metadata ${date_sauvegarde}

## supprimer les disques temporaires qui ne sont hélas pas supprimés par la commande précédente
for image_temp in $les_images_disques_temp
do
echo « suppression du disque temporaire ${image_temp}… »
rm -rf « ${image_temp} » && echo « $image_temp supprimé »
done
done

###########################
# démontage si nécessaire #
###########################

if [ $montage -eq 1 ]
then
    umount $ROOT_BACKUP
fi

exit 0

Juste pour le plaisir… CC-BY-SA

Tags:

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Back to top