km.azerttyu.net

Accueil > Du km au texte > informatique > Sauvegarder sur bandes ses machines virtuelles

Sauvegarder sur bandes ses machines virtuelles

jeudi 14 janvier 2010, par km

Pour limiter le nombre serveurs à utiliser et d’isoler les différents services, je découpe l’ensemble à l’aide de machines virtuelles Xen. La machine hôte fournis une partition LVM pour chacune de ses machines. La question se pose alors de comment sauvegarder l’ensemble en conservant la cohérence des données.

Principe

Nous aborderons une solution simple pour sauvegarder un ensemble de partitions LVM. Nous nous appuierons sur les subtilités de LVM et de ses snapshots

LVM et Les snapshots

Avant d’aborder les snapshots (copie de volume), il faut rapidement rappeler comment fonctionne LVM.

LVM agrège un ensemble de disques dur physiques et fournit un groupe de volumes logiques. Ce sont les volumes logiques qui seront vu par le système.

Ces volumes logiques stockent les données à l’aide des extent ce sont des blocs de données réservés. LVM essaiera toujours d’écrire l’ensemble des donnés d’un fichier dans le même extent. Cette approche limite la fragmentation. Enfin pour chaque volume, un tableau de description est présent pour indiquer l’ensemble des états de tous les extent.

Dans le cas d’un snapshot (cliché), comme on pourrait l’imaginer ce n’est pas une réplique exacte qui est faite. Le snapshot copie la description des états de tous les extent du volume d’origine. Un snapshot gère uniquement les différences entre elle et son volume père.

Lorsque le volume d’origine est modifié, l’extent qui supporte ces données est copié avant modification dans le snapshot. Le tableau de description est mis à jour en conséquence. Le snapshot ainsi conserve l’état du volume père au moment de sa création.

Cette approche permet de créer des volumes de taille inférieure au volume d’origine tout en gardant l’intégrité des données. Selon les documentations on peut considérer que la taille du snapshot peut faire dans les 15 à 20% du volume d’origine.

Pour se faire une idée plus claire et en images, je vous invite à consulter le site de Suno Ano.

Le script de backup

La partie du script spécifique à la sauvegarde profite pleinement du travail réalisé par Vivek Gite. On trouvera quel que ajustements déjà présenté dans le forum de sa page mais non intégré dans le script original.

Les fonctions de gestions des partitions

L’originalité de ce script repose sur la création et le montage des snapshot.

Nous avons un lot de fonctions :

  • snapshot_create()
  • snapshot_remove()
  • snapshot_create_all()
  • snapshot_remove_all()

Les 2 premières s’occupent de gérer la création, suppression d’un volume donné ainsi que son (dé)montage. Les 2 autres font appel aux précédentes pour gérer un lot de volume à sauvegarde.

« snapshot_create() » est surement la fonction la plus intéressante. Son travail consiste à créer une partition de type snapshot.
Il n’est pas nécessaire de faire une copie de taille identique, et il est pertinent d’optimiser l’occupation de la machine hôte. Ainsi la fonction calcule la taille du snapshot à hauteur de 20% (ratio empirique) du volume père. On notera une subtilité avec la gestion des langues, ceci est du au format de retour de certaines des fonctions appelées (bc et lvs) qui diffère selon la langue active.
Cette taille peut être largement réduite en fonction de l’espace disponible sur votre serveur et de la quantité de modifications de données au moment de la sauvegarde.

En prenant en compte tous ces détails, nous obtenons un script qui tourne en production sans problèmes.

Le script complet

  1. #!/bin/bash
  2. # Original script provided by Vivek Gite <vivek@nixcraft.com>
  3. # -------------------------------------------------------------------------
  4. # Copyright (c) 1999 Vivek Gite <vivek@nixcraft.com>
  5. # This script is licensed under GNU GPL version 2.0 or above
  6. # -------------------------------------------------------------------------
  7. # This script is part of nixCraft shell script collection (NSSC)
  8. # Visit http://bash.cyberciti.biz/ for more information.
  9. # -------------------------------------------------------------------------
  10. # Last updated on : March-2003 - Added log file support.
  11. # Last updated on : Feb-2007 - Added support for excluding files / dirs.
  12. # -------------------------------------------------------------------------
  13. # Actual script adapted by Camille Lafitte
  14. # <cam.lafit@azerttyu.net>
  15. # -------------------------------------------------------------------------
  16. # Last updated on Dec 2009 : Add mail notification from Vivek forum ( backup_notify )
  17. # Last updated on Dec 2009 : Mange date by number for better i18n support
  18. # Last updated on Dec 2009 : Add LVM snapshots support ( snapshot_* functions )
  19. #
  20. # A UNIX / Linux shell script to backup dirs to tape device like /dev/st0 (linux)
  21. # This script make both full and incremental backups.
  22. # You need at two sets of five tapes. Label each tape as Mon, Tue, Wed, Thu and Fri.
  23. # You can run script at midnight or early morning each day using cronjons.
  24. # The operator or sys admin can replace the tape every day after the script has done.
  25. # Script must run as root or configure permission via sudo.
  26. #
  27. # Script to backup a group of LVM volumes on tape device
  28. # -------------------------------------------------------------------------
  29. LOGBASE=/var/log/tar_back
  30.  
  31. #LV to backup
  32. LV_NAME="vg00/machine1 vg00/machine2 vg01/machine1"
  33.  
  34. # Backup dirs; do not prefix /
  35. BACKUP_ROOT_DIR="mnt/snapshots/"
  36. BACKUP_SNAP_DIR="/mnt/snapshots"
  37.  
  38. # Get todays day like Mon, Tue and so on
  39. NOW=$(date +"%w")
  40.  
  41. #Mail notifier
  42. MAIL_NOTIFIER="c.lafitte@dombox.fr"
  43.  
  44. # Tape devie name
  45. TAPE="/dev/st0"
  46.  
  47. # Exclude file
  48. TAR_ARGS=""
  49. EXCLUDE_CONF=/root/.backup.exclude.conf
  50.  
  51. # Backup Log file
  52. LOGFILE=$LOGBASE/$NOW.backup.log
  53.  
  54. # Path to binaries
  55. export PATH=/usr/local/bin:/usr/local/sbin:/bin:/sbin:$PATH
  56.  
  57. TAR=/bin/tar
  58. MT=/bin/mt
  59. MKDIR=/bin/mkdir
  60.  
  61.  
  62. # ------------------------------------------------------------------------
  63. # Excluding files when using tar
  64. # Create a file called $EXCLUDE_CONF using a text editor
  65. # Add files matching patterns such as follows (regex allowed):
  66. # home/vivek/iso
  67. # home/vivek/*.cpp~
  68. # ------------------------------------------------------------------------
  69. [ -f $EXCLUDE_CONF ] && TAR_ARGS="-X $EXCLUDE_CONF"
  70.  
  71. #### Custom functions #####
  72. # Make a full backup
  73. full_backup(){
  74. local old=$(pwd)
  75. cd /
  76. $TAR $TAR_ARGS -cvpf $TAPE $BACKUP_ROOT_DIR > $LOGFILE 2>&1
  77. backup_notify $?
  78. $MT -f $TAPE rewind
  79. $MT -f $TAPE offline
  80. cd $old
  81. }
  82.  
  83. # Make a partial backup
  84. partial_backup(){
  85. local old=$(pwd)
  86. cd /
  87. $TAR $TAR_ARGS -cvpf $TAPE -N yesterday $BACKUP_ROOT_DIR > $LOGFILE 2>&1
  88. backup_notify $?
  89. $MT -f $TAPE rewind
  90. $MT -f $TAPE offline
  91. cd $old
  92. }
  93.  
  94. # Make sure all dirs exits
  95. verify_backup_dirs(){
  96. local s=0
  97. for d in $BACKUP_ROOT_DIR
  98. do
  99. if [ ! -d /$d ];
  100. then
  101. echo "Error : /$d directory does not exits!"
  102. s=1
  103. fi
  104. done
  105. # if not; just die
  106. [ $s -eq 1 ] && exit 1
  107. }
  108.  
  109. snapshot_create_all() {
  110.  
  111. for d in $LV_NAME
  112. do
  113. if [ ! -d /$d ];
  114. then
  115. OIFS=$IFS
  116. IFS='/'
  117. d=( $d )
  118. snapshot_create ${d[0]} ${d[1]}
  119. IFS=$OIFS
  120. fi
  121. done
  122. }
  123.  
  124. snapshot_create(){
  125.  
  126. OLD_LANG=$LANG
  127. LANG=en_us.8859_1
  128.  
  129. VG=$1
  130. LV=$2
  131. #Taille de la partition en Mo
  132. SIZE=`lvs /dev/$VG/$LV -o lv_size --noheadings --units M --nosuffix`
  133. SIZE=${SIZE// /}
  134.  
  135. SNAP_SIZE=$(echo "scale=2;x = $SIZE * 20 / 100;x" | bc)
  136.  
  137. if [ ! -d /dev/$VG/$LV ]
  138. then
  139. lvcreate -L"$SNAP_SIZE"M -s -n $LV.snap "/dev/$VG/$LV"
  140. LANG=$OLD_LANG
  141.  
  142. fsck "/dev/$VG/$LV.snap"
  143. mkdir -p "$BACKUP_SNAP_DIR/$LV"
  144. mount "/dev/$VG/$LV.snap" "$BACKUP_SNAP_DIR/$LV"
  145. fi
  146. }
  147.  
  148. snapshot_remove_all(){
  149.  
  150. for d in $LV_NAME
  151. do
  152. if [ ! -d /$d ];
  153. then
  154. OIFS=$IFS
  155. IFS='/'
  156. d=( $d )
  157. snapshot_remove ${d[0]} ${d[1]}
  158. IFS=$OIFS
  159. fi
  160. done
  161. }
  162.  
  163. snapshot_remove(){
  164. VG=$1
  165. LV=$2
  166.  
  167. umount "$BACKUP_SNAP_DIR/$LV"
  168. lvremove "/dev/$VG/$LV.snap" -f
  169. }
  170.  
  171. backup_notify(){
  172. local s=$1
  173. if [ $s -eq 0 ]
  174. then
  175. echo $LOGFILE |mailx -s "Backup Successfully done @ $(hostname)" $MAIL_NOTIFIER #< $LOGFILE
  176. else
  177. echo $LOGFILE |mailx -s "Backup FAILED @ $(hostname)" $MAIL_NOTIFIER #< $LOGFILE
  178. fi
  179. }
  180.  
  181.  
  182. #### Main logic ####
  183.  
  184. # Make sure log dir exits
  185. [ ! -d $LOGBASE ] && $MKDIR -p $LOGBASE
  186.  
  187. # Verify dirs
  188. verify_backup_dirs
  189.  
  190. # Okay let us start backup procedure
  191. # If it is monday make a full backup;
  192. # For Tue to Fri make a partial backup
  193. # Weekend no backups
  194.  
  195. snapshot_create_all
  196. #Pas de backup le mecredi
  197. case $NOW in
  198. 1|4) full_backup;;
  199. 2|5) partial_backup;;
  200. *) ;;
  201. esac
  202. #esac > $LOGFILE 2>&1
  203.  
  204. snapshot_remove_all

Télécharger

Un message, un commentaire ?

Qui êtes-vous ?
Votre message
  • Pour créer des paragraphes, laissez simplement des lignes vides.