Lsyncd installation and configuration

Overview

This article describes how to use lsyncd as a sync’ing mechanism for multiple web servers data directories. This is only one scenario in which this program could be very useful for our customers.
These notes will provide instructions on how to setup lsyncd to sync the web directory on one server to two other web servers. This guide was setup on our default CentOS 5.5 LAMP build servers, but should work with a few modifications on Ubuntu.

Replicate from master to two slaves:
Master —> slave1
—> slave2
Preparation

Lsyncd requires passwordless SSH from the master to slave systems for the root user.

Generate SSH keypair on master:

# ssh-keygen -t rsa

Then copy /root/.ssh/id_rsa.pub on master to /root/.ssh/authorized_keys on the slave servers.

Then ensure the following lines are uncommented in /etc/ssh/sshd_config on the slave servers:

PermitRootLogin yes
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

If you have to create the /root/.ssh directory on the slave, it should be owned root:root and have permissions 0700.

Restart SSH after changes are made.

Test ssh from the master to the slave as root to make sure it isn’t throwing a message that prevents lsyncd from being able to connect

On Ubuntu, you may see %h/.ssh/authorized_keys. This is fine as well, the %h is just an alias for the home directory of the user logging in, i.e. /root/ for root.

Supporting Package Installation

First you need to ensure the following packages are installed, that are not within the default LAMP build
Dependencies

CentOS and RHEL

# yum -y install lua lua-devel pkgconfig gcc asciidoc

Ubuntu

# apt-get install -y lua5.1 liblua5.1-dev pkg-config rsync asciidoc

Lsync installation
Be sure to manually check the destination directory on the slave server if it already exists. Customers might have NFS or CloudFuse mounts which would end up wiped by the lsync process.

1. Then grab the source tarball from http://code.google.com/p/lsyncd/, and run the standard (on CentOS/RHEL, you can bypass this step and do ‘yum install lsyncd’ to install 2.1.4 from IUS)

tar xzvf lsyncd-2.1.5.tar.gz
cd lsyncd-2.1.5
./configure && make && make install

2. Create the Lsyncd log directory.

mkdir /var/log/lsyncd

3. Add init scripts for starting and stopping the service.
RHEL/CentOS

Create the following file at /etc/init.d/lsyncd: (skip if you did ‘yum install lsyncd’ above)

#!/bin/bash
#
# lsyncd: Starts the lsync Daemon
#
# chkconfig: 345 99 90
# description: Lsyncd uses rsync to synchronize local directories with a remote
# machine running rsyncd. Lsyncd watches multiple directories
# trees through inotify. The first step after adding the watches
# is to, rsync all directories with the remote host, and then sync
# single file buy collecting the inotify events.
# processname: lsyncd

. /etc/rc.d/init.d/functions

config=”/etc/lsyncd.lua”
lsyncd=”/usr/local/bin/lsyncd”
lockfile=”/var/lock/subsys/lsyncd”
pidfile=”/var/run/lsyncd.pid”
prog=”lsyncd”
RETVAL=0

start() {
if [ -f $lockfile ]; then
echo -n $”$prog is already running: ”
echo
else
echo -n $”Starting $prog: ”
daemon $lsyncd -pidfile $pidfile $config
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch $lockfile
return $RETVAL
fi
}

stop() {
echo -n $”Stopping $prog: ”
killproc $lsyncd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f $lockfile
return $RETVAL
}

case “$1” in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status $lsyncd
;;
*)
echo “Usage: lsyncd {start|stop|restart|status}”
exit 1
esac

exit $?

Configure Lsyncd to start at boot:

chkconfig –add lsyncd
chkconfig lsyncd on

Ubuntu

Create the following file at /etc/init/lsyncd.conf

description “lsyncd file syncronizer”

start on (starting network-interface
or starting network-manager
or starting networking)

stop on runlevel [!2345]

expect fork

respawn
respawn limit 10 5

exec /usr/local/bin/lsyncd -pidfile /var/run/lsyncd.pid /etc/lsyncd.lua

Then create a symlink to preserve functionality when called as an old style init script

ln -s /lib/init/upstart-job /etc/init.d/lsyncd

If you want to disable lsyncd from starting automatically at bootup (I.E. customer scaled down to one server), you can create a file at /etc/init/lsyncd.override

manual

Log rotation

Add this file at /etc/logrotate.d/lsyncd:

/var/log/lsyncd/*log {
missingok
notifempty
sharedscripts
postrotate
if [ -f /var/lock/lsyncd ]; then
/sbin/service lsyncd restart > /dev/null 2>/dev/null || true
fi
endscript
}

You can test this using the command

logrotate -d /etc/logrotate.d/lsyncd

Finally, for both distributions, set permissions and ownership on init.d file appropriately:

**NOTE** Don’t do this if you used the Upstart-Job method above for Ubuntu. As it is a symlink, this step is unnecessary.

# chmod 775 /etc/init.d/lsyncd
# chown root:root /etc/init.d/lsyncd

Configuration

Lsyncd configuration file examples. /etc/lsyncd.lua
Legacy: 2.0.X

Here is an example of a master, single slave configuration file (10.x.x.x is the private IP of the slave server) for 2.0.x

settings = {
logfile = “/var/log/lsyncd/lsyncd.log”,
statusFile = “/var/log/lsyncd/lsyncd-status.log”,
statusInterval = 20

}

sync{
default.rsyncssh,
source=”/var/www/html”,
host=”10.x.x.x”,
targetdir=”/var/www/html”,
rsyncOpts=”-avz”

}

Here is a more advanced example, which uses some Lua magic to make adding new servers easier. In this configuration, there are two slave servers, and new slaves can be added by including them in the “servers” block below. Also note that StrictHostKeyChecking is explicitly set to no, so you shouldn’t need to SSH to each server individually to accept the host key after adding them to your configuration.

settings = {
logfile = “/var/log/lsyncd/lsyncd.log”,
statusFile = “/var/log/lsyncd/lsyncd-status.log”,
statusInterval = 20
}

servers = {
“web02”,
“web03″
}

for _, server in ipairs(servers) do
sync {
default.rsync,
source=”/var/www/vhosts/”,
target=server..”:/var/www/vhosts/”,
rsyncOpts={“-e”, “/usr/bin/ssh -o StrictHostKeyChecking=no”, “-avz”}
}
end

Current: 2.1.X

Starting with 2.1.0 the configuration has become less stable. In 2.1.0, the last setting is ‘rsyncOps’ instead of ‘rsyncOpts’ (note the missing ‘t’).

With 2.1.1 the syntax change entirely.

Here is a 2.1.1 example with two hosts. Note that StrictHostKeyChecking is explicitly set to no, so you shouldn’t need to SSH to each server individually to accept the host key after adding them to your configuration.

If you installed via yum, the config file is /etc/lsyncd.conf instead of /etc/lsyncd.lua

settings {
logfile = “/var/log/lsyncd/lsyncd.log”,
statusFile = “/var/log/lsyncd/lsyncd-status.log”,
statusInterval = 20
}

sync {
default.rsync,
source=”/var/www/”,
target=”10.x.x.x:/var/www/”,
rsync = {
compress = true,
archive = true,
verbose = true,
rsh = “/usr/bin/ssh -p 22 -o StrictHostKeyChecking=no”
}
}

sync {
default.rsync,
source=”/var/www/”,
target=”10.X.X.X:/var/www/”,
rsync = {
compress = true,
archive = true,
verbose = true,
rsh = “/usr/bin/ssh -p 22 -o StrictHostKeyChecking=no”
}
}

2.0.4

Lsyncd version 2.0.4 has a known issue with permissions, see the following bug reports. Always make sure you install either 2.0.7 (stable) or 2.1.4+ (latest)

https://gist.github.com/axkibe/lsyncd/issues/94

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639148

2.1.2

Version 2.1.2 has a bug in it that it will not use your server specified in the target, nor can you specify a host due to an issue with the way it’s passing parameters. This is filed in this issue:

https://github.com/axkibe/lsyncd/issues/168

You can work around this by using

rsh = “/usr/bin/ssh -p 22 -o StrictHostKeyChecking=no”

until the fix goes into production.

2.1.4

On RedHat distros, the init script in lsync 2.1.4 may contain a bug to where the service will fail to start and you will be presented with “USAGE:” instructions. If this is the case, edit /etc/sysconfig/lsyncd and add the following line:

LSYNCD_OPTIONS=”-pidfile /var/run/lsyncd.pid /etc/lsyncd.conf”

Alternatively, you can modify the following line under the start() function in /etc/init.d/lsyncd:

daemon /usr/bin/lsyncd $LSYNCD_OPTIONS

Change this line to the following:

daemon /usr/bin/lsyncd -pidfile /var/run/lsyncd.pid /etc/lsyncd.conf

Exclusions

If you want to exclude a directory, use an exclude file and the excludeFrom directive as seen below.

The excludeFrom feature is not working in 2.1.1 (see https://github.com/axkibe/lsyncd/issues/164). The “exclude” function still lets you list every file you want to exclude, but trying to read the file from a list with excludeFrom will give an error on reastarting Lsyncd saying that excludeFrom is not a valid variable. (This bug has been fixed. You can now use exclude from as you normally would.)

Note that the paths to the files are relative from the source directive:

/etc/lsyncd-excludes.txt:

cache/
uploads/
dontcopymebro/

/etc/lsyncd.lua (this is a 2.0.x example, but the syntax of excludeFrom does not change between versions)

settings = {
logfile = “/var/log/lsyncd/lsyncd.log”,
statusFile = “/var/log/lsyncd/lsyncd-status.log”,
statusInterval = 20

}

sync{
default.rsyncssh,
source=”/var/www/html”,
host=”10.x.x.x”,
targetdir=”/var/www/html”,
excludeFrom=”/etc/lsyncd-excludes.txt”,
rsyncOpts=”-avz”
}

CAUTION! When using excludeFrom and a file, make sure the file has no empty lines in it. If it does, lsyncd treats this as “exclude /” and then everything gets excluded.
Delay considerations

Sync/propagation delay is generally significantly more noticeable on busy sites. The default delay (15 seconds) can be overridden in a couple of ways:

Added as an option to lsyncd process (at start) via the inclusion of ‘-delay SECONDS’
Fine grained control per sync block in the format of ‘delay=SECONDS’

An example of managing/overriding sync delay (2.0.x syntax)

sync{
default.rsyncssh,
source=”/var/www/html”,
host=”10.x.x.x”,
targetdir=”/var/www/html”,
delay=5,
rsyncOpts=”-avz”
}

The listed approach is likely to address sync times however bear in mind that it will lead to significantly more rsync (SSH) connections to the remote hosts in the ‘cluster’. A decent delay value should deal with unavailable resources on busy/volatile sites (to some extent at least – until we settle on an alternative).

So that’s about it. You should then be able to start it up at using ‘service lsyncd start’ and monitor the log file /var/log/lsyncd/lsyncd.log for any specific problems
Lsync Gotchas

There is a kernel parameter fs.inotify.max_user_watches which limits the number of directories which can be monitored by inotify. By default, it is set to 8192, but if the customer has a lot of directories, this will likely need to be increased. The Lsyncd log will typically notify you when this limitation is reached.

To increase the max_user_watches, use the following sysctl command:

sysctl -w fs.inotify.max_user_watches=16384 >> /etc/sysctl.conf
sysctl -p

To determine the number that this parameter should be set to, count the number of directories (including subdirectories) that will be monitored by lsync and multiply that by 2 or 3 to accommodate growth. You can can execute the following command:

find /var/www/vhosts/ -type d | wc -l | awk ‘{print $1″ directories needs monitoring, set [ fs.inotify.max_user_watches = ” $1*3″ ]”}’
Sample output:
33577 directories needs monitoring, set [ fs.inotify.max_user_watches = 100731 ]

If combining Lsyncd with NFS, be sure to read Lsyncd + NFS Solutions

About vicki

Welcome to the Sovereign Republic of Vickistan. I am the President here. Lucky me! No taxes or laws yet. Lucky you!
This entry was posted in Linux. Bookmark the permalink.