It has been a while, busy building clouds and stuff. In the Christmas spirit of sharing, today I wanted to share this bash script for ZFS backups, it will basically snapshot the ZFS share, RSYNC new files over and the delete the old ZFS snaps.
Simple, yes, but somehow a wheel that keeps being reinvented over and over again, so here’s my version of it. Hope it helps someone save some time.
For this script, the backup server is one of our own TerraNas servers (basically, Ubuntu 14 with Native ZFS and NFS/4) the client is a Ubuntu14 LTS server, the SSH keys have been imported to the client so we can SSH across without passwords and such.
On the ZFS/NFS server side, we disable ID mapping to have usernames cross the wire instead of ID’s
echo N > /sys/module/nfs/parameters/nfs4_disable_idmapping
share the ZFS drive with:
zfs set email@example.com/24,insecure,no_root_squash pool1/backup
Where 192.168.33.0/24 is your subnet or host of course.
Then we share it our with
zfs share -a and service nfs-kernel-server restart.
We do have one export to the localhost in the /etc/exports file, because NFS will complain if this file is empty, but the rest of the exports come from ZFS
On the client we have this little script:
Make note of the additions of MOUNT and UMOUNT to the sudoers file, to enable a user to mount NFS shares.
# User home ZFS Backup Script 2.0
# Needs SSH token access to ZFS Server and NFS Mount Points
# ZFS/NFS exports on ZFS server under zfs/backup/*
# add Cmnd_Alias MOUNT=/bin/mount,/bin/umount to the ALIAS section in /etc/sudoers using visudo
# add ALL ALL=NOPASSWD: MOUNT to the END of the /etc/sudoers using visudo
# Create or mount the ZFS folder
echo ZFS Backup from $BACKUPSOURCE to $BACKUPDEST started..
if ! [ -d $BACKUPSOURCE/zfs ]; then mkdir $BACKUPSOURCE/zfs; fi
if ! mountpoint -q $BACKUPSOURCE/zfs; then if ! (sudo mount $ZFSSERVER:$ZFSMOUNT $BACKUPSOURCE/zfs); then echo "Mount of $BACKUPSOURCE/ZFS failed"; exit 1; fi;fi
# Add attempt to backup list and syslog
echo $NOW,$HOME/zfs/$HOSTNAME-$USER-$NOW.log >> $HOME/zfs/backup-$HOSTNAME-$USER-dates.lst
# Create ZFS folder or snapshot
if [ -d $BACKUPDEST ]; then
ssh root@$ZFSSERVER 'zfs snapshot '$ZFSPOOL'/'$HOSTNAME'@'$USER-$NOW
ssh root@$ZFSSERVER 'zfs create '$ZFSPOOL'/'$HOSTNAME
# Remove the older snaps (see RETENTION varaible)
ssh root@$ZFSSERVER 'zfs list -rt snap -H -S creation -o name |grep '$USER' |tail -n '$RETENTION' |xargs -n 1 zfs destroy -r'
# Do the Magic
rsync -av -P $BACKUPSOURCE $BACKUPDEST --stats --human-readable --delete-before --log-file=$HOME/zfs/$HOSTNAME-$USER-$NOW.log --exclude-from=$BACKUPSOURCE/exclude.lst
# Clean it up
sudo umount $BACKUPSOURCE/zfs