ZFS for dummies – FreeBSD ZFS replication

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