Blog

Installation et configuration de lsyncd sur Debian

Écrit le 15 12 2016 par Kévin MET _

Fonctionnement

Avant de se lancer dans l'installation, un peu de théorie, histoire de savoir pourquoi il est plus intéressant d'utiliser lsyncd plutôt qu'un simple script rsync en cron. Le gros avantage de lsyncd est qu'il va utiliser inotify ou fsevevents pour monitorer les dossiers à l'intérieur de votre dossier source. Cela permet de lancer un rsync uniquement lorsqu'un changement est détecté. De plus, il va lancer un rsync uniquement sur le ou les fichiers qui ont été modifiés ce qui économise pas mal d'I/O, surtout lorsqu'on veut synchroniser des dossiers très lourd et qu'on a des disques en cartons 😉

Attention, ça ne remplace pas un FS distribué ou un DRBD qui seront bien plus gourmand en I/O mais qui, en contre-partie, offriront l'assurance de dossiers synchronisés en temps réel. En effet, lsyncd va générer une latence entre la synchronisation des dossiers qui va être plus ou moins longue (ce paramètre est réglable) et qui par défaut est de 15 secondes. Ce type de setup peut donc très bien être utiliser pour du failover par exemple mais ne se prêtera surement pas à du load-balancing ou du HA. Ceci est à définir en fonction de l'applicatif qui tourne derrière et de la criticité de celui-ci...

Installation & Configuration

Alors comme d'habitude, je suis sous Debian donc je ne parlerai que de Debian dans ce tutoriel mais pour les autres, cela vous permettra de vous familiariser avec les options de configurations. Pour l'installation, on part sur un bon vieux apt-get des familles :


root@web2:~# apt-get install lsyncd

On va ensuite directement attaquer avec la création des dossiers nécéssaires à la configuration et aux logs :


root@web2:~# mkdir /etc/lsyncd
root@web2:~# mkdir /var/log/lsyncd/

Je vais commencer par vous montrer un fichier de conf basique et je vous explique les options en dessous :


root@web2:~# cat /etc/lsyncd/lsyncd.conf.lua
settings {
	logfile = "/var/log/lsyncd/lsyncd.log",
	statusFile = "/var/log/lsyncd/lsyncd-status.log",
	statusInterval = 1
}

sync {
	default.rsyncssh,
	source="/home/mnttech/www",
	host="web3.mnt-tech.fr",
	targetdir="/home/mnttech/www",
	delay = 1,
	rsync = {
		archive = true,
		compress = true,
		whole_file = false
	},
	ssh = {
		port = 22
	}
}

Vous l'aurez compris, le fichier de configuration par défaut sur Debian est /etc/lsyncd/lsyncd.conf.lua (il est définit dans le script d'init). Le premier bloc settings permet de définir les paramètres généraux qui seront donc appliqués à tous les dossiers synchronisés et les blocs sync permettent de définir les dossiers synchronisés (vous pouvez en ajouter autant que vous le désirez).

Dans la partie settings, je n'utilise que 3 options car les autres ne me semblent pas forcément utiles mais vous pouvez voir la liste complète sur cette page.

  • logfile : permet de définir le fichier de log
  • statusFile : ce fichier décrit les dossiers qui sont monitorés par lsyncd
  • statusInterval : permet de définir le nombre de secondes avant que le fichier status soit mis à jour

A noter que l'option inotifyMode permet de choisir le type de changement à écouter via inotify ("Modify", "CloseWrite" ou "CloseWrite or Modify"). Par défaut, il s'agit de CloseWrite.

Dans la partie sync, je n'utilise également que peu d'options car les options par défaut correspondent bien à ma situation. Il serait d'ailleurs temps que j'explique à quoi me sert lsyncd, vu qu'on arrive à la moitié du tuto... Je l'utilise pour synchroniser des DocumentRoot d'un serveur vers un autre serveur. En cas de défaillance de ce serveur, je peux donc rapidement basculer vers le deuxième serveur qui est déjà configuré et qui contient donc toutes les données à jour. Dans mon exemple, il s'agit d'ailleurs du DocumentRoot du site sur lequel vous êtes actuellement que je réplique vers un serveur qui répond au doux nom de web3.mnt-tech.fr.

  • default.rsyncssh : on définit les paramètres par défaut de rsync via ssh
  • source : le dossier source
  • host : la machine distante sur laquelle se trouve le dossier de destination
  • targetdir : c'est bon, t'as compris, t'es pas con
  • delay : cela définit un délai avant de spawn un process rsync

Le paramètre le plus important est delay qui va définir par défaut le nombre de secondes avant de spawner un process rsync. Dans mon cas, j'ai mis une seconde car je sais que les modifications sont assez peu fréquentes sur ce site (il n'y a qu'à voir la fréquence de mise à jour de ce blog pour s'en rendre compte 😉 ) mais dans le cas d'un dossier avec beaucoup de modifications par secondes, il est sûrement plus intéressant de monter ce délai qui par défaut est à 15 secondes. Si en l'espace de delay secondes il y a eu 1000 modifications, un process rsync sera de toute façon lancé par lsyncd.

On peut ensuite modifier les options de rsync via le bloc rsync et je vous invite à aller voir la liste complètes des options sur cette page. Sur la même page on trouve les options de default.rsyncssh permettant par exemple de modifier le port ou la clé SSH. A noter que par défaut l'option --delete est utilisée et que l'option --whole-file est désactivée. J'ai donc préféré activer cette option qui permet de tirer partie de l'algorithme de rsync pour n'envoyer qu'une partie d'un fichier si celui-ci n'a été modifié que partiellement.

Il faut ensuite ajouter la clé publique de root sur le serveur distant avec ssh-copy-id par exemple et il ne reste plus qu'à lancer le service via systemctl :


root@web2:~# systemctl start lsyncd.service

Si vous souhaitez ajouter des dossiers synchronisés, il suffit d'ajouter des blocs sync dans votre fichier de configuration et de relancer lsyncd. Pour le moment lsyncd marche à merveille mais je n'ai fait que quelques tests sur des dossiers ne contenant pas énormément de fichiers. Je reviendrai éditer cet article quand ce sera le cas pour vous dire ce qu'il en est. Une dernière petite astuce avant de cloturer cet article, lorsque lsyncd ne se lance pas via systemd ou le script d'init, vous pouvez le lancer directement à la main pour voir ou se situe votre erreur. Un exemple avec un fichier de configuration mal édité :


root@web2:~# lsyncd /etc/lsyncd/lsyncd.conf.lua 
Error: error loading /etc/lsyncd/lsyncd.conf.lua: /etc/lsyncd/lsyncd.conf.lua:5: '}' expected (to close '{' at line 1) near 'plop'

UPDATE DU 22/12/2016

J'ai rapidement rencontré des problèmes d'instabilité suite à l'utilisation de la commande mv dans des dossiers synchronisés. Il suffisait de relancer lsyncd pour corriger le problème. Voici un extrait de log :


Fri Dec 16 00:57:51 2016 Normal: Moving /www/crons/ -> /crons/
Fri Dec 16 00:57:51 2016 Error: in Lua: default-rsyncssh.lua:92: attempt to call local 'path2' (a string value)
Fri Dec 16 00:57:51 2016 Error: Backtrace 1 :default-rsyncssh.lua:92
Fri Dec 16 00:57:51 2016 Error: Backtrace 2 :lsyncd.lua:1960
Fri Dec 16 00:57:51 2016 Error: Backtrace 3 :lsyncd.lua:3511

Après une rapide recherche on tombe sur le bug Debian qui indique que le patch est appliqué sur la version 2.1.6-1 qui est encore dans le dépôt instable. Comme je n'avais pas envie de faire du pinning je me suis dit que j'allais testé la fonctionnalité incluse dans systemd qui permet de relancer un service quand il est killé. Cette méthode, bien qu'un peu moche, fonctionne bien et cela permet de rester sur les dépôts de Debian stable. Voici le contenu de mon script d'init systemd :


[Unit]
Description=Live Syncing (Mirror) Daemon
After=network.target

[Service]
Restart=always
Type=forking
Nice=19
ExecStart=/usr/bin/lsyncd -pidfile /run/lsyncd.pid /etc/lsyncd/lsyncd.conf.lua
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/run/lsyncd.pid

[Install]
WantedBy=multi-user.target

Il faut le mettre dans /etc/systemd/system/lsyncd.service et lancer un systemctl daemon-reload puis un systemctl enable lsyncd.service et on finit par lancer lsyncd via ce script systemd en faisant systemctl restart lsyncd.service. Depuis que j'ai appliqué ce petit "patch" correctif je n'ai plus rencontré aucun problème car même après un crash le démon se relance tout seul est les fichiers sont bien synchronisés.

♥ Partage sur tes réseaux sociaux ♥
Kévin MET
Kévin MET

Auteur de ce blog et gérant de la société MNT-TECH, je publie sur ce blog lorsque le temps me le permet et lorsqu'un sujet qui me parait intéressant n'a pas encore été abordé en français. Toutes les informations techniques présentes sur cette page peuvent être réutilisées moyennant le fait de citer la source.