Esta pagina se ve mejor con JavaScript habilitado

Backup Jails Iocage mediante snapshots ZFS

 ·  🎃 kr0m

Realizar backups fiables de forma rápida y sencilla puede resultar una tarea titánica, por suerte mediante el uso de snapshots ZFS podremos simplificarlo de tal modo que será coser y cantar.

El artículo se compone de distintas secciones:


Creamos un snapshot

Creamos el snapshot mediante Iocage , en realidad podríamos hacerlo mediante comandos ZFS, pero prefiero utilizar Iocage.

Como ejemplo lo haremos sobre una Jail llamada HAProxy(si con bases de datos también funciona sin problemas):

iocage snapshot -n BACKUP HAProxy

Snapshot: zroot/iocage/jails/HAProxy@BACKUP created.

Consultamos los snapshots de la Jail:

iocage snaplist HAProxy

+-----------------------------------------------------+-----------------------+-------+-------+
|                        NAME                         |        CREATED        | RSIZE | USED  |
+=====================================================+=======================+=======+=======+
| BACKUP                                              | Thu Jul 22  22:30 2021 | 112K  | 0B   |
+-----------------------------------------------------+-----------------------+-------+-------+
| BACKUP/root                                         | Thu Jul 22  22:30 2021 | 4.28G | 136K |
+-----------------------------------------------------+-----------------------+-------+-------+

Como vemos hay dos snapshots, esto es debido a que cuando realizamos un snapshot desde Iocage este lo hace del directorio donde se encuentran los ficheros de configuración de la Jail y del sistema de ficheros raíz.

Nosotros backupearemos el sistema de ficheros raíz y los ficheros de configuración los backupearemos manualmente sin utilizar ZFS.


Dump snapshot

Consultamos los snapshots ZFS disponibles:

zfs list -t snapshot

NAME                                                                              USED  AVAIL     REFER  MOUNTPOINT
zroot/iocage/jails/HAProxy@BACKUP                                                   0B      -      112K  -
zroot/iocage/jails/HAProxy/root@BACKUP                                            136K      -     4.28G  -

Como ya hemos dicho anteriormente hay dos snapshots pero solo nos interesa el del sistema de ficheros raíz de la Jail.

Dumpeamos el snapshot a un fichero:

zfs send zroot/iocage/jails/HAProxy/root@BACKUP > haproxy.raw

Si consultamos el tipo de fichero que hemos generado veremos que se trata de un ZFS shapshot:

file haproxy.raw

haproxy.raw: ZFS shapshot (little-endian machine), version 17, type: ZFS, destination GUID: 8A 36 8B AC 2E C4 C0 85, name: 'zroot/iocage/jails/HAProxy/root@BACKUP'

Además del dump del snapshot es recomendable copiar los ficheros de configuración de la Jail:

cp /zroot/iocage/jails/HAProxy/config.json /root/
cp /zroot/iocage/jails/HAProxy/fstab /root/

Eliminamos el snapshot:

iocage snapremove -n BACKUP HAProxy

Snapshot: zroot/iocage/jails/HAProxy@BACKUP destroyed

Restore dataset ZFS

Creamos el dataset donde restauraremos el snapshot:

zfs create storage/restored
zfs recv -dvu storage/restored < haproxy.raw

receiving full stream of zroot/iocage/jails/HAProxy/root@BACKUP into storage/restored/iocage/jails/HAProxy/root@BACKUP
received 6.01G stream in 350 seconds (17.6M/sec)

Localizamos el dataset a montar:

zfs list

NAME                                         USED  AVAIL     REFER  MOUNTPOINT
storage/restored                            4.28G   168G       96K  /storage/restored
storage/restored/iocage                     4.28G   168G       96K  /storage/restored/iocage
storage/restored/iocage/jails               4.28G   168G       96K  /storage/restored/iocage/jails
storage/restored/iocage/jails/HAProxy       4.28G   168G       96K  /storage/restored/iocage/jails/HAProxy
storage/restored/iocage/jails/HAProxy/root  4.28G   168G     4.28G  /storage/restored/iocage/jails/HAProxy/root

Lo montamos:

zfs mount storage/restored/iocage/jails/HAProxy/root

Como podemos ver los ficheros están accesibles en el punto de montaje:

ls -la /storage/restored/iocage/jails/HAProxy/root

total 128
drwxr-xr-x  19 root  wheel    24 May 17 08:38 .
drwxr-xr-x   3 root  wheel     3 Jul 22 09:54 ..
-rw-r--r--   2 root  wheel  1023 May 17 08:38 .cshrc
-rw-r--r--   2 root  wheel   507 May 17 08:38 .profile
-r--r--r--   1 root  wheel  6109 May 17 08:38 COPYRIGHT
drwxr-xr-x   2 root  wheel    46 Jul  5 07:53 bin
drwxr-xr-x  15 root  wheel    66 Jul  5 07:53 boot
dr-xr-xr-x   2 root  wheel     2 Oct 23  2020 dev
drwxr-xr-x  27 root  wheel   109 Jul 19 19:23 etc
lrwxr-xr-x   1 root  wheel     8 Jan  1  2021 home -> usr/home
drwxr-xr-x   5 root  wheel    67 Jul  5 07:53 lib
drwxr-xr-x   3 root  wheel     5 May 17 08:37 libexec
drwxr-xr-x   2 root  wheel     2 Oct 23  2020 media
drwxr-xr-x   2 root  wheel     2 Oct 23  2020 mnt
drwxr-xr-x   2 root  wheel     2 Oct 23  2020 net
dr-xr-xr-x   2 root  wheel     2 Oct 23  2020 proc
drwxr-xr-x   2 root  wheel   150 May 17 08:39 rescue
drwxr-xr-x   4 root  wheel    15 Jun 28 07:45 root
drwxr-xr-x   2 root  wheel   137 May 17 13:55 sbin
drwxr-xr-x   3 root  wheel     3 Mar 18 09:11 storage
lrwxr-xr-x   1 root  wheel    11 Nov  2  2020 sys -> usr/src/sys
drwxrwxrwt   6 root  wheel     6 Jul 22 05:00 tmp
drwxr-xr-x  15 root  wheel    15 Jan  1  2021 usr
drwxr-xr-x  25 root  wheel    25 Jul 19 19:23 var

Finalmente desmontamos y destruimos el dataset:

zfs umount storage/restored/iocage/jails/HAProxy/root
zfs destroy -r storage/restored


Restore Jail Iocage

Para restaurar el snapshot como una Jail primero debemos crear los datasets que Iocage espera:

zfs create zroot/iocage/jails/restored
zfs create zroot/iocage/jails/restored/root

Volcamos el snapshot:

zfs recv -F zroot/iocage/jails/restored/root < haproxy.raw

Editamos los ficheros de configuración para que los datos cuadren:

vi config.json

{
    "boot": 1,
    "cloned_release": "12.2-RELEASE",
    "host_hostname": "restored",
    "host_hostuuid": "restored",
    "ip4_addr": "nfe0|192.168.69.69/24",
    "jail_zfs_dataset": "iocage/jails/restored/data",
    "last_started": "2021-07-13 18:22:06",
    "release": "13.0-RELEASE-p3"
}

Copiamos la configuración al directorio correcto:

cp /root/config.json /zroot/iocage/jails/restored/config.json

Si la Jail tenía algún punto de montaje debemos editar también el fstab:

vi fstab

/storage/backups/HAProxy	/zroot/iocage/jails/restored/root/storage/backups/HAProxy	nullfs	rw	00 # Added by iocage on 2021-03-18 22:12:31

Copiamos la configuración al directorio correcto:

cp /root/fstab /zroot/iocage/jails/restored/fstab

Arrancamos la Jail:

iocage start restored

* Starting restored
  + Started OK
  + Using devfs_ruleset: 1011 (iocage generated default)
  + Using IP options: ip4.addr=nfe0|192.168.69.69/24 ip4.saddrsel=1 ip4=new ip6.saddrsel=1 ip6=new
  + Starting services OK
  + Executing poststart OK

Comprobamos que esté up:

iocage list

+-----+----------+-------+--------------+---------------+
| JID |   NAME   | STATE |   RELEASE    |      IP4      |
+=====+==========+=======+==============+===============+
| 1   | DrWho    | up    | 13.0-RELEASE | 192.168.69.6  |
+-----+----------+-------+--------------+---------------+
| 3   | HAProxy  | up    | 13.0-RELEASE | 192.168.69.11 |
+-----+----------+-------+--------------+---------------+
| 2   | Infinity | up    | 13.0-RELEASE | 192.168.69.12 |
+-----+----------+-------+--------------+---------------+
| 4   | Lomax    | up    | 13.0-RELEASE | 192.168.69.7  |
+-----+----------+-------+--------------+---------------+
| -   | Mistery  | down  | 13.0-RELEASE | 192.168.69.3  |
+-----+----------+-------+--------------+---------------+
| 5   | Potras   | up    | 13.0-RELEASE | 192.168.69.5  |
+-----+----------+-------+--------------+---------------+
| 15  | restored | up    | 13.0-RELEASE | 192.168.69.69 |
+-----+----------+-------+--------------+---------------+
| 6   | rxWod    | up    | 13.0-RELEASE | 192.168.69.10 |
+-----+----------+-------+--------------+---------------+

Script backups

Mediante el siguiente script conseguiremos realizar backups a nivel ZFS de todas las Jails que estén arrancadas pero cuyo nombre no comience por test_ o sea Lomax, además guardaremos un histórico de X días.

vi .scripts/jailsBackup.sh

#!/usr/local/bin/bash
source /root/.scripts/cecho.sh

BACKUP_DIR='/storage/backups'
DAYS_OF_BACKUP='7'

clear
cecho "Cyan" "<== Iocage Jail backup script by kr0m ==>"

echo ""
echo ""
for JAIL in $(iocage list|grep up|grep -v 'test_'|grep -v 'Lomax'|awk '{print$4}'); do
    cecho "Cyan" "-----------------------------------"
    cecho "Cyan" ">> Making ZFS snapshot: $JAIL"
    iocage snapshot -n BACKUP $JAIL
    BACKUP_SNAPSHOT=$(zfs list -t snapshot|grep $JAIL|grep 'root@BACKUP'|awk '{print$1}')
    cecho "Cyan" ">> Saving ZFS snapshot -> $JAIL.raw"
    zfs send $BACKUP_SNAPSHOT > $BACKUP_DIR/$JAIL/$JAIL.raw
    cecho "Cyan" ">> Copying config files"
    cp /zroot/iocage/jails/$JAIL/config.json $BACKUP_DIR/$JAIL/
    cp /zroot/iocage/jails/$JAIL/fstab  $BACKUP_DIR/$JAIL/
    cecho "Cyan" ">> Deleting ZFS snapshot"
    iocage snapremove -n BACKUP $JAIL
    cecho "Cyan" ">> Compressing ZFS snapshot and config files"
    cd $BACKUP_DIR/$JAIL/
    DATE=$(date +%d-%m-%Y)
    tar czvf zfs_$DATE.tar.gz $JAIL.raw config.json fstab
    rm $JAIL.raw config.json fstab

    # Make cleaning of old backups:
    TOTAL=$(ls -lt zfs_*|wc -l|awk '{print$1}')
    if [ $TOTAL -gt $DAYS_OF_BACKUP ]; then
        cecho "Cyan" ">> Deleting old ZFS backups"
        let TO_DELETE=$TOTAL-$DAYS_OF_BACKUP
        for BACKUP in $(ls -lt zfs_*|awk '{print$9}'|tail -n $TO_DELETE); do
            cecho "Cyan" "-- Deleting ZFS backup: $BACKUP"
	    rm $BACKUP
        done
    fi
done

NOTA: El comando cecho simplemente es para que aparezca texto en color por terminal, podemos bajarnos el fichero de aquí o simplemente sustituirlo por echos normales.

Le asignamos los permisos necesarios:

chmod 700 .scripts/jailsBackup.sh

Programamos el backup a las 5:00 de la madrugada:

crontab -e

00 05 * * * /root/.scripts/jailsBackup.sh >/dev/null 2>&1
Si te ha gustado el artículo puedes invitarme a un RedBull aquí