Backup efficienti di container LXC in Proxmox (e non solo)

Proxmox

NOTA: Il seguente post è la traduzione dell'equivalente sul blog it-notes. L'originale sarà sempre più aggiornato.

A volte un container lxc può essere un'alternativa più valida rispetto ad ad una macchina virtuale KVM. Ha un overhead inferiore, una gestione delle risorse più semplice ed efficiente e un minore impatto sulla macchina fisica.

Si ottiene (potenzialmente) meno isolamento dalla macchina fisica e si è costretti ad usare il kernel dell’host. Inoltre, non è possibile eseguire un sistema operativo diverso.

Proxmox supporta in maniera nativa i container lxc ed essi sono spesso una buona scelta. Ho recentemente convertito alcune VM in container lxc e sono più veloci, più leggeri e l'occupazione della ram è abbastanza bassa.

Ci sono due grossi svantaggi: non è possibile migrare un container lxc in esecuzione (deve essere spento, spostato e riavviato - se si usa uno storage condiviso, spesso è una questione di secondi) e i backup su Proxmox Backup Server sono più lenti rispetto al backup di una VM.

Questo perché una VM può monitorare, grazie alle dirty bitmap di KVM, le sue operazioni su disco per sapere in anticipo quali blocchi devono essere controllati e copiati. Quando si ha a che fare con i container lxc non è possibile farlo, quindi ogni operazione di backup dovrà controllare ogni singolo file - questo si è dimostrato efficiente in termini di spazio e deduplicazione, ma piuttosto lento in termini di tempo. Una delle mie VM (750 GB memorizzati ma con sporadico accesso al disco) ha richiesto solo alcuni minuti per il backup con dirty bitmap, ma più o meno 2 ore per il backup da quando è stata trasformata in un contenitore lxc.

Il backup con borg si è dimostrato abbastanza efficiente, così ho cercato di trovare un modo per eseguire il backup di quei contenitori eseguendo una snapshot, eseguendo il backup e, poi, rilasciandola.

Non possiamo usare dattobd sul container, quindi dobbiamo fare una snapshot e fare il backup direttamente dall'host. Questo ha un grande vantaggio: non abbiamo bisogno che il container conosca la sua posizione di backup in quanto ogni operazione sarà fatta dall'host Proxmox.

I miei container sono generalmente memorizzati in volumi rbd di Ceph o in thin pool di LVM.

Ho creato uno script per affrontare entrambe queste situazioni - e non dipende da Proxmox, quindi funziona anche se non lo si usa.

Prima di tutto, si dovrebbe creare un utente e un repository borg su una macchina remota e permettere all'host Proxmox di effettuare il login via ssh usando una chiave. Poi, creare una directory (/tobackup nei seguenti script, sull'host) dove verranno montate le snapshot.

Nell'esempio/script seguente, non verrà utilizzata alcuna crittografia per la memorizzazione di backup. Se si desidera crittografare il backup, sarà necessario eseguire piccole modifiche.

Ecco il mio rbd_borg_bck.sh :

#!/bin/bash
set -e
export SOURCE_DISK=$1
export USERNAME=$2
export HOST=$3
PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes;
echo "Creating and mapping snapshot..."
rbd snap create $SOURCE_DISK@tobackup && DDISK=`rbd map $SOURCE_DISK@tobackup`
echo "Creating backup directory..."
mkdir -p /tobackup/$DDISK
echo "Mounting snapshot..."
mount -o noload $DDISK /tobackup/$DDISK
echo "DOING BACKUP..."
REPOSITORY=$USERNAME@$HOST:$USERNAME/
TAG=daily
borg create -v --stats --progress --compression zlib,9                           \
    $REPOSITORY::$TAG'-{now:%Y-%m-%dT%H:%M:%S}'          \
    /tobackup/$DDISK/                                       \
    --exclude '*/home/*/.cache*'                  \
    --exclude '*/home/*/.local*'                  \
    --exclude '*/home/*/.pki*'                    \
    --exclude '*/home/*/Virtualbox VMs*'          \
    --exclude '*/home/*/.vagrant.d*'              \
    --exclude '*/root/.cache*'                    \
    --exclude '*/var/swap*'
sleep 3s;
echo "Unmounting snapshot..."
umount /tobackup/$DDISK
sleep 3s;
echo "Unmapping snapshot..."
rbd unmap $DDISK
echo "Remove snapshot..."
rbd snap remove $SOURCE_DISK@tobackup
echo "Pruning..."
borg prune -v $REPOSITORY --stats --prefix $TAG'-' \
    --keep-daily=14 --keep-weekly=8 --keep-monthly=12
echo "Done!"

Per esempio, per eseguire il backup di un disco memorizzato nel pool "vmrbdpool" denominato vm-101-disk-0 tramite ssh sul server backupserver.mydomain.org, nome utente sul server (e nome del repository, all'interno della directory home di quell'utente, chiamato server01), si può lanciare lo script in questo modo:

/usr/local/bin/rbd_borg_bck.sh vmrbdpool/vm-101-disk-0 server01 backupserver.mydomain.org

Questo può anche essere programmato e lanciato da cron (sull'host Proxmox) o in qualsiasi altro modo.

Per i thin pool di LVM, lo script è un po' diverso. Ecco il mio lvm_thin_borg_bck.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash
set -e

export SOURCE_DISK=$1
export USERNAME=$2
export HOST=$3
export LVM=$4
export DDISK=$4/$2-borgsnap

PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH

export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes;

echo "Creating and mapping snapshot..."
lvcreate -n $2-borgsnap -s $1
lvchange -ay -Ky $DDISK


echo "Creating backup directory..."
mkdir -p /tobackup/$DDISK

echo "Mounting snapshot..."
mount -o ro /dev/$DDISK /tobackup/$DDISK

echo "DOING BACKUP..."

REPOSITORY=$USERNAME@$HOST:$USERNAME/
TAG=daily

borg create -v --stats --progress --compression zlib,9                           \
    $REPOSITORY::$TAG'-{now:%Y-%m-%dT%H:%M:%S}'          \
    /tobackup/$DDISK/                                       \
    --exclude '*/home/*/.cache*'                  \
    --exclude '*/home/*/.local*'                  \
    --exclude '*/home/*/.pki*'                    \
    --exclude '*/home/*/Virtualbox VMs*'          \
    --exclude '*/home/*/.vagrant.d*'              \
    --exclude '*/root/.cache*'                    

sleep 3s;

echo "Unmounting snapshot..."
umount /tobackup/$DDISK

sleep 3s;

echo "Remove snapshot..."
yes | lvremove $DDISK

echo "Pruning..."
borg prune -v $REPOSITORY --stats --prefix $TAG'-' \
    --keep-daily=14 --keep-weekly=8 --keep-monthly=12

echo "Done!"

In questo esempio, vogliamo fare il backup di un disco "/dev/prox1/vm-120-disk-0", il nome utente sul server è server01 (stesso nome del repository), il server è backupserver.mydomain.org e, come ultimo argomento, "prox1" che è il pool lvm.

/usr/local/bin/lvm_thin_borg_bck.sh /dev/prox1/vm-120-disk-0 server01 backupserver.mydomain.org prox1

Borg è efficiente e veloce e, grazie a questo tipo di configurazione, posso creare un backup del container da 750 GB in 2 minuti.

Grazie a questo tipo di configurazione, i backup possono essere effettuati in modo coerente ed efficiente.

Commenti