Auto-hébergment : mon système de sauvegarde
Cet article a été publié par Benjamin
le 19-06-11 à 18:58 dans la catégorie Auto hébergement
Tags :
- auto-hebergement
- Libre
- Serveur
La sauvegarde est un élément très important dans l'auto-hébergement. On oublie la sauvegarde, ça crash, on a plus rien...
Pendant
quelques semaines après avoir mis en place mon auto-hébergement, je
n'avais toujours qu'un seul disque dur dans mon serveur, je lui faisais
confiance :)
Et puis j'ai eu un petit problème sur un serveur au boulot, problème qui a miraculeusement été résolu grâce à une sauvegarde efficace. Je me suis donc décidé à investir un peu de mon temps dans la sauvegarde de mon serveur perso.
J'aurai pu choisir de mettre en place un système de RAID1 entre les deux disques mais j'ai préféré opter pour une synchronisation d'un disque vers l'autre plusieurs fois par semaine. Cela me permet de revenir en arrière si besoin. Par exemple, je fais une mise à jour qui se passe mal ou j'écrase un fichier involontairement. Je peux facilement récupérer la configuration ou le fichier de la veille, stocké sur mon deuxième disque, chose qui aurait été impossible en RAID1.
J'ai organisé ma sauvegarde en deux étapes : la base de données MySQL et les répertoires/fichiers de mon système.
Sauvegarde des bases de données
J'ai écrit un script bash qui me permet de faire des dumps de mes bases de données :
#!/bin/sh
#
# Il faut que le user dump ait un droit general de SELECT et RELOAD
MYSQL_BIN_PATH=/usr/bin
MYSQL_DATA_PATH=/var/lib/mysql
MYSQL_HOME=/mysql
FIC_ERR=$MYSQL_HOME/dump/erreur.txt
HOSTNAME=`hostname`
SYSTEME="mail@me.fr"
USER=dump
PASSWD="xxdumpxx"
/bin/rm $MYSQL_HOME/dump/*
LISTE_BASES=`/usr/bin/find $MYSQL_DATA_PATH/* -maxdepth 0 -type d -printf "%f\n" `
for DB in $LISTE_BASES
do
DATABASE=`echo $DB | sed 's/@002d/-/'`
echo base $DATABASE
$MYSQL_BIN_PATH/mysqldump -u $USER --password=$PASSWD --opt --databases --result-file $MYSQL_HOME/dump/$DATABASE.dump $DATABASE 2>>$FIC_ERR
RET=$?
RETOUR=`expr $RETOUR + $RET`
if [ $RET -gt 0 ]
then
MESSAGE="$MESSAGE Erreur de dump de la base $DATABASE\n"
fi
/bin/gzip $MYSQL_HOME/dump/$DATABASE.dump
done
/bin/chmod -R 600 $MYSQL_HOME/dump
/bin/chmod -R 700 $MYSQL_HOME/dump*
if [ $# -gt 0 ] && [ $RETOUR -gt 0 ]
then
echo $MESSAGE | /bin/mail -s "mysql sur $HOSTNAME. Erreur dump des bases" $SYSTEME
fi
Ce script va interroger le nom de mes différentes bases de données stockées sur mon serveur et en fait un dump séparé. Au final, j'obtiens un répertoire /mysql/dump/ qui contiendra les différents dumps de mes différentes bases de données.
Note : L'utilisateur qui fera le dump doit avoir les droits de SELECT, RELOAD et LOCK TABLES sur les bases de données.
Sauvegarde des répertoires/fichiers de mon serveur
Une fois mes bases de données sauvegardées, je vais copier tous les fichiers importants sur le deuxième disque dur. Pour cela, j'utilise rsync :
#!/bin/bash
# $? = code de retour de la dernière commande. 0 si pas de problème
# on additionne les codes de retour à chaque fin de chaque commande, si ça dépasse 0, c'est qu'il y a eu une erreur quelque part
/bin/bash /scripts/dump_mysql.sh
FICHIER_LOG="/scripts/backup_rsync.log"
/bin/rm $FICHIER_LOG
/usr/bin/touch $FICHIER_LOG
echo "*****************************************************************" >> $FICHIER_LOG
/bin/date >> $FICHIER_LOG
echo "*************Dump MySQL *************" >> $FICHIER_LOG
/usr/bin/rsync -rlpgotD --stats --delete --force /mysql/ /backup/mysql/ >> $FICHIER_LOG
RET=$?
RETOUR=`expr $RETOUR + $RET`
echo "*************Configuration Apache /etc/apache2 *************" >> $FICHIER_LOG
/usr/bin/rsync -rlpgotD --stats --delete --force /etc/apache2/ /backup/etc/apache2/ >> $FICHIER_LOG
RET=$?
RETOUR=`expr $RETOUR + $RET`
echo "*********************Home /home/*********************" >> $FICHIER_LOG
/usr/bin/rsync -rlpgotD --stats --delete --force /home/ /backup/home/ >> $FICHIER_LOG
RET=$?
RETOUR=`expr $RETOUR + $RET`
/bin/date >> $FICHIER_LOG
RET=$?
RETOUR=`expr $RETOUR + $RET`
echo "*****************************************************************" >> $FICHIER_LOG
if [ $RETOUR -ne 0 ]
then
echo "Le script de rsync a echoue. Code erreur : "$RETOUR | /usr/bin/mail -s "Erreur script rsync" mail@me.fr
fi
Ce script va faire une sauvegarde (miroir) des répertoires /home/, /mysql/ et /etc/apache2/ vers /backup/home/, /backup/mysql/ et /backup/etc/apache2. /backup étant le point de montage de mon disque de sauvegarde.
Voici une explication des arguments de rsync :
- rsync : appelle le programme rsync
- -r : parcours le dossier indiqué et tous ses sous-dossiers
- -l : copie les liens symboliques comme liens symboliques
- -t : préserve les dates
- -g : préserve le groupe
- -o : mettre le propriétaire du fichier de destination identique à celui du fichier source
- -D : préserve les périphériques
- -p : provoque la mise à jour des permissions sur la destination pour qu'elles soient identiques aux permissions sur la source.
- --force : force la suppression de répertoires même non-vides
- --stats : affiche quelques statistiques de transfert de fichiers, ce qui permet de vérifier l'efficacité de la sauvegarde.
- --delete : efface avant le transfert les fichiers qui n'existent pas sur la source.
Automatisation de la sauvegarde
Je n'ai plus qu'à appeler le script ci-dessus à la fréquence à laquelle je souhaite faire mes sauvegardes dans le cron. Voici ma crontab :30 23 * * 1,4,6 /root/scripts/backup_rsync.sh >/dev/null 2>&1
Ainsi, tous les lundis, jeudis et samedi à 23h30, je sauvegarde les répertoires importants de mon disque 1 vers mon disque 2.
Bonus
Je fais également une sauvegarde de mes bases de données et de mon répertoire www sur une clé USB une fois par mois avec ce script :#!/bin/bash
# $? = code de retour de la dernière commande. 0 si pas de problème
# on additionne les codes de retour à chaque fin de chaque commande, si ça dépasse 0, c'est qu'il y a eu une erreur quelque part
MAIL_CONTACT='mail@gmail.com'
FICHIER_LOG="/root/scripts/logs/backup_usb.log"
REP_DEST="/mnt/usb/`date +%d%m%Y`"
/bin/rm $FICHIER_LOG
/usr/bin/touch $FICHIER_LOG
/bin/mount /dev/sdc1 /mnt/usb/
/bin/rm -rf /mnt/usb/*
/bin/mkdir $REP_DEST
echo "*****************************************************************" >> $FICHIER_LOG
/bin/date >> $FICHIER_LOG
echo "*************Copie des répertoires /mysql *************" >> $FICHIER_LOG
/bin/cp -pr /mysql/ $REP_DEST
RET=$?
RETOUR=`expr $RETOUR + $RET`
echo "*************Copie du répertoire /www *************" >> $FICHIER_LOG
/bin/cp -pr /www/ $REP_DEST
RET=$?
RETOUR=`expr $RETOUR + $RET`
/bin/date >> $FICHIER_LOG
RET=$?
RETOUR=`expr $RETOUR + $RET`
echo "*****************************************************************" >> $FICHIER_LOG
if [ $RETOUR -ne 0 ]
then
echo "Le script de backup USB a echoue. Code erreur : "$RETOUR | /usr/bin/mail -s "Erreur script backup USB" $MAIL_CONTACT
fi
/bin/umount /mnt/usb/
Si vous cherchiez des pistes pour sauvegarder votre serveur, j'espère vous avoir un peu éclairé.
Comme toujours, si vous avez des suggestions à me proposer ou si vous souhaitez des précisions supplémentaires sur ces scripts, n'hésitez pas à demander.
Par ailleurs, je serais curieux de connaitre vos moyens de sauvegarde en auto-hébergement :)
Commentaires
De mon coté, j'ai un script du même pour les dumps sql. Autrement je mixe des rsync et le génial Rsnapshot qui est à base de rsync mais qui permet de gérer la retention des sauvegardes (7 journalières,4 hebdos et 12 mensuels soit 23 versions). Il gère les fichiers identiques pour les différentes versions en faisant des liens (ce qui évite l'explosion de taille).
Le tout est stocké soit sur autre poste de mon réseau local (le /etc, /var/log) soit sur le serveur d'un pote pour le /var/www.
Pour les synthèses, j'utilise soit des checks nagios maisons ou des mails.
Je dors l'esprit tranquille (enfin dans le meilleur des mondes car en ce moment j'ai un des mes postes qui accueillait mes sauvegardes est mort....)
Je crois qu'il faut aussi penser au sinistre majeur (incendie, grosse surtension, vols complets,etc). Bref le truc qui fait que tu as plus rien chez toi de fonctionnel. La soluce: soit pusher ses données ailleurs (dans mon cas chez un serveur distant d'un pote) soit en gravant des cd de temps à temps à laisser chez de la famille/amis. Faut tout racheter et remonter des achines mais tu as toujours les données!
Bonjour,
pour ma part, je n'ai pas (encore) de base Mysql hébergée. Pour le moment, il n'y a que du mail sur une Debian stable.
Pour les sauvegardes, j'utilise rdiff-backup qui me permet de faire des incrémentielles. Je garde 1 mois de sauvegarde stocké sur mon NAS qui, lui, est en RAID1.
En plus, je maintiens une machine virtuelle sur une autre machine que le serveur qui me permet de remonter ma sauvegarde et faire fonctionner mon serveur le temps que la machine physique soit à nouveau en état de marche.
Voici mon script de sauvegarde, il est surement perfectible mais pour le moment, il me va:
#!/bin/bash
DATE=`date +%Y%m%d-%H%M`
REP_LOG=/var/log/sauvegarde
LOG=$REP_LOG/sauvegarde.$DATE.log
BACKUP_DEV=serveur_nas:/nfs/sauvegardes
BACKUP_MOUNT=/NAS/sauvegardes
MACHINE=serveur_a_sauvegarder
echo "`date +%H:%M:%S` - Début de la sauvegarde" > $LOG
echo "" >> $LOG
echo "`date +%H:%M:%S` - Sauvegarde des paquets" >> $LOG
echo "" >> $LOG
nice -n 19 dpkg --get-selections > /root/sauvegarde/paquets_installes.txt
echo "`date +%H:%M:%S` - Montage du volume NAS" >> $LOG
echo "" >> $LOG
mount -t nfs -o rw $BACKUP_DEV $BACKUP_MOUNT >> $LOG 2>> $LOG
if [ $(mount | grep $BACKUP_DEV | grep $BACKUP_MOUNT | wc -l) -lt 1 ]
then
echo "Erreur de montage du peripherique de sauvegarde." >> $LOG 2>> $LOG
exit 1
fi
echo "`date +%H:%M:%S` - Sauvegarde du système" >> $LOG
echo "" >> $LOG
nice -n 19 rdiff-backup -v5 --exclude-globbing-filelist /root/sauvegarde/EXCLUDE.lst / $BACKUP_MOUNT/system/$MACHINE >> $LOG 2>&1 && nice -n 19 rdiff-backup -v5 --remove-older-than 1M --force $BACKUP_MOUNT/system/$MACHINE >> $LOG 2>&1
echo "" >> $LOG
echo "`date +%H:%M:%S` - Suppression des logs de sauvegarde périmés" >> $LOG
echo "" >> $LOG
find $REP_LOG -xdev -name "sauvegarde.*" -mtime +30 -type f -exec rm -f {} \;
echo "" >> $LOG
echo "`date +%H:%M:%S` - Démontage du volume NAS" >> $LOG
echo "" >> $LOG
umount $BACKUP_MOUNT >> $LOG 2>> $LOG
echo "" >> $LOG
echo "`date +%H:%M:%S` - Fin de la sauvegarde" >> $LOG
Salut, juste pour dire qu'en aucun cas le RAID est un système de sauvegarde et surtout qu'il ne permet pas de s'affranchir d'une politique de sauvegarde digne de ce nom.
Sinon ton article est intéressant mais pourquoi ne pas faire une sauvegarde sur disque externe plus régulièrement ? Un alim qui brule entrainant un court jus des disques et tu as presque tout perdu...
Pour ma part, je suis plutôt adepte de la solution rdiff-backup, tout comme Pierre, sauf que je pousse jusqu'à une sauvegarde toutes les heures (en mode fichier, je ne fais des dumps de base que tous les jours). En fait, rdiff-backup est tellement efficace qu'on peut vraiment l'utiliser sur des intervalles super court (comme moi, 1h) avec des rétentions super longues (personnellement 6 mois).
Et je me permet de rejoindre Guiona : un disque dur externe, c'est certes plus encombrant et moins performant, mais il y a moins de risque de tout cramer. Et en plus, tu peux le prendre en vacances pour éviter de perdre tes données en cas de cambriolage :)
Pendant longtemps, je n'ai pas fait de sauvegardes et j'ai eu de la chance.
Je pense que la politique de sauvegarde doit couvrir au mieux les risques redoutés pour être efficace. Si le risque majeur est seulement la panne disque, le RAID1 est prévu pour. Si ce risque redouté est une panne de l'alimentation du serveur ou toute autre chose pouvant détériorer le/les disque(s), alors une sauvegarde externe sera plus appropriée ou à utiliser en complément. Si le risque majeur est le vol, l'incendie ou autre chose du genre, mieux vaut prévoir de faire ses sauvegardes sur une machine distante par exemple.
Moi, je n'ai pas une confiance absolue dans mon matériel (on n'est jamais à l'abri d'une panne).
Maintenant, je fais une sauvegarde automatique hebdomadaire de mes bases de données que je m'envoie ensuite par mail (c'est perfectible mais j'ai tout, c'est l'essentiel). Les données sont elle sauvegardés de manière incrémentielle (via rsync) chaque nuit sur un NAS, à côté de mon serveur.
J'en ai eu l'utilité pas plus tard que la semaine dernière car j'ai effacé par erreur un dossier important pour moi sur le serveur. J'ai donc juste eu à aller chercher la copie sur le NAS et à la placer à sa place.
Bonjour
J'avais l'habitude d'écrire mes scripts de backup jusqu'a que je découvre backup-ninja.
C'est une suite de scripts qui automatise les backups de mon serveur MySQL, SVN, LDAP logs et quelques répertoires avec copie en rdiff-backup :)
Tout ca avec très peu de lignes de configuration des services!! Bref que du bon.
Plus jamais je ne ferais de script de backup moi même vu la qualité de ce qui existe déjà :)
Bref je vous recommande vivement de l'essayer ^^
Bonsoir,
Très intéressant ce lieu d'échange en français. J'en suis à mes débuts d'hébergeur à la maison. Pour ma part je fais une sauvegarde du /home/vmail, var/www et bases de données MySQL chaque semaine sur un 2e disque avec rsync sur mon serveur et une deuxième fois sur un disque externe que je peux transporter avec moi lors de mes absences.
J'ai également sauvegarder mes fichiers de configurations bind pour mon DNS primaire public et aussi mon DNS privé.
J'ai commencé à mettre la doc sur mon site mais ça évolue lentement...
Bonjour,
pour ma part, j'utilise rsnapshot (http://rsnapshot.org). Il est très simple à configurer (un seul fichier de config), il utilise RSYNC et permet de faire de la rotation. De plus, il utilise très peu d'espace disque grâce aux hard links. Il peut faire de la sauvegarde locale ou distante de plusieurs machines via SSH (pas besoin d'agent donc). Possibilité d'exécuter des scripts avant sauvegarde (comme par exemple un dump de bases de données). Il permet également de générer des rapports de sauvegarde et de les envoyer par email. Je l'utilise au travail pour sauvegarder tous nos serveurs BSD/Linux ainsi que pour mon serveur perso.
Essayez-le ça vaut le coup !
Simple, bourrin, j'avais pas trop de temps, mais je pense que ça marche...
rsync -avz /{bin,boot,dev,etc,home,lib,opt,root,sbin,selinux,srv,usr,var,vmlinuz
} /media/SD-Backup/
J'ai fais un cron hebdomadaire dessus.
Mon seul problème est que la sauvegarde incrémentielle sature le disque de backup au bout d'un moment (les fichiers supprimés dans le disque ne le sont pas dans celui de sauvegarde).
Mais ça doit être une option de rsync.