远程增量ZFS备份。无处更容易

保护你的兄弟,安全...


ZFS 0.8能够发送加密数据的增量快照而无需解密。也就是说,拥有一个加密的阵列,您可以在远程计算机上组织其镜像副本,而不用信任远程场所的所有者。密钥和解密的数据不会离开受信任的前提。

如果发生火灾,例如星星,我的客户(微控制器)没有一个以上的服务器机房。在危险的管理业务中与您的同事达成协议后,您可以彼此相互保证,而不必担心他们会使用数据。

任何虚拟机形式的服务都安装在Proxmox上,数据位于ZFS上,您将始终有机会存储虚拟机的远程副本。有一天,您可能会变得沮丧而不是沮丧,而是去了一个偏僻的房间,拿起一块铁,并以良好的身体状态运行了所有服务。大约2年前,我已经将几乎所有服务转移到Proxmox,我不后悔,一切正常。在ZFS上,我有一个可供30个人使用的终端服务器,该服务器与瘦客户机相关联(即30个完整的作业)。除了当前副本,您还将在本地和远程获得最近x天的快照。

是的,您会因为使用zfs和加密而失去工作效率,但是对我自己而言,我得出的结论是,我已经准备为此功能支付此价格。

一汤匙焦油


在解决问题时,您会立即在药膏中飞翔。是的,ZFS较慢。实质上。但是您不能将其用作常规fs。它应在磁盘阵列中工作,欢迎增加磁盘数量,磁盘最好是SAS,控制器应在HBA模式下工作(而不是raid0作为单个磁盘),应该有ECC RAM,并且应该很多,必须有一个SSD(更好的PCI-E)作为用于读取第二级(较小,从64开始的演出)的高速缓存,而用于ZIL的一个SSD可能很小,但最好是MLC。

关于固态硬盘,我提出了这些建议,并购买了2个128的PCI-E SSD,每个硬盘分为16个演出和其余的演出。我在ZIL中启动了两个16 GB分区作为镜像,并在第二级缓存下将其余部分作为条带启动。在zfs的帮助下,演出了16场歌剧。(事实证明,使用ebay购买的一位母亲的一个插槽无法正常工作;如果有效,则可以使用32个插槽)

zfskeeper.sh


从脚本中,我需要自动通知问题,监视两端的捕捉次数和速度控制。在我掌握的剧本中,没有什么令我满意。下面,我将提供一些在执行此操作之前检查过的脚本。接收电子邮件通知,代替我的数据在你的send_error_to_mail()与你的功能

zfskeeper.sh帮助会告诉你使用的例子
zfskeeper.sh准备会告诉你的预备动作的程序(推荐)
zfskeeper.sh银行/加密/ subvol-100磁盘0 10将获取当前快照,并保留最后10个快照
zfskeeper.sh bank /加密/ subvol-100-disk-0 10 Remotehost 22 10m复制器bank / rtl / subvol-100-disk-0 20将未加密的数据发送到remotehost:22个用户复制器下的数据,速度高达10MB / s,并在源上保留10个图像,在远程主机上
保留 20个图像zfskeeper.sh bank / encrypted / subvol-100-disk-0 10 Remotehost 22 10m复制器bank / rtl / subvol -100-disk-0 20 -w是同一件事,但是数据将被加密

#!/bin/bash

zpool=$1
lsnaps=$2

ip=$3
port=$4
speedl=$5
remoteuser=$6
backpool=$7
rsnaps=$8
sendargs=$9

ZFSLOGDIR=~/zfskeeplogs
if [ ! -d "$ZFSLOGDIR" ]; then
    mkdir -p $ZFSLOGDIR
fi

NAMESNAP=`date "+%Y_%m_%d_%T"|sed s/:/_/g`
logfile=$ZFSLOGDIR/$NAMESNAP.log

write_to_log ()
{
echo `date +"%T"`" $1" >> $logfile
}

log_last_command ()
{
if [ $? -ne 0 ]; then
	    write_to_log "$1 FAILED."
	    if [ $2 = true ]; then
		write_to_log "Script execution stops"
		send_error_to_mail "$1" "$?" "$*"
		exit 1
	    fi
	else
	    write_to_log "$1 COMPLETED."
	fi
}

send_error_to_mail ()
{

Subject=`hostname`" ZFS backup $zpool missing"
swaks --header "Subject: $Subject" --to admin@mydomain.ru --from "alertbot@mydomain.ru" -a LOGIN -au alertbot@mydomain.ru -ap ailPass --server mail.mydomain.ru -tls --body \
"$Subject
command: zfskeeper.sh $3

    $1
    $2" \
    --attach $logfile
#    --attach-type "$(get_mimetype $logfile)" --attach $logfile

}

case "$#" in
    1)
    case "$1" in
	prepare)
    echo "
    Sender mashine:
    apt install swaks mbuffer
    useradd -s /bin/bash replicator
    mkdir -p /home/replicator 
    chown replicator:replicator /home/replicator
    zfs allow -u replicator send,snapshot,destroy,mount bank/encrypted
    su replicator
    ssh-keygen

    Receiver machine:
    ln -s /usr/sbin/zfs /usr/local/bin/zfs
    useradd -s /bin/bash replicator
    mkdir -p /home/replicator 
    chown replicator:replicator /home/replicator
    passwd replicator

    Sender mashine:
    ssh-copy-id -i .ssh/id_rsa.pub Remotehost
    zfs allow -u replicator compression,create,receive,destroy,mount bank/companyname

    "
    ;;
	*)
    echo "
    Usage:

    To show the prepare instrutions:
    zfskeeper.sh prepare

    localkeeping:
    keep last 10 snapshots of bank/encrypted/subvol-100-disk-0

    zfskeeper.sh bank/encrypted/subvol-100-disk-0 10

    remotekeeping:

    keep last 10 snapshots bank/encrypted/subvol-100-disk-0 and send it by ssh to Remotehost:22 bank/rtl/subvol-100-disk-0
    and keep last 20 copies by replicator user and limit transferspeed 10Mb/s

    zfskeeper.sh bank/encrypted/subvol-100-disk-0 10 Remotehost 22 10m replicator bank/rtl/subvol-100-disk-0 20

    If you need to send encrypted data, then you need add -w to the end of the line

    zfskeeper bank/encrypted/subvol-100-disk-0 10 Remotehost 22 10m replicator bank/rtl/subvol-100-disk-0 20 -w
    "
    ;;
    esac
    exit 0
    ;;
    2)
    echo `date +"%T"`" Local keeping of $NAMESNAP being started" > $logfile
    ;;
    8|9)
    echo `date +"%T"`" Remote keeping of $NAMESNAP being started" > $logfile
    ;;
    *)
    echo "illegal number of parameters" >&2
    exit 1
    ;;
esac



####################################### Local part #######################################################

# Remove waste local snaps
numsnap=`zfs list -H -o name -t snapshot -s creation|grep "${zpool}@"|wc|awk '{ print $1 }'`
let MAXSNAP=numsnap-lsnaps+1 >/dev/null
if [ $MAXSNAP -gt 0 ] ; then
    for d in `zfs list -H -o name -t snapshot -s creation| grep "${zpool}@"|/usr/bin/head -n"$MAXSNAP"`; do
        zfs destroy ${d}
        log_last_command "Remove local snapshot $d"
    done
fi

# Create fresh local snap
zfs snapshot $zpool@backup_$NAMESNAP
log_last_command "Create local $zpool@backup_$NAMESNAP" true

####################################### Local part #######################################################

if [ -z "$backpool" ]; then
    write_to_log "Local keeping is complete"
    exit 0
fi

####################################### Remote part #######################################################


# Check remote address
if [ -n "$ip" ]; then
    if ping -c 1 $ip > null ; then
            sship="ssh -c aes128-ctr -p"$port" -l"$remoteuser" "$ip
    else
            echo "URL $ip is not accesiible, abort"
            send_error_to_mail "Try to ping remote host" "URL $ip is not accesiible, abort" "$*"
            exit 1
    fi
else
    # Remote backup is unnecessary
    exit 0
fi


# Remove waste local snaps
numsnap=`$sship zfs list -H -o name -t snapshot -s creation|grep "${backpool}@"|wc|awk '{ print $1 }'`
let MAXSNAP=numsnap-rsnaps+1 >/dev/null
if [ $MAXSNAP -gt 0 ] ; then
    for d in `$sship zfs list -H -o name -t snapshot -s creation| grep "${backpool}@"|/usr/bin/head -n"$MAXSNAP"`; do
        $sship zfs destroy ${d}
        log_last_command "Remove local snapshot $d"
    done
fi

# Receive last remote snap
MOST_SLAVE_SNAP_NAME=`$sship zfs list -H -o name -t snapshot -s creation|grep "$backpool@backup"|tail -n1|awk -F "@" '{print $2}'`

# If localbackup has same snap then send incremental copy. If has't then send full
if [ -n "`zfs list -H -o name -t snapshot -s creation|grep -w "$zpool@$MOST_SLAVE_SNAP_NAME"`" ]; then
    #zfs send $sendargs -i $MOST_SLAVE_SNAP_NAME $zpool@backup_$NAMESNAP | pv -L $speedl | $sship zfs receive -vF $backpool@backup_$NAMESNAP &>> $logfile
    zfs send $sendargs -i $MOST_SLAVE_SNAP_NAME $zpool@backup_$NAMESNAP | mbuffer -q -v 0 -s 128k -m 1G | pv -L $speedl | $sship "mbuffer -q -v 0 -s 128k -m 1G | zfs receive -vF $backpool@backup_$NAMESNAP" &>> $logfile
    log_last_command "Sending incremental backup to the remote machine" true
else
    #If backpool exist we remove it. You can rename it
    if [ -n "`$sship zfs list -H -o name -s creation|grep -w "$backpool"`" ]; then
	#$sship zfs rename -p $backpool `$sship zfs list -H -o name|grep -w "$backpool"|awk -F "/" '{print $1}'`/old_$NAMESNAP
	$sship zfs destroy -r $backpool 2>> $logfile
	log_last_command "Need to destroy remotepool for full sending $backpool" true
    fi
    #zfs send $sendargs $zpool@backup_$NAMESNAP | pv -L $speedl | $sship zfs receive -vF $backpool &>> $logfile
    zfs send $sendargs $zpool@backup_$NAMESNAP | mbuffer -q -v 0 -s 128k -m 1G | pv -L $speedl | $sship "mbuffer -q -v 0 -s 128k -m 1G | zfs receive -vF $backpool" &>> $logfile

    log_last_command "Sending full backup to the remote machine" true
fi


####################################### Remote part #######################################################

write_to_log "Remote keeping is complete"
exit 0


zfskeepall.sh


为了保持几个部分的色调,您需要一个控制脚本。每个人都可以根据自己的口味和颜色来进行配置,具体取决于配置。我的测试看起来像这样:

#!/bin/bash
scriptpath=/home/replicator/zfskeeper.sh
$scriptpath bank/encrypted/subvol-100-disk-0 5 RemoteHost 22 30m replicator bank/rtl/subvol-100-disk-0 5 -w

现有解决方案


我首先找到它,然后根据它检查了该机制的整体可操作性。感谢作者,但是写作风格很脏,必须明确地重写。

zfs-auto-snapshot.sh仅仅是一个块。

zfsbackup.sh值得一看,它漂亮,整洁但又笨重,功能低下-也是一个整洁但功能低下的

PS我从第三次咬住zfs以来,每次咬了约一个月。我无法让她迅速工作,而最大程度地失败了。通常,安装SAS磁盘(至少7200,至少NL)后,情况发生了变化。

大家平安!感谢您的阅读!

All Articles