Copias de seguridad incrementales remotas de ZFS. En ninguna parte más fácil

Asegura a tu hermano, seguro ...


ZFS 0.8 tiene la capacidad de enviar instantáneas incrementales de datos cifrados sin descifrar. Es decir, al tener una matriz encriptada, puede organizar una copia espejo de ella en una máquina remota, sin confiar en el propietario de las instalaciones remotas. La clave y los datos descifrados no salen de las instalaciones de confianza.

Ninguno de mis clientes (microcontroladores) tiene más de una sala de servidores, si se produce un incendio, por ejemplo, una estrella. Habiendo acordado con su colega en un negocio administrativo peligroso, pueden asegurarse mutuamente sin temor a que puedan usar los datos.

Cualquier servicio en forma de máquina virtual se instala en Proxmox, donde los datos se encuentran en ZFS, y siempre tendrá la oportunidad de almacenar una copia remota de la máquina virtual. Existe la posibilidad de que un día, en lugar de caer en el desánimo, vaya a una habitación remota, recoja un pedazo de hierro y ejecute todos los servicios con buena salud. Ya transferí casi todos mis servicios a Proxmox hace aproximadamente 2 años y no me arrepiento, todo funciona bien. En ZFS, tengo un servidor de terminal para 30 personas, que está vinculado a clientes ligeros (es decir, 30 trabajos completos). Además de la copia actual, también tendrá instantáneas de los últimos x días, tanto local como remotamente.

Sí, perderá productividad por el uso mismo de zfs y por el cifrado, pero por mí mismo llegué a la conclusión de que estaba listo para pagar este precio por dicha funcionalidad.

Una cucharada de alquitrán


En taclear vuelas inmediatamente en la pomada. Sí, ZFS es más lento. Esencialmente. Pero no puedes usarlo como un fs regular. Debería funcionar en una variedad de discos, donde un aumento en el número de discos es bienvenido, los discos deben ser preferiblemente SAS, el controlador debe funcionar en modo HBA (y no raid0 como discos individuales), debe haber RAM ECC y debe haber muchos, debe haber uno SSD (mejor PCI-E) como caché para leer el segundo nivel (pequeño, conciertos desde 64) y un SSD para ZIL puede ser muy pequeño, pero preferiblemente MLC.

Con respecto al SSD, puse estas recomendaciones y compré 2 SSD PCI-E de 128 y cada uno dividido en 16 conciertos y el resto. Lancé dos particiones de 16 gigabytes en ZIL como un espejo y lancé las partes restantes bajo el caché de segundo nivel como una banda. A merced de zfs dio 16 conciertos de ópera. (Una ranura en una madre comprada con eBay resultó inoperante; si funcionara, daría 32)

zfskeeper.sh


De la secuencia de comandos necesitaba una notificación automática de problemas, monitoreando el número de instantáneas en ambos extremos y control de velocidad. De los guiones que cayeron en mis manos, no hubo guiones que me satisficieran. A continuación daré algunos de los scripts que revisé antes de hacer esto. Para recibir notificaciones por correo electrónico, reemplace mis datos en la función send_error_to_mail () con la suya.

Zfskeeper.sh le mostrará ejemplos de uso
zfskeeper.sh prepare le indicará el procedimiento para las acciones preparatorias (recomendado)
zfskeeper.sh bank / encrypted / subvol-100-disk-0 10 tomará la instantánea actual y dejará las últimas 10 instantáneas
zfskeeper.sh bank / encrypted / subvol-100-disk-0 10 Remotehost 22 10m replicator bank / rtl / subvol-100-disk-0 20Envíe datos sin cifrar a host remoto: 22 bajo el replicador de usuario con una velocidad de hasta 10 MB / sy deje 10 imágenes en la fuente y 20 en el host remoto
zfskeeper.sh bank / encrypted / subvol-100-disk-0 10 Remotehost 22 10 m replicator bank / rtl / subvol -100-disk-0 20 -w lo mismo, pero los datos se cifrarán

#!/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


Para mantener entonadas varias secciones, necesita un script de control. Todos ya pueden hacerlo a su gusto y color, dependiendo de la configuración. Mi prueba se ve así:

#!/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

Soluciones existentes


Primero lo encontré, sobre la base de eso verifiqué la operatividad general del mecanismo. Gracias a los autores, pero el estilo de escritura es bastante sucio, tuvo que reescribirse sin ambigüedades.

zfs-auto-snapshot.sh es solo un bloque. Hay algo para pedir prestado,

zfsbackup.sh hermoso, ordenado, pero voluminoso y poco funcional , también un

PS ordenado, pero poco funcional . Mordí el zfs por tercera vez, cada vez que mordisqueaba durante aproximadamente un mes. No pude hacer que trabajara rápidamente, y al máximo fallé. En general, la situación cambió después de instalar discos SAS (al menos 7200, al menos NL).

¡Paz para todos! ¡Gracias por leer!

All Articles