Cuando el año pasado instalé LXD y lo configuré por primera vez, me encontré que podía utilizar, de hecho se recomienda, el sistema de ficheros ZFS para albergar los contenedores. Posteriormente, cuando instalé Proxmox en el servidor de mi departamento, me encontré de nuevo con ZFS. Anteriormente no le había prestado mucha atención a ZFS, normalmente utilizo EXT4 o XFS, pero estaba claro que había una estrecha relación entre ZFS y los sistemas de virtualización.
ZFS es un sistema de ficheros desarrollado por Sun Microsystems (creadores también del lenguaje de programación Java), posteriormente la empresa fue adquirida por Oracle, actuales propietarios. OpenZFS es la variante libre y posee una licencia de tipo CDDL, que aunque es software libre, es incompatible con GPL. Por este motivo, el kernel de Linux no lo incorpora de serie. Sin embargo, los usuarios pueden instalarlo sin problemas ya que se encuentra en los repositorios de la mayoría de las distribuciones de Linux.
Características de ZFS
ZFS era el acrónimo de Zettabyte File System. Actualmente no significa nada, es simplemente un nombre. Es un sistema de 128 bits y fue desarrollado con la idea de que nunca se fuera a quedar pequeño. Con 128 bits el espacio máximo es de 2¹²⁸ bytes, es decir, el volumen más grande que puede manejar es de 256 trillones de yobibytes. Con ficheros de un tamaño máximo de 16 exbibytes, ¡cifras realmente astronómicas!
A parte de su potencia a la hora de manejar volúmenes y ficheros exageradamente enormes, ZFS es un sistema que permite crecer con el tiempo. Se le pueden añadir más unidades de almacenamiento. Por otro lado, verifica constantemente la integridad de los datos almacenados, corrigiendo sobre la marcha los posibles errores que se vaya encontrando. Además, es copy-on-write (COW), admite compresión, deduplicación de datos, creación de instantáneas y clonación.
Es perfecto para crear RAID de discos. Cuenta con RAIDZ, que es un sistema RAID propio que soluciona los "agujeros de escrituras" de los sistemas RAID 5, al permitir stripes de datos de tamaño dinámico.
Nomenclatura propia de ZFS
ZFS utiliza el concepto de VDEV, Virtual DEVice. Un VDEV no es más que un conjunto de una o más unidades de almacenamiento físico. Es similar a los volúmenes de otros sistemas de almacenamiento. A partir de uno o más VDEV se crea el pool de almacenamiento. ZFS cuenta con siete tipos de VDEV:
- disk: Es el sistema por defecto y representa discos físicos.
- file: Ficheros cuyo espacio se hayan asignado de antemano.
- mirror: RAID 1 estándar.
- raidz1/2/3: Niveles RAID, no estándar, basados en paridad distribuida.
- spare: Discos duros marcados como "de reserva" para utilizarse en un RAID.
- cache: Sistema para utilizarse como caché de disco de nivel 2.
- log: Sistema de registro independiente llamado "ZFS Intent Log" o ZIL.
Por otro lado, ZFS denomina datasets a los sistemas de ficheros.
La forma de trabajar es la siguiente: se van creando VDEV a partir de las unidades de almacenamiento, cada VDEV pasa al pool de almacenamiento y a partir de este pool se van creando cada dataset. Los datasets ven el pool completo, de modo que si creamos un pool de 100GB cada vez que creemos un dataset nuevo, tendrá un tamaño de 100GB. Conforme se vayan llenando los diferentes datasets, el tamaño de todos irá disminuyendo. A la hora de crear un dataset podemos limitarlo a un tamaño menor en caso de necesitarlo.
Por ejemplo, podemos crear un pool para almacenar el directorio home de nuestros usuarios y crear un dataset diferente para cada usuario del sistema. En el caso de querer restringir el tamaño del directorio home de un usuario en concreto, simplemente restringimos el tamaño del dataset correspondiente en el momento de la creación.
Para hacer pruebas podemos utilizar ficheros ya existentes como unidades de almacenamiento a la hora de crear los VDEV (VDEV de tipo file), algo que nos puede dar bastante juego en entornos de prácticas.
Instalación y primeros pasos
Para instalarlo en Ubuntu, simplemente ejecutamos desde la terminal el siguiente comando:
# apt install zfsutils-linux
y se instalará directamente desde los repositorios de nuestra distribución.
Una vez instalado ya podemos empezar a utilizarlo. Lo primero que tendremos que hacer es crear un pool nuevo a partir de VDEV. Para realizar las pruebas podemos utilizar discos duros, pendrives o ficheros. En mi caso voy a utilizar ficheros. Es necesario que los ficheros existan de antemano, de modo que voy a crear varios con el comando dd.
# for i in {1..4}; do dd if=/dev/zero of=fichero$i bs=1G count=4 ; done
El comando anterior crea 4 ficheros de 4GB cada uno de ellos. Ahora vamos a crear nuestro primer pool de datos:
En este ejemplo almacen es el nombre del pool y cada uno de los ficheros es un VDEV, hay que indicar la ruta absoluta de los ficheros. Lo que ha creado este comando en un RAID 0 con los tres VDEV, ya que este es el comportamiento por defecto. Además habrá montado el pool como un dataset denominado /almacen en nuestro sistema de ficheros raíz. En el caso de utilizar discos físicos en vez de ficheros, tendríamos que haber puesto los nombres de dichos discos, por ejemplo:
# zpool create almacen /dev/sdc /dev/sdd /dev/sde
Si queremos que lo monte en otro directorio, lo podemos especificar con el parámetro -m, por ejemplo, -m /mnt/alamacen.
Con el siguiente comando podremos ver los pools disponibles:
# for i in {1..4}; do dd if=/dev/zero of=fichero$i bs=1G count=4 ; done
El comando anterior crea 4 ficheros de 4GB cada uno de ellos. Ahora vamos a crear nuestro primer pool de datos:
# zpool create almacen /home/usuario/fichero1 /home/usuario/fichero2 /home/usuario/fichero3
En este ejemplo almacen es el nombre del pool y cada uno de los ficheros es un VDEV, hay que indicar la ruta absoluta de los ficheros. Lo que ha creado este comando en un RAID 0 con los tres VDEV, ya que este es el comportamiento por defecto. Además habrá montado el pool como un dataset denominado /almacen en nuestro sistema de ficheros raíz. En el caso de utilizar discos físicos en vez de ficheros, tendríamos que haber puesto los nombres de dichos discos, por ejemplo:
# zpool create almacen /dev/sdc /dev/sdd /dev/sde
Si queremos que lo monte en otro directorio, lo podemos especificar con el parámetro -m, por ejemplo, -m /mnt/alamacen.
Con el siguiente comando podremos ver los pools disponibles:
# zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
almacen 11,9G 76K 11,9G - 0% 0% 1.00x ONLINE -
y para ver el estado de un pool utilizaremos:
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
/home/usuario/fichero3 ONLINE 0 0 0
errors: No known data errors
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
/home/usuario/fichero3 ONLINE 0 0 0
errors: No known data errors
Para destruir el pool podemos utilizar el siguiente comando:
# zpool destroy almacen
Hay que tener en cuenta que todos los datos se perderán.
Para crear un RAID 1 utilizaremos el siguiente comando:
Su estado será:
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
errors: No known data errors
Ahora mirror-0 es el VDEV, por lo tanto, si queremos crear un RAID 10 podemos crear un par de VDEV de tipo mirror y automáticamente formará con estos RAID 1 un RAID 0, ya que es el comportamiento por defecto. Para ello, primero destruimos el pool anterior y a continuación creamos nuestro RAID 10:
# zpool destroy almacen
# zpool destroy almacen
Hay que tener en cuenta que todos los datos se perderán.
Para crear un RAID 1 utilizaremos el siguiente comando:
# zpool create almacen mirror /home/usuario/fichero1 /home/usuario/fichero2
Su estado será:
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
errors: No known data errors
# zpool destroy almacen
# zpool create almacen mirror /home/usuario/fichero1 /home/usuario/fichero2 mirror /home/usuario/fichero3 /home/usuario/fichero4
Si ahora comprobamos el estado de nuestro pool:
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
/home/usuario/fichero3 ONLINE 0 0 0
/home/usuario/fichero4 ONLINE 0 0 0
errors: No known data errors
# zpool status almacen
pool: almacen
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
almacen ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/home/usuario/fichero1 ONLINE 0 0 0
/home/usuario/fichero2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
/home/usuario/fichero3 ONLINE 0 0 0
/home/usuario/fichero4 ONLINE 0 0 0
errors: No known data errors
Podemos ver que hay dos VDEV, mirror-0 y mirror-1.
RAIDZ
A la hora de crear un RAID, podemos utilizar los tres tipos anteriores (RAID 0, RAID 1 y RAID 10) o bien utilizar el formato RAIDZ que aporta este sistema de ficheros. RAIDZ es una variante de RAID 5 que lo optimiza y elimina el denominado "agujero de escritura". Estos sistemas RAID almacenan los datos en varios discos y además va almacenando la paridad de los mismos para poder reconstruirlos en el caso de que un disco falle. ZFS cuenta con tres tipos de RAIDZ: raidz1 o raidz, raidz2 y raidz3. La diferencia entre ellos es la cantidad de bloques de paridad que almacena, que viene indicado por el número correspondiente. Con raidz1 se admite que falle un disco, con raidz2 podrían fallar dos discos y con raidz3 podrían fallar hasta tres discos y el sistema se podría reconstruir. Si se tienen discos asignados al pool como spare, cuando falle uno, el sistema automáticamente incorporará este disco de repuesto al RAID y lo reconstruirá.Para crear un RAIDZ lo indicaremos en el comando de la siguiente forma:
# zpool create almacen raidz /home/jramirez/zfs/fichero1 /home/jramirez/zfs/fichero2 /home/jramirez/zfs/fichero3
Podemos sustituir raidz por raidz2 o raidz3 según la opción que necesitemos.
Datasets
En el momento de ejecutar los comandos anteriores para crear un pool nuevo, el sistema crea de forma automática un dataset con el pool completo como se ha visto anteriormente. Pero podemos crear nosotros nuestros propios datasets según nuestras necesidades. Para ello podemos utilizar el siguiente comando:# zfs create almacen/usuarios
Tras su ejecución el sistema creará un dataset nuevo y lo montará de forma automática en la raíz de nuestro sistema de ficheros.
Para visualizarlo utilizaremos:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
almacen 102K 7,70G 24,0K /almacen
almacen/usuarios 24,0K 7,70G 24,0K /almacen/usuarios
Lo podemos desmontar con:
# umount /almacen/usuarios
# umount /almacen/usuarios
Y para volver a montarlo utilizaremos:
# zfs mount almacen/usuarios
Si queremos un punto de montaje diferente, se lo podemos indicar con:
# zfs set mountpoint=/mnt/usuarios almacen/usuarios
Y para renombrarlos, podemos utilizar:
# zfs rename almacen/usuarios almacen/empleados
Y esto es todo por ahora. En un próximo artículo veremos como podemos recuperar un RAID ante algún fallo o como mover los discos a otro sistema.
@josrrp
# zfs mount almacen/usuarios
Si queremos un punto de montaje diferente, se lo podemos indicar con:
# zfs set mountpoint=/mnt/usuarios almacen/usuarios
Y para renombrarlos, podemos utilizar:
# zfs rename almacen/usuarios almacen/empleados
Y esto es todo por ahora. En un próximo artículo veremos como podemos recuperar un RAID ante algún fallo o como mover los discos a otro sistema.
@josrrp
Comentarios
Publicar un comentario