Ir al contenido
  1. Posts/

zfs clone en Proxmox: cómo pruebo cambios sin tocar el dataset original

·2197 palabras·11 mins

zfs clone es una de esas funciones que no parecen gran cosa hasta que la usas justo en el momento adecuado. Ya tienes un snapshot. Quieres probar algo encima de ese estado. No quieres tocar el dataset original. Tampoco quieres esperar a copiar decenas o cientos de gigas. Ahí entra el clon.

La idea es sencilla. ZFS coge un snapshot y crea a partir de él un dataset nuevo, escribible, que comparte los bloques originales. Al principio ocupa muy poco porque no duplica todo el contenido. A medida que cambias cosas dentro del clon, ZFS va guardando las diferencias. Es como decirle al sistema: “déjame una rama de este punto exacto y ya veré qué hago con ella”.

En Proxmox me gusta para pruebas controladas. No lo uso como magia negra para producción. Lo uso para validar cambios, revisar datos, probar una limpieza o montar una copia temporal antes de tomar una decisión. Es rápido, pero no es gratis mentalmente. El clon depende del snapshot del que nace. Si no entiendes esa relación, acabas con snapshots que no puedes borrar y datasets colgando como trastos en un garaje.

El flujo mínimo es este.

1
2
zfs snapshot pve-zfs/datos@app-antes-upgrade
zfs clone pve-zfs/datos@app-antes-upgrade pve-zfs/pruebas/app-upgrade

Después ya puedes montar o usar pve-zfs/pruebas/app-upgrade como un dataset normal. La diferencia importante es que no has copiado todo el dataset original. Has creado una vista escribible desde un snapshot.

la captura de este post
#

La captura usa una salida saneada de Proxmox. No hay IPs reales, nombres internos ni rutas privadas. Es el caso más básico: snapshot, clon, comprobación de origen y limpieza.

Salida saneada de zfs clone en Proxmox

Esta es la salida saneada que usé para generar la captura:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ zfs snapshot pve-zfs/appdata@antes-upgrade

$ zfs clone pve-zfs/appdata@antes-upgrade pve-zfs/pruebas/appdata-upgrade

$ zfs list -o name,origin,used,refer -r pve-zfs/pruebas
NAME                              ORIGIN                          USED  REFER
pve-zfs/pruebas                   -                                96K    96K
pve-zfs/pruebas/appdata-upgrade   pve-zfs/appdata@antes-upgrade   128K  3.42G

$ zfs get origin pve-zfs/pruebas/appdata-upgrade
NAME                             PROPERTY  VALUE                         SOURCE
pve-zfs/pruebas/appdata-upgrade  origin    pve-zfs/appdata@antes-upgrade -

$ zfs destroy pve-zfs/pruebas/appdata-upgrade
$ zfs destroy pve-zfs/appdata@antes-upgrade

Ese último orden importa. Primero destruyo el clon. Después el snapshot. Si intento borrar el snapshot mientras el clon depende de él, ZFS me va a parar los pies. Bien por ZFS. A veces necesitamos que el ordenador nos quite las cerillas.

cuándo me resulta útil
#

El caso más claro es probar un cambio destructivo sin tocar el dataset real. Imagina un dataset con configuración de una aplicación, datos de prueba o una carpeta grande que usa un contenedor. Quieres cambiar permisos, limpiar basura, actualizar una estructura o ejecutar un script que mueve ficheros. Puedes hacerlo directamente y confiar en tu pulso. También puedes crear snapshot, clonar y romper el clon con alegría moderada.

La segunda opción me parece más adulta.

También lo uso cuando quiero inspeccionar un estado antiguo sin restaurarlo. Un snapshot por sí solo es de solo lectura. Eso está bien para mirar. Pero si necesito levantar una copia modificable, cambiar algo y ver cómo se comporta, el clon encaja mejor. No estoy diciendo que haya que clonar cada snapshot. Sería absurdo. Pero para una prueba concreta ahorra bastante tiempo.

Otro caso: migraciones pequeñas. Antes de tocar el dataset bueno, creo un clon y ejecuto el proceso sobre esa copia. Si el proceso genera una estructura limpia, anoto pasos y los repito sobre el origen cuando ya tengo confianza. Si sale mal, borro el clon y no me llevo el desastre a casa.

En homelab esto pasa más de lo que parece. Cambias una aplicación self-hosted de versión. El contenedor arranca, migra base de datos, toca ficheros y ya no hay vuelta sencilla. Si has hecho backup, perfecto. Si además puedes probar la migración sobre un clon, mejor todavía. No siempre merece la pena, pero cuando la aplicación tiene datos que te importan, el coste de clonar es ridículo comparado con arreglar una migración rota a medianoche.

qué diferencia hay entre snapshot, clone y rollback
#

Esta parte conviene tenerla clara porque son tres palabras que se pisan en la cabeza.

Un snapshot es una foto de solo lectura de un dataset en un momento concreto. No lo editas. Lo conservas para comparar, enviar o volver atrás.

Un rollback devuelve el dataset original a un snapshot anterior. Es una acción directa sobre el dataset. Si vuelves atrás, tiras cambios posteriores. Es útil, pero no es una prueba. Es una decisión.

Un clon crea un dataset nuevo y escribible desde un snapshot. El origen queda quieto. Tú trabajas en una rama aparte. Si te gusta lo que ves, puedes usar lo aprendido. Si no, borras el clon.

Para mí, esa es la gracia. rollback es cirugía sobre el paciente. clone es ensayar la operación en una copia. La analogía es un poco dramática, pero el homelab también tiene sus quirófanos cutres.

el detalle incómodo: el snapshot queda retenido
#

El clon depende del snapshot original. Eso significa que el snapshot no se puede borrar mientras exista un clon que cuelga de él.

Puedes verlo con:

1
zfs get origin pve-zfs/pruebas/appdata-upgrade

También puedes usar zfs list mostrando la columna origin.

1
zfs list -o name,origin,used,refer

Si el dataset no es un clon, origin saldrá vacío o con un guion. Si es un clon, verás el snapshot base. Esa columna es la que miro antes de hacer limpieza. No me gusta borrar snapshots a ciegas. Menos todavía cuando he estado creando clones para pruebas.

El error típico es crear varios clones temporales y olvidarse de ellos. Semanas después miras los snapshots y hay uno que no se deja borrar. ZFS no está siendo caprichoso. Hay algo que depende de él.

Para encontrar clones, suelo hacer algo así:

1
zfs list -o name,origin | grep '@'

No es una obra de ingeniería, pero funciona. Si aparece una línea con origin, ya sé que hay una dependencia real.

clones para probar upgrades de aplicaciones
#

Este es probablemente mi uso favorito. Tengo una app con datos en un dataset. Antes de actualizar, creo snapshot y clon.

1
2
zfs snapshot pve-zfs/appdata@app-v1
zfs clone pve-zfs/appdata@app-v1 pve-zfs/pruebas/appdata-v2

Luego apunto un contenedor de prueba a ese dataset clonado. No uso el contenedor de producción. No uso las mismas credenciales externas. No expongo el servicio fuera. Solo quiero ver si arranca, si migra y si los datos tienen pinta normal.

Si la aplicación actualiza su base de datos interna, prefiero que lo haga primero contra el clon. Así veo logs, tiempos y errores sin jugármela. Si todo parece bien, ya tengo una idea más clara de lo que pasará en producción.

Hay una limitación obvia. Si la aplicación habla con servicios externos o depende de rutas muy específicas, el clon no replica el mundo entero. Solo replica datos del dataset. Hay que tenerlo en cuenta. Un clon de ZFS no convierte tu homelab en un entorno de staging perfecto. Ojalá. Solo te da una copia escribible muy barata del almacenamiento.

clones para revisar limpiezas
#

También me sirven para limpiezas agresivas. Por ejemplo, un dataset lleno de cachés, exports viejos o carpetas que ya no sé si usa alguien. En vez de borrar sobre el origen, clono y pruebo una limpieza.

1
2
zfs snapshot pve-zfs/media@app-limpieza
zfs clone pve-zfs/media@app-limpieza pve-zfs/pruebas/media-limpieza

En el clon ejecuto el script, veo cuánto libera y compruebo qué rutas toca. Si el script borra más de lo que debería, no pasa nada grave. Borro el clon y corrijo.

Esto parece una tontería hasta que un find mal escrito decide que el martes es buen día para llevarse medio árbol por delante. Los comandos de limpieza tienen una capacidad especial para parecer obvios justo antes de ser idiotas.

cuidado con el espacio usado
#

Un clon empieza ocupando poco, pero eso no significa que sea gratis para siempre. Si cambias muchos datos dentro del clon, ZFS tiene que guardar esos bloques nuevos. Si borras cosas en el clon, no necesariamente liberas espacio del pool de la forma que esperas, porque el snapshot base sigue reteniendo los bloques originales.

Por eso miro used y refer.

1
zfs list -o name,used,refer,origin pve-zfs/pruebas/appdata-upgrade

refer te da una idea del tamaño visible del dataset. used te dice lo que ese dataset está consumiendo de forma propia. En clones y snapshots conviene no leer una sola columna y sacar conclusiones heroicas.

Si voy a hacer una prueba que va a escribir muchísimo, igual prefiero una copia completa o un entorno separado. zfs clone brilla cuando quieres probar cambios razonables sobre una base existente. Si vas a machacar medio dataset, deja de ser tan elegante.

cómo limpio después
#

Mi regla es simple: todo clon temporal tiene que morir al terminar la prueba. Si no lo voy a usar mañana, lo borro hoy.

Primero reviso:

1
zfs list -o name,origin -r pve-zfs/pruebas

Después destruyo el clon:

1
zfs destroy pve-zfs/pruebas/appdata-upgrade

Y solo después, si el snapshot ya no me interesa, borro el snapshot:

1
zfs destroy pve-zfs/appdata@antes-upgrade

Si ZFS se queja, no fuerzo nada. Miro dependencias. En almacenamiento, forzar sin entender es una forma muy rápida de convertir una tarde normal en una autopsia.

promote: existe, pero no lo uso a la ligera
#

ZFS tiene zfs promote, que permite invertir la relación entre un clon y su origen. Puede ser útil cuando un clon acaba convirtiéndose en el dataset principal. Pero no es un comando que use por costumbre.

1
zfs promote pve-zfs/pruebas/appdata-upgrade

Antes de hacer eso, quiero entender exactamente qué snapshots quedan en cada lado y qué dataset va a depender de cuál. Para la mayoría de mis pruebas, no necesito promover nada. Pruebo, aprendo, borro. Si una prueba acaba siendo producción, prefiero planear esa migración con calma en vez de improvisar una promoción porque me ha dado pereza copiar datos.

No digo que promote sea malo. Digo que no es el botón de “hacer bueno el clon” para tocar sin mirar. Tiene su sitio, pero no en una rutina nocturna con café malo y demasiadas pestañas abiertas.

mi checklist antes de clonar
#

Antes de crear un clon suelo revisar cuatro cosas.

Primero, que el dataset origen es el correcto. Parece obvio. No lo es cuando tienes nombres parecidos y varios nodos.

Segundo, que el snapshot tiene un nombre claro. @test no me vale. @antes-upgrade-junio ya me dice algo.

Tercero, que el destino está en una zona de pruebas. Me gusta usar una rama tipo pve-zfs/pruebas/... porque luego puedo listar y limpiar fácil.

Cuarto, que sé cómo voy a borrar el clon. Si no tengo una salida limpia, probablemente estoy mezclando prueba y producción.

El comando queda más o menos así:

1
2
3
zfs snapshot pve-zfs/appdata@antes-upgrade-junio
zfs clone pve-zfs/appdata@antes-upgrade-junio pve-zfs/pruebas/appdata-upgrade-junio
zfs list -o name,origin,used,refer pve-zfs/pruebas/appdata-upgrade-junio

Con eso tengo una copia escribible, rápida y bastante segura para experimentar.

cuándo no usaría zfs clone
#

No lo usaría como sustituto de backup. Si el pool cae, el clon cae con él. Si el servidor se muere, el clon no vive en una dimensión paralela. Para protección real quiero copias fuera del pool, y si puede ser fuera del equipo.

Tampoco lo usaría para pruebas que necesitan aislar servicios completos. Si una app depende de base de datos externa, colas, buckets o endpoints remotos, clonar solo el dataset puede darte una falsa sensación de seguridad. Sirve para una parte del sistema, no para todo el sistema.

Y no lo usaría si no voy a limpiar después. Los clones temporales olvidados son deuda técnica con sombrero de copa. Al principio no molestan. Luego bloquean snapshots, ocupan espacio y nadie recuerda por qué existen.

cómo lo encajo en Proxmox
#

En Proxmox, muchas veces los discos de VM y contenedores viven como volúmenes ZFS gestionados por la propia plataforma. Ahí tengo cuidado. No me gusta clonar por debajo algo que Proxmox cree gestionar de otra forma, salvo que sepa exactamente qué estoy haciendo.

Donde más cómodo me siento es con datasets auxiliares: appdata, plantillas, datos montados en contenedores, exports y carpetas de pruebas. Cosas que yo he creado como datasets y cuyo ciclo de vida entiendo.

Para VMs completas, prefiero usar snapshots y clones desde Proxmox cuando toca. La interfaz y las herramientas de Proxmox ya llevan su propia contabilidad. Mezclar comandos manuales de ZFS con recursos gestionados por Proxmox puede funcionar, pero no es mi primera opción para una rutina normal.

con qué me quedo
#

zfs clone me parece una herramienta muy buena para ensayar. No arregla una mala política de backups. No sustituye staging. No convierte Proxmox en magia. Pero te da una copia escribible de un punto exacto con un coste inicial bajísimo.

Lo uso cuando quiero tocar datos con menos miedo, probar upgrades, revisar limpiezas o entender qué va a pasar antes de hacerlo sobre el dataset bueno. La clave está en tres hábitos: nombrar bien el snapshot, revisar origin y borrar el clon cuando termina la prueba.

Si mantienes eso, zfs clone es de las herramientas más agradecidas de ZFS. Si no, se convierte en otra capa de cosas raras que tendrás que explicar dentro de tres meses. Y dentro de tres meses nadie quiere explicaciones. Quiere que el pool esté limpio y que el servicio arranque.