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