Ir al contenido principal

ZFS, Primera parte

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:
  1. disk: Es el sistema por defecto y representa discos físicos.
  2. file: Ficheros cuyo espacio se hayan asignado de antemano.
  3. mirror: RAID 1 estándar.
  4. raidz1/2/3: Niveles RAID, no estándar, basados en paridad distribuida.
  5. spare: Discos duros marcados como "de reserva" para utilizarse en un RAID.
  6. cache: Sistema para utilizarse como caché  de disco de nivel 2.
  7. log: Sistema de registro independiente llamado "ZFS Intent Log" o ZIL.
Hay que tener en cuenta que cada VDEV individual que se añada al pool de almacenamiento será utilizado para distribuir dinámicamente los stripes de datos que se vayan añadiendo, es decir, se formará un RAID 0 con ellos.

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:

# 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

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:

# 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

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 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

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

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


Comentarios

Entradas populares de este blog

Instalando Moodle con Docker

En este blog ya hemos hablado en varios artículos sobre la tecnología de contenedores, pero hasta ahora nos habíamos centrado en LXD . En este artículo vamos a explicar cómo podemos instalar Moodle en menos de un minuto (dependiendo de la velocidad de descarga que se tenga, se puede alargar un poco más) usando contenedores. Acerca de Moodle No voy a explicar que es Moodle ni como instalarlo desde cero, para eso existe en Internet multitud de tutoriales. Lo que sí quiero comentar es que para instalar Moodle hace falta un servidor web con PHP . Además requiere que PHP tenga instalado una serie de componentes adicionales. Por otro lado, necesitamos tener instalado en el servidor un sistema de gestión de bases de datos relacional, ya que Moodle almacena la información en él. Normalmente se utiliza MySQL , MariaDB o PostgreSQL . También debemos crear una base de datos específica para Moodle con su respectivo usuario. Durante la instalación Moodle creará las tablas necesari

Analizando el protocolo HTTP

El objetivo de este artículo es el de explicar de forma práctica el funcionamiento del protocolo HTTP y entender el intercambio de datos que se realiza entre los servidores y los clientes web. Por otro lado, cubre la necesidad de tener un texto en español que sirva de referencia a mis alumnos de Servicios en Red  a la hora de realizar la práctica de clase  HTTP-1 . La idea es ver de forma práctica el funcionamiento interno del protocolo HTTP . Para ello, vamos a utilizar un par de herramientas de la línea de comandos de Linux ( telnet y netcat ), con las que vamos a simular el comportamiento tanto del navegador como del servidor web. HTTP es un protocolo de la capa de aplicación, y como muchos otros protocolos de esta capa, está basado en texto. De hecho, los comandos que envía el navegador al servidor y sus respuestas se pueden leer perfectamente en inglés. Por defecto, HTTP utiliza el puerto 80 TCP y HTTPS  el puerto 443 TCP. Los ejemplos que vamos a ilustrar serán