RSYNC : synchroniser deux serveurs

Bonsoir 🙂

Je suis en train de vous écrire un article sur une configuration avec deux serveurs et un load balancer.
A cette occasion, j’ai eu besoin de synchroniser les deux serveurs en question, du serveur A vers le B et réciproquement.

J’ai choisi une synchronisation semi temps-réel, elle s’exécute une fois par minutes via une tâche Cron.

Voici les étapes, a effectué de préférences en root. A faire sur le serveur A, puis à adapter pour votre second serveur.
Ceci peut également serveur pour faire du backup en temps réel ou presque.
A noter également que pour quelques choses de plus pointu d’autres outils seront plus optimisé, n’hésitez pas à proposer des solutions en commentaire 🙂

Le fichier bash à créer pour le Rsync

nano /root/scriptsh/rsync.sh

#!/bin/sh

#Rsync with B server

LOG_FILE=/root/scriptsh/rsync.log
SOURCE_DIR=/var/www/mywebsite/web
DISTANT_DIR=/var/www/mywebsite
DISTANT_USER=admin
DISTANT_HOST=IP
KEY=/root/scriptsh/key.pem

rsync -vrlpEogth --progress --log-file=$LOG_FILE -e "ssh -i $KEY" --rsync-path="sudo -i rsync" $SOURCE_DIR $DISTANT_USER@$DISTANT_HOST:$DISTANT_DIR
chown -R web1:client1 /var/www/mywebsite/web/*

Explication :

Je défini une série de variables:
LOG_FILE: le fichier qui va logger nos opérations
SOURCE_DIR et DISTANT_DIR: le répertoire source sur le serveur actuel et le répertoire distant (à savoir que /web n’est pas nécessaire pour le répertoire distant car ce qui sera envoyé est le répertoire local web et son contenu. Le contenu local sera donc bien dans web sur le serveur distant)
DISTANT_USER: l’utilisateur sur le serveur distant pour la connexion ssh
DISTANT_HOST: l’adresse ip (ou nom de domaine) du serveur distant
KEY: la clé de connexion ssh. Pour utiliser un mot de passe, vous pouvez adapter le code comme ceci :

rsync -vrlpEogth --progress --log-file=$LOG_FILE -e ssh --rsync-path="sudo -i rsync" $SOURCE_DIR $DISTANT_USER:$PASSWORD@$DISTANT_HOST:$DISTANT_DIR
et créer une variable PASSWORD= qui contiendra le mot de passe.
De même, si le serveur ssh se trouve sur un autre port que le port 22, adapter la partie -e "ssh -i $KEY" par -e "ssh -i $KEY -p 1234

Après les variables, la requête 🙂
Pour -vrlpEogth, je vous invite à faire un rsync --help. Globalement cela active le mode verbose, conserve les droits des fichiers, crée les liens symboliques (et ne récupère donc pas le fichier pour le transmettre).
-e ssh : Cela nous donne le driver de connexion auquel on peut ajouter des paramètres.
--rsync-path="sudo -i rsync" il s’agit de la requête rsync qui sera effectué sur le serveur distant lors de l’exécution. Par défaut, c’est juste rsync (et on peut donc ne pas mettre le paramètre), toutefois j’ai choisi de l’utiliser afin d’ajouter sudo -i qui me permet de passer en root, sans quoi je n’aurais pas les droits d’écriture nécessaire. En fonction des cas il vous faudra peut être l’adapter.

La suite c’est le coeur de la requêtes en tant que tel (dossier source, connection au serveur et dossier distant)

Je termine mon code par chown -R web1:client1 /var/www/mywebsite/web/* qui m’assure de rétablir les permissions correctement. Evidemment il vous faudra changer web1 et client1 par votre user et groupe.

Vous pouvez également ajouter l’attribut --exclude 'log' pour exclure certain dossier.
Ici j’exclus un fichier de log. Rsync ne gérant pas bien la modification de fichiers, cela ne ferait que créer des conflits. A noter que mon système ne fonctionne bien que parce que le serveur ne modifie pas de fichiers (sauf cas de log). Il n’y a que des créations de fichiers.

Ajout de la tâche CRON

crontab -e
et ajouter la ligne
* * * * * sh /root/scriptsh/rsync.sh 2>&1 > /dev/null

Ou, si vous êtes comme moi avec ISPConfig :
* * * * * sh /root/scriptsh/rsync.sh 2>&1 > /dev/null | while read line; do echo `/bin/date` "RSYNC $line" >> /var/log/ispconfig/cron.log; done
Ce qui affichera un message accessible dans l’admin d’ISPConfig.

Rien de bien particulier concernant les Cron, une simple recherche vous apprendra ce qu’il faut savoir si nécessaire

Bon amusement 🙂

Ps: Il y a évidemment des améliorations possible, l’une d’entre elle pourrait être de « locker » l’exécution pour éviter que deux instance de cron ne s’exécute en même temps et ne plante.

Update 7/11/15 ==> j’ai améliorer cette solution, lisez ici Synchroniser deux serveurs en temps réel avec inotify et rsync

Laisser un commentaire

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