Exemple de réplication d’une jail en ZFS sur FreeBSD
L’environnement d’exemple est celui ou j’ai divers web, blog, photos, etc., mais le même principe de réplication est utilisé à grande échelle pour un plan de continuité d’activité (PCA) entre des serveurs sur deux centre de données différent avec des périodes de réplication adaptée aux besoins.
pour mon exemple, /etc/crontab
# chaque jour juste l’incrémental 45 4 * * * root (echo "Subject: ZFS replicate zsync_web incremental " && ( (/usr/bin/time -h /backup/zsync_web incremental) 2>&1 ) ) | sendmail -f FROM@DOMAIN TO@DOMAIN # le 22 du mois, un full 10 4 22 * * root (echo "Subject: ZFS replicate zsync_web full " && ( (/usr/bin/time -h /backup/zsync_web full) 2>&1 ) ) | sendmail -f FROM@DOMAIN TO@DOMAIN
Je passe sur l’échange de clef SSH entre le host source et celui de destination pour faire la réplication via ssh, et j’utilise aussi shlock.
# pkg info | grep shlock
shlock-2.6.3 Create lock files for use in shell scripts
Le principe ZFS, un bookmark et des snapshot, du zfs send et receive entre deux serveurs.
La syntaxe:
/backup/zsync_web full|incremental|list|show
# /backup/zsync_web list
snapshot jails/web :
jails/web@L1_5 13.2M – 92.4G –
jails/web@L1_6 12.5M – 92.4G –
jails/web@L1_7 18.4M – 92.4G –
jails/web@L1_1 7.01M – 92.4G –
jails/web@L1_2 17.1M – 92.4G –
jails/web@L1_3 5.66M – 92.4G –
jails/web@L1_4 2.16M – 92.4G –
bookmark jails/web :
jails/web#L0_1_bookmark – – – –
Le script au complet:
# zsync / ZFS incremental backup réplication
# FreeBSD 12 - 2021-01 jcmichot _@_ free.org
# replicate/synchronize zfs file system on remote host
DAYWEEK=`date "+%u"`
# /!\ CHANGE "HOSTNAME" /!\ by your replication target hostname
MYTARGET="HOSTNAME"
# /!\ CHANGE "jail/web"/!\ by your source jail to replicate
MYFS="jails/web"
LOCK="/var/tmp/zsync_web.lock"
IGNORE=nozsync
CMD=$1
trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15
if shlock -p $$ -f ${LOCK} ; then
case $CMD in
full)
# dump 0 - full backup day
# LOCAL: remove all MYFS zsync snapshots and bookmark
zfs list -t snapshot | grep -e "$MYFS@L1_" -e "$MYFS@L0_" | awk '{ printf("zfs destroy %s\n", $1 ); }' | sh
zfs list -t bookmark | grep "$MYFS#L0_" | awk '{ printf("zfs destroy %s\n", $1 ); }' | sh
# REMOTE (TARGET), remove all MYFS zsync snapshots
REMOTESNAPS=`ssh root@$MYTARGET zfs list -H -t snapshot -o name | grep $MYFS@`
PROCED="$IGNORE $REMOTESNAPS"
for p in $PROCED
do
case $p in
$IGNORE)
;;
*)
ssh root@$MYTARGET zfs destroy $p
;;
esac
done
zfs snapshot $MYFS@L0_1
zfs bookmark $MYFS@L0_1 $MYFS#L0_1_bookmark
zfs send -cvV $MYFS@L0_1 | ssh root@$MYTARGET zfs receive -F $MYFS@L0_1
zfs destroy $MYFS@L0_1
for i in 1 2 3 4 5 6 7
do
zfs snapshot $MYFS@L1_$i
done
;;
incremental)
zfs destroy $MYFS@L1_$DAYWEEK
zfs snapshot $MYFS@L1_$DAYWEEK
# REMOTE (TARGET), remove the DAYWEEK INCREMENTAL snapshot
REMOTESNAPS=`ssh root@$MYTARGET zfs list -H -t snapshot -o name | grep $MYFS@L1_$DAYWEEK`
PROCED="$IGNORE $REMOTESNAPS"
for p in $PROCED
do
case $p in
$IGNORE)
;;
*)
ssh root@$MYTARGET zfs destroy $p
;;
esac
done
zfs send -cvV -i $MYFS'#L0_1_bookmark' $MYFS@L1_$DAYWEEK | ssh root@$MYTARGET zfs receive -F $MYFS@L1_$DAYWEEK
;;
list)
echo "snapshot $MYFS :";
zfs list -t snapshot | grep -e $MYFS@L1_ -e $MYFS@L0_
echo "bookmark $MYFS :";
zfs list -t bookmark | grep -e $MYFS#
;;
show)
echo "no zsync running";
;;
*)
echo "unknown command"
echo "$0 full|incremental|list|show";
;;
esac
rm -f ${LOCK}
else
case $CMD in
show)
SPID=`cat ${LOCK}`
top -ap $SPID
;;
*)
echo "zsync locked by `cat ${LOCK}`"
;;
esac
exit 0;
fi
