On my server i have several Linux Vservers running. This works really well, but i am missing some sort of fail-over. I have read articles about drdb8 and active-passive setups, but I don’t want something to complicated. To solve my problem, I have written a small script to rsync a vserver remotely. The script will be executed from the remote server and uses SSH, rsync and vserver-build to do the work. This will not provide any fail-over, but will give you a copy of the vserver in case the real server crashes. You will have to start the vserver manually and the data will be old (from when the script was executed). I have developed and tested the script on Debian GNU/Linux 5.0 (Lenny). It should work on other Linux distributions, but you may have to change some paths.
#!/bin/sh
# Small script to copy a linux vserver from remote host to local host by using
# ssh, rsync and vserver-build. To avoid typing password, you can generate ssh keys
# without passphrase and append public key to the remote .ssh/authorized_keys file.
# If you specify the third parameter, true, the vserver will be started on this host
# after copying is done. Otherwise it will be started on the remote host again.
# Check parameters
if [ $# -lt 2 ]; then
echo "Usage: $0 [source] [vhost] "
echo "Example: $0 root@primary-server vhost1"
exit 1
fi
# Set values
SOURCE=${1:-"root@primary-server"}
VHOST=${2:-"vhost1"}
MIGRATE=${3:-"false"}
LOGFILE="/tmp/rsync-vhost_$$.log"
# Warning
echo "WARNING: this script will delete the LOCAL vserver ${VHOST} before copy/move"
echo "Press CTRL-C to abort !!!"
sleep 5
# Get context and network
CONTEXT=$(ssh -q -n $SOURCE cat /etc/vservers/${VHOST}/context)
NET_DEV=$(ssh -q -n $SOURCE cat /etc/vservers/${VHOST}/interfaces/0/dev)
NET_IP=$(ssh -q -n $SOURCE cat /etc/vservers/${VHOST}/interfaces/0/ip)
NET_PREFIX=$(ssh -q -n $SOURCE cat /etc/vservers/${VHOST}/interfaces/0/prefix)
NETWORK="${NET_DEV}:${NET_IP}/${NET_PREFIX}"
# Write to logfile
echo "Source: $SOURCE, Vserver: $VHOST, Migrate: $MIGRATE, Context: $CONTEXT, Network: $NETWORK" | tee $LOGFILE
# Make sure vserver is NOT running on local host
vserver $VHOST running >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Vserver $VHOST is already running on LOCAL host, aborting."
exit 1
fi
# Make sure vserver is running on remote host
ssh $SOURCE "vserver $VHOST running" >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Vserver $VHOST is NOT running on REMOTE host, aborting."
exit 1
fi
# Delete vserver on local host
echo "Deleting LOCAL copy of $VHOST"
echo 'y' | vserver $VHOST delete >/dev/null 2>&1
# Stop vserver on remote host
echo "Stopping REMOTE vserver ($VHOST on $SOURCE)"
ssh -q -n $SOURCE "vserver $VHOST stop" >>$LOGFILE 2>&1
# Build copy of vserver
echo "Building LOCAL copy of REMOTE vserver ($VHOST on $SOURCE)"
RSYNC_RSH=ssh
vserver ${VHOST} build -m rsync --context ${CONTEXT} \
--hostname ${VHOST}.nellemann.biz \
--interface ${NETWORK} \
-- --source ${SOURCE}:/vservers/${VHOST}
# Start vserver on remote host - or local host if migrating
if [ x"$MIGRATE" == x"true" ]; then
echo "Migrating $VHOST to LOCAL server"
echo "vserver $VHOST start"
else
echo "Starting REMOTE vserver ($VHOST on $SOURCE)"
ssh -q -n $SOURCE "vserver $VHOST start" >>$LOGFILE 2>&1
fi
echo "done."
exit 0