Sauvegarde des jails

Un mien camarade qui se reconnaitra a eu une mauvaise expérience. La machine qu’il louait pour ses effets personnels (mails, site web, photo, etc) est tombée en carafe.

À moins d’avoir les moyens de payer une autre machine de stockage pour les sauvegardes, comment faire ?

Du coup, je me suis interrogé sur la sauvegarde de toutes les jails que j’utilise sur mon serveur et de leur sauvegarde.

Il y a les snapshots, mais les snapshots NE SONT PAS DES SAUVEGARDES. Ils résident sur la même machine que les données, sur les mêmes disques. Si le disque meurre, les snapshots s’envolent avec lui.

Par contre, on peut se servir des snapshots comme point de départ d’une sauvegarde externe.

  Il faut bien sûr avoir de quoi faire cette sauvegarde externe, Un NAS personnel, de la place sur la machine d’un copain (qui peut utiliser de la place sur votre machine pour ces sauvegardes), etc.

  On suppose donc que vous avez un « endroit » pour stocker vos sauvegardes.

  Je vais sauvegarder mes jails sur une machine qui n’a pas ZFS, c’est plus facile sur une machine qui utilise ZFS, je verrais un autre billet à ce sujet.

ezjail-admin et les snapshots automatiques

Vous l’avez vu, j’utilise ezjail pour gérer mes jails1. Et ezjail-admin a une fonctionnalité intéressante qui est de faire des snapshots des toutes les jails quand on l’invoque et de nettoyer les snapshots trop vieux.

C’est cette commande qui va être au cœur de notre script, c’est même par elle qu’il va commencer (après les définitions d’usage).

Faire un snapshot de toutes les jails

C’est la commande ezjail-admin avec le paramètre snapshot qui va faire le travail pour nous.

1
2
3
4
5
6
LOG=/var/log/backupJails.log

debug=0
# Create new snapshot

/usr/local/bin/ezjail-admin snapshot


Trouver le nombre de Jail

C’est en fait l’indice de la boucle qui va nous faire faire une sauvegarde de toutes les jails.

1
2
3
4
5
# Find number of jail

NB_JAILS=$(/usr/local/bin/ezjail-admin list | /usr/bin/grep -v STA |
  /usr/bin/grep -v "\--" | /usr/bin/wc -l)
DATUM=$(/bin/date +"%F")


La boucle

Dans cette boucle nous allons récupérer les derniers snapshots faits. Ils sont reconnaissables à leur nom qui comprend la chaîne autosnap.

1
2
3
4
5
# Loop

for lastsnap in $(/sbin/zfs list -t snapshot -o name,creation -s creation |
  /usr/bin/grep ez-autosnap- | /usr/bin/tail -n "${NB_JAILS}"|awk '{print $1}')
do


Définition des différentes variables

Il nous faut définir quelques variables que nous allons utiliser et qui sont propres à chaque jails. Par la même occasion nous definissons un petit mode debug qui ne fait qu’afficher le contenu des variables en questions.

1
2
3
4
5
6
7
8
  jailName=$(echo "${lastsnap}" | /usr/bin/awk -F / '{print $3}'| /usr/bin/awk -F @ '{print $1}')
  snapName=$(echo "${lastsnap}" | /usr/bin/awk -F @ '{print $1}')
  compressedName=$(echo "${jailName}"."${DATUM}".xz)
  if [ "${debug}" == 1 ] ; then
    echo "lastsnap == ${lastsnap}"
    echo "jailName == ${jailName}"
    echo "snapName == ${snapName}"
    echo "compressedName == ${compressedName}"


Le morceau de choix

C’est que nous allons utiliser la commande zfs send qui va créer un flux de données que nous allons compresser dans un fichier temporaire. Ce fichier est envoyé sur la machine distante qui stockera la fichier compressé. J’ai choisi d’utiliser le format de compression xz qui prend plus de temps et de cpu que gzip, mais qui est plus efficace.

Une fois envoyé sur la machine distance (commande scp), le fichier est supprimé pour éviter que les sauvegardes soient à l’origine d’un remplissage intempestif des disques.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  else
    echo "$(/bin/date +"%F-%T") Compress ${snapName}" >> ${LOG}"
    /sbin/zfs send "${lastsnap}" | xz > /tmp/"${compressedName}"
    echo "$(/bin/date +"%F-%T") Send ${snapName}" >> "${LOG}"
    /usr/bin/scp /tmp/"${compressedName}" octopuce:/data/backupJails/.
    echo "$(/bin/date +"%F-%T") Remove ${snapName}" >> "${LOG}"
    /bin/rm /tmp/"${compressedName}"
    echo "-----------------------------------------------------------" >> "${LOG}"
  fi
done


Fin, on envoie un mail

On finit le script par l’envoi d’un mail avec le contenu du log.

1
2
/usr/bin/mail -s "Backup jail $(date +"%F")" admin@exodus-privacy.eu.org < "${LOG}"
/bin/rm/"${LOG}"


La restauration

Pour restaurer une jail, on fait l’inverse. On copie le fichier de sauvegarde sur la machine hôte, on décompresse et on envoie à zfs receive.

 # xs -d fichier_jail.xz | zfs receive zroot/ezjail/jailname


Conclusion

Ce script est loin d’être parfait, aucun test de code retour de commande, pas de gestion d’erreur est un début pour avoir un semblant de sauvegarde.


  1. Je ne me suis pas encore mis à iocage, plus récent et maintenu contrairement à ezjail [return]