Problema
En entornos con Proxmox VE es frecuente montar un pool ZFS en el host y exponerlo a un contenedor LXC mediante bind mount para servir archivos con Samba. El desafío surge al diseñar la estrategia de respaldo con Proxmox Backup Server (PBS): ¿debería PBS respaldar solo el disco raíz del contenedor o incluir también los datos del pool ZFS que están montados dentro del LXC? Además, muchos administradores se preguntan si colocar el sistema operativo del host y los discos raíz de máquinas virtuales/LXC en el mismo SSD RAID‑1 es una práctica segura o si genera cuellos de botella.
Causa
1. Separación lógica vs. física de datos
Los contenedores LXC son esencialmente procesos aislados; su sistema de archivos raíz está en un subvolumen ZFS o en un directorio del host. Cuando se hace bind mount de un dataset ZFS externo, el contenedor ve esos datos como parte de su árbol, pero PBS, al trabajar a nivel de subvolumen del contenedor, no tiene visibilidad directa del dataset externo. Si se configura una tarea de backup que solo apunta al subvolumen del contenedor, los archivos del dataset quedan fuera del snapshot y, por tanto, fuera del respaldo.
2. Snapshots y consistencia de ZFS
ZFS permite snapshots atómicos de datasets completos. Si el dataset está montado dentro del contenedor y se modifica mientras PBS crea un backup, el snapshot del contenedor no captura esos cambios. La única forma de garantizar consistencia es crear un snapshot del dataset ZFS antes de que PBS lo incluya en la copia.
3. Uso intensivo del SSD para OS + VM roots
Un SSD en espejo (RAID‑1) ofrece redundancia y buen rendimiento, pero si el mismo espejo aloja tanto el sistema operativo del host como los discos raíz de todas las VMs/LXC, cualquier I/O intensivo de backup o de la carga de trabajo de Samba compite por el mismo recurso. En entornos SMB con varios TB de datos, esa competencia puede traducirse en latencias notables y mayor desgaste del SSD.
Solución
Estrategia de backup híbrida
-
Separar los datasets
- Mantener el dataset ZFS que contiene los datos de Samba en su propio pool o al menos en un dataset independiente (
tank/samba-data). - El contenedor LXC tiene su propio dataset (
tank/lxc-samba-root) que solo contiene la configuración y los binarios de Samba.
- Mantener el dataset ZFS que contiene los datos de Samba en su propio pool o al menos en un dataset independiente (
-
Configurar PBS para respaldar ambos datasets
- Crear dos trabajos de backup en PBS:
a) Root backup: apunta al subvolumen del contenedor (/var/lib/vz/snippets/lxc-samba-root).
b) Data backup: apunta al dataset ZFS externo (/mnt/samba-data). - En el trabajo de Data backup habilitar la opción
--snapshotpara que PBS solicite a ZFS un snapshot antes de copiar.
- Crear dos trabajos de backup en PBS:
-
Automatizar snapshots con hooks
- Utilizar los hook scripts de Proxmox (
/etc/pve/lxc/<CTID>.conf) para ejecutarzfs snapshotjusto antes de que PBS inicie el backup del dataset externo. - El hook también puede destruir el snapshot después de que PBS confirme la transferencia, evitando la proliferación de snapshots.
- Utilizar los hook scripts de Proxmox (
-
Revisar la arquitectura de discos
- Mantener el SSD RAID‑1 exclusivamente para el sistema operativo del host y los discos raíz de VMs/LXC que requieren alta velocidad (por ejemplo, bases de datos pequeñas).
- Reservar los HDDs en el pool ZFS para datos de usuario, backups y archivos de Samba.
- Si el presupuesto lo permite, agregar un SSD dedicado para los snapshots de ZFS (
tank/snapshots) de modo que la escritura de snapshots no impacte el rendimiento del pool de datos.
Implementación paso a paso
a) Creación de datasets
# Dataset para el root del contenedor LXC
zfs create -o mountpoint=/var/lib/vz/snippets/lxc-samba-root tank/lxc-samba-root
# Dataset para los archivos de Samba
zfs create -o mountpoint=/mnt/samba-data tank/samba-data
b) Bind mount en el contenedor
Edita la configuración del contenedor (/etc/pve/lxc/101.conf):
mp0: /mnt/samba-data,mp=/srv/samba,bind=1
c) Hook script para snapshots
Crea /etc/pve/lxc/101.hookscript:
#!/bin/bash
# $1 = pre-start | post-stop | pre-backup | post-backup
if [ "$1" = "pre-backup" ]; then
zfs snapshot tank/samba-data@pbs-$(date +%Y%m%d%H%M%S)
elif [ "$1" = "post-backup" ]; then
zfs destroy tank/samba-data@pbs-$(date +%Y%m%d%H%M%S)
fi
Hazlo ejecutable y enlázalo en la configuración:
hookscript: /etc/pve/lxc/101.hookscript
d) Configuración de PBS
En la interfaz web de PBS crea dos Backup Jobs:
-
Job 1 – LXC Root:
- Source:
proxmox-host:/tank/lxc-samba-root - Type:
LXC - No snapshot (el contenedor ya está detenido o en modo freeze).
- Source:
-
Job 2 – Samba Data:
- Source:
proxmox-host:/tank/samba-data@pbs-* - Type:
Filesystem - Enable snapshot (PBS enviará
zfs snapshotautomáticamente si el host tiene el daemonzfshabilitado).
- Source:
Ventajas
- Consistencia: Cada backup de datos incluye un snapshot ZFS atómico, evitando archivos corruptos.
- Escalabilidad: Los datasets pueden crecer independientemente; los snapshots no afectan al pool de datos.
- Rendimiento: Separar SSD y HDD reduce la contención de I/O y prolonga la vida útil del SSD.
Cuándo aplicar esta solución
- Entornos con bind mounts: Si cualquier contenedor LXC consume datasets ZFS externos, la estrategia híbrida es la más segura.
- Alto volumen de datos: Cuando el pool ZFS supera varios terabytes y los backups deben ser consistentes sin detener el servicio.
- Infraestructura con SSD limitado: Si el SSD está destinado al host y a VMs críticas, mover los datos de usuario a HDD evita cuellos de botella.
- No aplicar: En despliegues muy pequeños (p.ej., un único contenedor con <100 GB) donde la complejidad del hook script no justifica el beneficio; en ese caso un backup simple del contenedor puede ser suficiente.
Código
# Crear datasets
zfs create -o mountpoint=/var/lib/vz/snippets/lxc-samba-root tank/lxc-samba-root
zfs create -o mountpoint=/mnt/samba-data tank/samba-data
# Configurar bind mount en LXC
echo "mp0: /mnt/samba-data,mp=/srv/samba,bind=1" >> /etc/pve/lxc/101.conf
# Hook script (pre-backup / post-backup)
cat > /etc/pve/lxc/101.hookscript <<'EOF'
#!/bin/bash
if [ "$1" = "pre-backup" ]; then
zfs snapshot tank/samba-data@pbs-$(date +%Y%m%d%H%M%S)
elif [ "$1" = "post-backup" ]; then
zfs destroy tank/samba-data@pbs-$(date +%Y%m%d%H%M%S)
fi
EOF
chmod +x /etc/pve/lxc/101.hookscript
echo "hookscript: /etc/pve/lxc/101.hookscript" >> /etc/pve/lxc/101.conf
Verificación
-
Comprobar snapshot
Ejecutazfs list -t snapshot | grep pbs-antes y después de iniciar el backup. Debería aparecer y luego desaparecer tras elpost-backup. -
Validar backup en PBS
En la UI de PBS verifica que ambos jobs aparecen como Successful y que el tamaño del backup de datos coincide con el uso del dataset (zfs get used tank/samba-data). -
Prueba de restauración
- Restaura el dataset en un entorno de pruebas:
zfs rollback tank/samba-data@pbs-<timestamp>. - Monta el contenedor y verifica que Samba sigue sirviendo los archivos sin errores.
- Restaura el dataset en un entorno de pruebas:
-
Monitoreo de I/O
Usaiostat -x 5ozpool iostat -v tank 5para observar que durante el backup el SSD no muestra picos de escritura inesperados.
Notas adicionales
- Retención de snapshots: Si el hook script falla y deja snapshots huérfanos, programa una tarea cron que elimine snapshots viejos (
zfs destroy -r tank/samba-data@pbs-*con una política de retención de 7‑14 días). - Compresión ZFS: Activar
compression=lz4entank/samba-datareduce el espacio necesario tanto en disco como en el backup, sin penalizar el rendimiento de Samba. - Seguridad: Asegúrate de que el usuario que ejecuta PBS tenga permisos de
zfs allowsobre el dataset, evitando que el proceso sea root por completo. - Off‑site: PBS permite replicar backups a otro servidor PBS mediante remote repositories. Configura una replicación diaria del job de datos para cumplir con la política de copia off‑site sin sobrecargar el host principal.