Esta pagina se ve mejor con JavaScript habilitado

WebZFS

 ·  🎃 kr0m

WebZFS es un sistema con interfaz web con la que podremos administrar sistemas de ficheros ZFS, este software es compatible tanto el FreeBSD, Linux como NetBSD. La interfaz web facilita mucho la administración de las operaciones mas frecuentes en sistemas ZFS pero lo que realmente hace especial este software es la posibilidad de administrar políticas de snapshots y replicación en sistemas remotos, pudiendo de este modo tener un sistema de respaldo que además es PITR.

El manual consta de las siguientes secciones:


Instalación

Clonamos el repositorio de WebZFS:

git clone https://github.com/webzfs/webzfs.git
cd webzfs

Instalamos mediante el script de la plataforma que corresponda.
NOTA: Hará algunas preguntas sobre debe arrancar el servicio en el boot del sistema, responderemos según convenga.

pkg install rsync bash
bash install_freebsd.sh
bash install_linux.sh

WebZFS se podría bindear a las IPs de las que disponga el sistema, pero como es un software que correrá como root, es preferible dejarlo bindeado a la loopback y crear un túnel SSH para su acceso:

ssh -L 26619:127.0.0.1:26619 SERVER_IP

Ahora tan solo debemos acceder mediante el túnel:
http://127.0.0.1:26619


System Dashboard

En esta sección simplemente muestra información general acerca del sistema, estado de los pools ZFS y consumo de RAM:


Pools

Desde esta sección podremos gestionar los pools ZFS, a continuación las acciones que podemos llevar a cabo.

Import Pool:

Importar pools, estos suelen ser discos/particiones en ZFS que se crearon desde un sistema externo o pools que fueron previamente exportados para realizar algún tipo de mantenimiento sobre estos.

Create Pool:

Crear pools nuevos. En mi caso voy a crear un Mirror con dos discos de distinto tamaño, esto dará error a no ser que maquemos la opción Force creation if devices in use, mis dispositivos no están en uso pero como esta opción añade el parámetro -f al comando ZFS, me vale.

Al crear el Mirror con dos discos de distinto tamaño, podemos ver que WebZFS está bugeado ya que está dando por supuesto que los dos discos son del mismo tamaño, calculando mal el espacio final aunque el pool final sea del tamaño correcto.

Podemos verlo claramente en estas capturas:

Zpool creation Zpool list

View details:

Desde esta sección podemos ver los detalles del pool como el espacio consumido, errores, VDevs que lo conforman, puntos de montaje y estado de los dispositivos físicos:

También podremos realizar ciertas acciones sobre el pool, como iniciar y parar un Scrub, realizar un checkpoint(snapshot a nivel de pool), exportar el pool, reservar espacio o cambiar el punto de montaje:

Si le damos a Manage VDevs nos permitirá modificar la composición física de los discos que forman el pool, esta operación es realmente delicada y WebZFS nos advierte de ello:

Antes de nada debemos detectar los discos del sistema para poder acceder a todas las opciones:

Ahora todas las opciones deberían de aparecer habilitadas:

Desde la sección Pool Topology podremos deshabilitar, cambiar y eliminar discos del VDev:

Desde la sección Attach Device podremos añadir discos, tan solo debemos seleccionar el disco desde el que espejar y el disco nuevo:

Desde la sección Replace Device podremos reemplazar discos, tan solo debemos seleccionar el disco que queremos reemplazar y el disco nuevo:

De igual manera como podíamos hacer en la sección Pool Topology desde Device Operations podremos cambiar y eliminar discos del VDev, pero además rehabilitarlos:

También podemos añadir discos para funciones específicas como Hot Spare, L2ARC, SLOG, Special Metadata VDev o Dedup VDev. Justo al lado tenemos el recuadro para eliminar este tipo de discos:

NOTA: Podemos apreciar en esta última captura de pantalla otro bug, en el botón podemos ver que pone: onclick=“showConfirm(‘confirm-add-vdev’)"> + Add Auxiliary VDev

Properties:

En properties podremos ver y modificar todas las propiedades de un Pool ZFS:

History:

La sección History nos mostrará el histórico del pool:

Start Scrub:

Si deseamos realizar un Scrub también podremos hacerlo:

Export Pool:

También podremos exportar pools:


Datasets

Desde esta sección podremos visualizar o añadir datasets a los Pools:

Details:

Desde Details podremos visualizar los datos básicos del dataset:

Además de gestionar sus propiedades:

Renombrar el dataset:
Hay que tener en cuenta que debemos indicar el path completo, POOL_NAME/NEW_DATASET_NAME y que solo soporta el renombrado de datasets de segundo orden, por ejemplo TestPool -> TestPool2 no dejaría, pero TestPool/00 -> TestPool/01, si.

O realizar ciertas acciones sobre el dataset.

Snapshot:

Crear un snapshot del dataset es tan sencillo como darle al botón Snapshot y asignarle un nombre:

Create Child:

Es lo mismo que crear un dataset nuevo solo que permite indicar el path sin límite de profundidad.

Mount:

Como su nombre indica, nos permite montar el dataset:

Umount:

Como su nombre indica, nos permite desmontar el dataset:

Peek:

Mediante Peek podremos navegar de forma gráfica por el contenido del dataset:

Properties:

Este botón hace exactamente lo mismo que el botón Manage Properties de arriba en esa misma ventana.

Rename:

Este botón hace exactamente lo mismo que el botón Rename de arriba en esa misma ventana.

Promote:

Este último botón solo funciona si se trata de un dataset que se originó clonando un snapshot, a modo de ejemplo he generado un clon para poder realizar la prueba.

Debemos tener en cuenta que los clones comparten la “raíz” con el snapshot del que fueron clonados ocupando solo el espacio de los cambios realizados en el clon, además el padre no podrá ser eliminado mientras existan clones que dependan de este. Solo cuando promocionamos el clon, este heredará los snapshots del padre y el padre se convertirá en hijo del dataset promocionado, en resumen se invertirán los roles entre datasets.

Properties:

Podemos gestionar las propiedades del dataset:

Mount Dataset:

Como su nombre indica, nos permite montar el dataset:

Umount Dataset:

Como su nombre indica, nos permite desmontar el dataset:

Rename Dataset:

Hay que tener en cuenta que debemos indicar el path completo, POOL_NAME/NEW_DATASET_NAME y que solo soporta el renombrado de datasets de segundo orden, por ejemplo TestPool -> TestPool2 no dejaría, pero TestPool/00 -> TestPool/01, si.


Snapshots

Entramos en uno de los apartados mas interesantes de ZFS, los snapshots.

Desde esta sección podremos crear snapshots:

También nos permite comparar snapshots:

Y programar snapshots automáticos mediante Sanoid :

Primero debemos definir una política de snapshots o utilizar alguna de las existentes:

New policy Already created policies

Procedemos a crear una policy nueva a modo de ejemplo, con snapshots automáticos de la última hora cada 15m, luego dos días de snapshots cada hora y un mes de snapshots cada día.

Dejamos la opción habilitada de Auto-Snapshot y Auto-Prune porque queremos que Sanoid se encargue tanto de realizar los snapshots como de hacer limpieza de estos. También podría darse el caso en que los snapshots o la limpieza se hagan mediante un proceso externo y Sanoid solo encargarse de alguna de las dos acciones.

Ahora ya podemos añadir un dataset a snapshotear:

Podemos editar o eliminar el dataset desde la interfaz:

Además de crear un snapshot en ese mismo momento, prunear snapshots existentes o validar la configuración:

La integración de WebZFS con Sanoid debe estar bugeado, genera la configuración correctamente pero no deja programada la ejecución para que genere/prunee los snapshots.

Hay que crontabearla manualmente:

crontab -e
# SANOID
* * * * * /usr/local/bin/sanoid --cron >/dev/null 2>&1

Podemos ver como se han generado los snapshots automáticamente:

Siguiendo en el menú principal, podemos realizar varias acciones sobre los snapshots.

View Details

Podemos ver los detalles y las propiedades del snapshot además de poder realizar operaciones sobre este:

Desde aquí podremos clonar el snapshot para crear un dataset a partir de este, el clon será dependiente del padre y solo ocupará espacio adicional a medida que hagamos cambios en los datos compartidos con el padre:

También podemos renombrar el snapshot:

Holdear el snapshot, opción que nos permitirá proteger el snapshot de borrados accidentales:

Si intentamos eliminar el snapshot mientras tengamos un Hold la interfaz simplemente fallará en silencio :

Pero podemos ver en los logs:

/opt/webzfs/.config/webzfs/logs/zfs_operations.log

2026-09-13 11:29:23 [ERROR] user=kr0m operation=destroy_snapshot status=FAILED snapshot=TestPool@test error="Failed to destroy snapshot: cannot destroy snapshot TestPool@test: it's being held. Run 'zfs holds -r TestPool@test' to see holders.

NOTA: El botón Release Hold está bugeado, una vez holdeado no podremos desholdearlo.

Entre otras opciones que ofrece la interfaz tenemos.

  • Clone to Dataset: Este botón es exactamente el mismo que el Clone de mas arriba en esta misma página.

  • Rollback Dataset: Nos permite retroceder atrás al estado de un snapshot en concreto, pero debemos tener en cuenta que es un proceso destructivo e irreversible, si existen snapshots intermedios estos serán destruidos también.

TestPool tiene estos tres snapshots y revertimos a 111:

Si no habilitamos la opción Force rollback - Destroy more recent snapshots la interfaz fallará en silencio pero en los logs veremos:

/opt/webzfs/.config/webzfs/logs/zfs_operations.log

2026-09-13 11:41:59 [ERROR] user=kr0m operation=rollback_snapshot status=FAILED snapshot=TestPool@111 force=False error="Failed to rollback snapshot: cannot rollback to 'TestPool@111': more recent snapshots or bookmarks exist
  • Rename Snapshot: Este botón es exactamente el mismo que el Rename de mas arriba en esta misma página.

  • Compare Changes: Este botón es exactamente el mismo que el Compare Snapshots de las sección Snapshots pero con el campo First Snapshot ya preseleccionado.

  • Create Bookmark: Los bookmarks ZFS sirven principalmente para permitir envíos incrementales (zfs send) sin tener que conservar el snapshot completo en el origen, ahorrando espacio.

El botón Remove Bookmark está bugeado, una vez bookmarkeado no podremos desbookmarkearlo. Tendremos que acceder al menú principal de los snapshots y hacerlo desde la lista que muestra:

Bugged button Working button
  • Destroy Snapshot: Elimina el snapshot.

El resto de opciones que aparecen en la lista de snapshots tienen exactamente las mismas funciones que los botones dentro de cada snapshot, Create Bookmark, Clone, Rollback, Rename, Destroy:


Replication

Otra sección muy interesante, mediante Syncoid podremos sincronizar los snapshots ZFS a un sistema remoto, una vez sincronizado el primer snapshot solo se sincronizarán las diferencias entre estos lo que hará la sincronización mucho mas rápida que un Rsync tradicional.

Antes de nada debemos de dar de alta un servidor(en mi caso 192.168.69.5) accesible por SSH y proporcionar el password de root, este password solo se utilizará una vez para autorizar la key SSH que utilizará Syncoid posteriormente. Lo recomendable es cambiar el password, realizar la configuración y cuando la key esté autorizada revertir el password.

Para ello accedemos a la sección Utilities -> SSH Connections:

En el servidor SSH se ha permitido el acceso por root, para que pueda gestinar ZFS sin problemas:

PermitRootLogin yes

Una vez hecho esto ya podemos configurar Syncoid.

Desde esta sección podemos ejecutar ZFS Send/Receives manualmente, tan solo debemos comprobar la conectividad antes y confirmar que el comando a ejecutar sea correcto:

En el servidor remoto podemos ver que el snapshot test se ha creado bajo el dataset TestPool:

ColdStar # ~> zfs list zroot/TestPool
NAME             USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool   112K   382G   112K  /zroot/TestPool

ColdStar # ~> zfs list -t snapshot
NAME                  USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool@test     0B      -   112K  -

La siguiente opción Schedule Syncoid Job nos permite programar trabajos de Syncoid para que los snapshots se vayan replicando de forma automática.

Debemos indicar el origen, el destino y cada cuanto se debe realizar la sincronización:

Aquí debemos hacer una distinción según hayamos configurado una política de auto-snapshoting por Sanoid o no:

  • Con auto-snapshoting(Elimino el dataset TestPool en destino antes de proceder): Podemos dejar que Syncoid genere un snapshot cada vez que se ejecute el job.
    En origen creará un snapshot nuevo y eliminará el viejo en cada ejecución y en destino recibirá el snapshot nuevo y eliminará el viejo. Quedando de este modo el último snapshot en ambas partes.

Podemos ver en origen que se ha generado un snapshot automáticamente:

MightyMax # ~> zfs list TestPool -t snapshot
NAME                                                                      USED  AVAIL  REFER  MOUNTPOINT
TestPool@syncoid_MightyMax.alfaexploit.com_2026-09-14:16:30:01-GMT02:00     0B      -   112K  -

Y en destino está recibiendo los datos:

ColdStar # ~> zfs list zroot/TestPool -t snapshot
NAME                                                                            USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool@syncoid_MightyMax.alfaexploit.com_2026-09-14:16:30:01-GMT02:00     0B      -   112K  -

ColdStar # ~> zfs list zroot/TestPool
NAME             USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool   112K   382G   112K  /zroot/TestPool
  • Sin auto-snapshoting(Elimino el dataset TestPool en destino antes de proceder): Por otro lado es recomendable configurar una política de auto-snapshoting desde Sanoid y dejar que Syncoid se limite a copiar los datos sin generar snapshots, de esta manera podemos tener un histórico de snapshots en ambas partes.

Política de snapshoting de Sanoid utilizando la política de test generada anteriormente en la sección Snapshots :

Replicación de Syncoid, en esta ocasión deshabilitamos los sync snapshots ya que lo está haciendo Sanoid:

Podemos ver en origen que se ha generado un snapshot automáticamente:

MightyMax # ~> zfs list TestPool -t snapshot
NAME                                               USED  AVAIL  REFER  MOUNTPOINT
TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_09:10:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_09:15:00_frequently     0B      -   112K  -

Y en destino está recibiendo los datos:

ColdStar # ~> zfs list zroot/TestPool -t snapshot
NAME                                                     USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:10:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:15:00_frequently     0B      -   112K  -

ColdStar # ~> zfs list zroot/TestPool
NAME             USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool   112K   382G   112K  /zroot/TestPool

Pero esta estrategia de backups presenta un inconveniente y es que no hay nada que prunee los snapshots en destino por lo tanto se irán acumulando ocupando finalmente todo el espacio en disco. En origen no ocurre esto ya que Sanoid solo retendrá los snapshots definidos en la política vinculada con el job en cuestión.

MightyMax # ~> zfs list TestPool -t snapshot
NAME                                               USED  AVAIL  REFER  MOUNTPOINT
TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_10:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_10:00:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_10:15:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_10:30:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_10:45:00_frequently     0B      -   112K  -
ColdStar # ~> zfs list zroot/TestPool -t snapshot
NAME                                                     USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:10:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:15:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:30:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:45:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:00:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:15:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:30:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:45:00_frequently     0B      -   112K  -

Para evitar esto podemos instalar WebZFS también en destino y configurar un Sanoid job con la misma retención que en origen(o distinta según convenga) pero en Advanced Options de la política dejar:

  • Auto-Snapshot: No - Manual only
  • Auto-Prune: Yes - Automatically prune old snapshots

Eliminamos el pool en destino para evitar problemas y que resincronice con las políticas indicadas:

zfs destroy -r zroot/TestPool

Creamos la política de retención:

Y luego el job asociado a dicha política:

Como ya comentamos anteriormente en la sección Snapshots , la integración de WebZFS con Sanoid debe estar bugeado, genera la configuración correctamente pero no deja programada la ejecución para que genere/prunee los snapshots.

Hay que crontabearla manualmente:

crontab -e
* * * * * /usr/local/bin/sanoid --cron >/dev/null 2>&1

Como podemos observar ahora se conservan los mismos snapshots tanto en origen como en destino:

MightyMax # ~> zfs list TestPool -t snapshot
NAME                                               USED  AVAIL  REFER  MOUNTPOINT
TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_10:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_11:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_12:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_13:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_13:30:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_13:45:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_14:00:00_hourly         0B      -   112K  -
TestPool@autosnap_2026-09-15_14:00:00_frequently     0B      -   112K  -
TestPool@autosnap_2026-09-15_14:15:00_frequently     0B      -   112K  -
ColdStar # ~> zfs list zroot/TestPool -t snapshot
NAME                                                     USED  AVAIL  REFER  MOUNTPOINT
zroot/TestPool@autosnap_2026-09-15_09:10:00_daily          0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_09:10:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_10:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_11:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_12:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_13:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_13:30:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_13:45:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_14:00:00_hourly         0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_14:00:00_frequently     0B      -   112K  -
zroot/TestPool@autosnap_2026-09-15_14:15:00_frequently     0B      -   112K  -

La siguiente opción Syncoid simplemente nos permite visualizar los jobs programados y gestionar las conexiones SSH a equipos remotos:

Desde la lista de jobs podemos ejecutarlos manualmente, editarlo, deshabilitarlo o eliminarlo.

Y en la sección final tan solo tenemos dos opciones mas Native ZFS Send/Receive y Syncoid que hacen exactamente lo mismo que los botones de arriba en esa misma página ZFS Send/Receive y Schedule Syncoid Job.


Observability

Desde aquí podremos acceder a diferentes paneles de monitorización del estado de los sistemas de ficheros ZFS del equipo, algunos paneles ya los hemos visto anteriormente en este artículo ya que son los mismos.

ARC Hit Rate:

En este panel podremos ver datos relacionados con la caché en RAM de ZFS mas comunmente conocida como ARC: Adaptive Replacement Cache.

El primer botón que encontramos es Real-Time Stats que nos mostrará en tiempo real las estadísticas ZFS:

El resto del panel son información acerca del ARC:

  • ARC Size: Cantidad de RAM que está utilizando actualmente el ARC.
  • Hit Rate: Veces en las que se accede a RAM en vez de a disco.
  • Cache Hits: Número de veces en las que el dato estaba en RAM.
  • Cache Misses: Número de veces en las que el dato no estaba en RAM y se ha tenido que acceder al disco.
  • Cache Distribution (MRU vs MFU): ARC mantiene en RAM los datos que han sido utilizados recientemente y los que se utilizan con mayor frecuencia.
    • MRU (Most Recently Used): Número de accesos que han sido satisfechos desde la caché con datos pertenecientes a la lista de elementos utilizados recientemente.
    • MFU (Most Frequently Used): Número de accesos que han sido satisfechos desde la caché con datos pertenecientes a la lista de elementos utilizados con mayor frecuencia.
  • Access Type Breakdown: Desglose por tipo de acceso.
  • Demand (On-Request): Número de veces en la que los datos han sido solicitados por una acción en el sistema.
  • Prefetch (Predictive): Número de veces en la que los datos fueron precargados por el sistema de predicción y servidos al ser solicitados por una acción en el sistema.
  • Miss & Ghost Rates:
    • MISS RATE: Un miss ocurre cuando ZFS recibe una petición de lectura y el dato no está disponible en el ARC.
    • GHOST HITS/MISSES: Un ghost hit significa que ZFS recuerda que ese bloque estuvo anteriormente en el ARC, pero ya lo había expulsado cuando volvió a solicitarse
  • Miss Breakdown: Desglose por tipo de miss.
    • Cold misses: Número de accesos que han sido misses.
    • Ghost hits (near-misses): Número de accesos que han sido misses pero el dato ha estado en RAM anteriormente.
  • Ghost Hit Detail: Detalles de los ghost misses.
    • MFU ghost hits: Número de ghost hits accediendo a datos MFU.
    • MRU ghost hits: Número de ghost hits accediendo a datos MRU.
  • Detailed Statistics: Datos en crudo sobre los detalles de ARC.

Ghost Hit Rate:
Nos lleva a la sección ARC Hit Rate explicada al principio de esta misma sección .

Disk Health:
Nos permite realizar/programar un análisis del estado de los discos físicos del sistema:

Si lo programamos, veremos el siguiente panel:

Pool Scrub Status:
Esta sección nos permititrá programar Scrubs en los pools ZFS, ver la lista de programados, ejecutar de forma inmediata Scrubs que fueron ejecutados anteriormente y ver el estado de los scrubs actuales.

Añadimos un Scrub programado:

Visualizamos la lista de tareas programadas:

Dataset Space Usage:
Desde aquí podremos visualizar el espacio consumido por Dataset.

Module Parameters:
Podemos ver los parámetros pasados al módulo ZFS en caso de cargarlo como módulo, en mi caso no es posible.

ZFS Processes:
Podemos visualizar los procesos del sistema relacionados con ZFS.

System I/O Statistics:
Podemos visualizar estadísticas de acceso por disco.

Pool History:
Podemos visualizar el histórico de acciones realizadas por pool.

Pool Events:
Podemos visualizar el histórico de eventos por pool.

Pool I/O Stats:
Podemos visualizar estadísticas de acceso por pool.

Per-Dataset I/O Stats:
Podemos visualizar estadísticas de acceso por dataset.

Kernel Debug Log:
Permite buscar y filtrar mensajes de log de debug relacionados con ZFS.

System Log(ZFS Filtered):
Permite buscar y filtrar mensajes de log relacionados con ZFS.

System Log(Full Log):
Permite buscar y filtrar mensajes de log.

Search Logs:
Buscador de logs del sistema que busca en todas las fuentes de log disponibles.

También nos mostrará al final del panel el histórico reciente de los Pools:


Utilities

Desde esta sección podremos acceder a un gran abanico de paneles.

Scheduling:
Nos muestra el panel de tareas programadas, ya sean Scrubs, SMART Tests, Replication Jobs. Pero no Sanoid Schedules(Snapshoting policies).

También presenta un botón que se asegura de que las tareas estén programadas en el sistema por el medio correspondiente, aunque en mi caso no me ha hecho falta utilizarlo.

SMART Monitoring:
Desde aquí podremos configurar SMART, reinicar el servicio y modificar parámetros de configuración(en mi caso no utilizo SMART ya que confío en la monitorización nativa de discos de ZFS).

Programar SMART tests, en realidad nos lleva al Scheduling genérico que ya hemos visto anteriormente en este artículo.

También podemos bajarnos la info SMART de los discos.

O correr tests tanto cortos como largos en todos los discos, pero parecen estar bugeados ambos botones, no aparece ningún error pero no corre ningún test.

También podemos ver los detalles del disco.

Todos los botones Attributes, Health, Tests, Temperature, Error Log, Download son los mismos que aparecen en la lista de discos, así que dichas secciones serán analizadas mas adelante.

Los botones Disable SMART y Run Self-Test también parecen estar bugeados, no hacen nada.

La siguiente opción nos permite visualizar los atributos SMART.

El estado de salud.

También podemos acceder al menú para correr tests.

NOTA: Ambos botones parecen estar bugeados.

También podemos visualizar la temperatura del disco.

Visualizar los logs de error.

O descargar datos SMART.

Scrub Status:
Esta sección es exactamente la misma que encontramos en Observability -> Pool Scrub Status descrita anteriormente en este mismo artículo.

SSH Connections:
Desde aquí podremo administrar las conexiones SSH a sistemas remotos. Su funcionamiento ya fué explicado en la sección Replication de este mismo artículo.

Health Analysis:
Su funcionamiento ya fué explicado en la sección Observability -> Disk Health de este mismo artículo.

Support Bundle:
Esta sección colecta información útil de diagnóstico de nuestro sistema en caso de necesitar asistencia técnica.

System Services:
Nos permite visualizar los servicios del sistema y ver el PID con el que corren.

Shell:
Nos permite ejecutar comandos del sistema desde la inetrfaz web, mucho cuidado con lo que ejecutamos ya que lo hará mediante el usuario con el que esté corriendo el proceso.

También nos permite navegar por el sistema de ficheros desde dos botones que hacen exactamente lo mismo:

Text Editor:
Nos permite editar ficheros del sistema. Este editor presenta una peculiaridad y es que no se pueden hacer dos guardados consecutivos sin antes darle a Load File entre guardados.

File Browser:
Este explorador de ficheros ya lo hemos visto en el apartado Utilities -> Shell

Audit Logs:
Desde esta sección podremos ver los logs relacionados con la autenticación, las operaciones ZFS y los accesos a ficheros desde el File Browser.

  • Authenticaction.

  • ZFS Operations.

  • File Access.

WebZFS Settings:
Desde esta sección podremos configurar aspectos como el tema, el estilo de los recuadros de la interfaz o el timeout de la sesión. Además nos proporcionará acceso a un sistema de backup/restore de la configuración:


Fleet View:

Desde aquí podremos visualizar el estado de los pools ZFS en servidores remotos, tan solo debemos añadir alguno de los servidores previamente añadidos mediante Utilities -> SSH Connections.

Si deseamos eliminar un servidor existente tan solo debemos clickar en Manage Servers.


Replicación Bastille:

En mi caso voy a utilizar WebZFS para generar snapshots mediante Sanoid y los replicaré en un servidor remoto mediante Syncoid, estos datasets corresponden a unas jails Bastille que conforman todos los servicios en AlfaExploit.

De este modo en caso de fallo en el servidor principal tan solo debo arrancar las jails en el servidor de respaldo y todos los servicios seguirán funcionando sin problemas.

Creamos un Syncoid job que se llevará el dataset zroot/bastille al servidor remoto ColdStar:

Los datasets en origen/destino quedarán así:

MightyMax # ~> zfs list zroot/bastille
NAME             USED  AVAIL  REFER  MOUNTPOINT
zroot/bastille   118G   734G   112K  /usr/local/bastille

ColdStar # ~> zfs list zroot/bastille
NAME             USED  AVAIL  REFER  MOUNTPOINT
zroot/bastille   118G   264G   112K  /zroot/bastille

Ahora configuramos Sanoid para que siga la política de snapshots que necesitemos.
En mi caso conservaré:

  • 4h horas pudiendo restaurar con una granuladidad de 15m.
  • 2 días pudiendo restaurar con una granularidad de 1h.
  • 1 mes con una granularidad de 1 día.

Quedando así:

Y añadimos el dataset en el que debe realizar los snapshots:

Como ya se ha mencionado anteriormente en este mismo artículo, la integración de WebZFS con Sanoid debe estar bugeado, genera la configuración correctamente pero no deja programada la ejecución para que genere/prunee los snapshots.

Hay que crontabearla manualmente:

crontab -e
# SANOID
* * * * * /usr/local/bin/sanoid --cron >/dev/null 2>&1

En destino configuramos Sanoid solo para que prunee los snapshots y no se acumulen como ya se explicó que ocurre en este mismo artículo:

Como ya se ha mencionado anteriormente en este mismo artículo, la integración de WebZFS con Sanoid debe estar bugeado, genera la configuración correctamente pero no deja programada la ejecución para que genere/prunee los snapshots.

Hay que crontabearla manualmente:

crontab -e
# SANOID
* * * * * /usr/local/bin/sanoid --cron >/dev/null 2>&1

Finalmente la sincronización en origen/destino quedará así:

MightyMax # ~> zfs list -t snapshot|grep autosnap|wc -l
     891

ColdStar # ~> zfs list -t snapshot|grep autosnap|wc -l
     891

Instalamos Bastille en el servidor de backup tal y como se indica en este artículo anterior .

pkg install vim git-lite bash ca_root_nss
pkg install bastille

vi /usr/local/etc/bastille/bastille.conf
## ZFS options
bastille_zfs_enable="YES"    ## default: ""
bastille_zfs_zpool="zroot"   ## default: ""

Para pasar al servidor de backup debemos seguir los siguientes pasos:

  • Paramos WebZFS en origen para que Syncoid deje de ejecutarse:
service webzfs stop
sysrc webzfs_enable="NO"
  • Comentamos crontabs Sanoid/Syncoid en origen para que deje de generar snapshots y sincronizar con el servidor remoto:
crontab -e
# SANOID
#* * * * * /usr/local/bin/sanoid --cron >/dev/null 2>&1
# BEGIN WEBZFS SCHEDULED TASKS - do not edit this block by hand
#*/15 * * * * cd /opt/webzfs && HOME=/opt/webzfs /opt/webzfs/.venv/bin/python -m services.task_runner --task-type syncoid --task-id 11 >> /opt/webzfs/webzfs_tasks.log 2>&1
# END WEBZFS SCHEDULED TASKS
  • En el servidor destino los puntos de montaje de los datasets son incorrectos(son los que pone ZFS por defecto):
zfs set mountpoint=/usr/local/bastille zroot/bastille
zfs set mountpoint=/var/log/bastille zroot/bastille/logs
  • En el servidor destino la interfaz de red tiene otro nombre así que hacemos el cambio en la configuración de las jails:
grep interface /usr/local/bastille/jails/*/jail.conf
sed -i '' 's/nfe0/vtnet0/g' /usr/local/bastille/jails/*/jail.conf
grep interface /usr/local/bastille/jails/*/jail.conf
  • Paramos Bastille en origen:
bastille stop all
  • Arrancamos Bastille en destino:
bastille start all

Si queremos revertir y arrancar las jails de nuevo en el sistema original tenemos dos opciones.

Si tenemos datos a preservar mientras las jails están corriendo en ColdStar.

  • Configurar toda la replicación pero a la inversa: ColdStar -> MightyMax.
  • Parar las jails en ColdStar y arrancarlas en MightyMax.
  • Configurarlo todo de nuevo para que sincronice: MightyMax -> ColdStar.

Si no tenemos datos a preservar mientras las jails están corriendo en ColdStar.

  • Parar las jails en ColdStar y arrancarlas en MightyMax.
  • Arrancar WebZFS y rehabilitar Crones en MightyMax.

Monitorización:

Sanoid permite monitorizar el estado de los datasets:

sanoid --monitor-snapshots
OK: all monitored datasets (zroot/bastille, zroot/bastille/backups, zroot/bastille/cache, zroot/bastille/cache/13.1-RELEASE, zroot/bastille/cache/13.2-RELEASE, zroot/bastille/cache/14.2-RELEASE, zroot/bastille/cache/14.3-RELEASE, zroot/bastille/cache/15.1-RELEASE, zroot/bastille/jails, zroot/bastille/jails/Atlas, zroot/bastille/jails/Atlas/root, zroot/bastille/jails/DataDyne, zroot/bastille/jails/DataDyne/root, zroot/bastille/jails/HellStorm, zroot/bastille/jails/HellStorm/root, zroot/bastille/jails/MetaCortex, zroot/bastille/jails/MetaCortex/root, zroot/bastille/jails/PacketRadio, zroot/bastille/jails/PacketRadio/root, zroot/bastille/jails/RECLog, zroot/bastille/jails/RECLog/root, zroot/bastille/jails/RedbullTank, zroot/bastille/jails/RedbullTank/root, zroot/bastille/jails/RosettaStone, zroot/bastille/jails/RosettaStone/root, zroot/bastille/jails/TimeGuard, zroot/bastille/jails/TimeGuard/root, zroot/bastille/logs, zroot/bastille/releases, zroot/bastille/releases/14.2-RELEASE, zroot/bastille/releases/14.3-RELEASE, zroot/bastille/releases/15.1-RELEASE, zroot/bastille/templates) have fresh snapshots

Aprovechando esto vamos a crontabear tanto en origen como en destino un script que compruebe el estado y avise vía Telegram en caso de fallo:

vi /root/.scripts/monitor-sanoid.sh
#!/usr/bin/env bash

#
# monitor-sanoid.sh
#
# Monitor Sanoid snapshots and send Telegram alerts on failure.
#

TELEGRAM_BOT_TOKEN="XXXXX"
TELEGRAM_CHAT_ID="YYYY"

STATE_FILE="/var/run/sanoid-monitor.state"

sendTelegram() {
    curl -fsS -X POST \
        "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
        -d "chat_id=${TELEGRAM_CHAT_ID}" \
        --data-urlencode "text=$1" \
        >/dev/null
}

OUTPUT=$(sanoid --monitor-snapshots 2>&1)
RET=$?

if [ "$RET" -ne 0 ]; then

    # Send an alert only on the first failure
    if [ ! -f "$STATE_FILE" ] || [ "$(cat "$STATE_FILE")" != "FAILED" ]; then
        sendTelegram "🚨 SANOID ALERT on $(hostname)

Snapshot monitoring has FAILED.

$OUTPUT"

        echo "FAILED" > "$STATE_FILE"
    fi

else

    # Send a recovery notification after a previous failure
    if [ -f "$STATE_FILE" ] && [ "$(cat "$STATE_FILE")" = "FAILED" ]; then
        sendTelegram "✅ SANOID RECOVERY on $(hostname)

Snapshot monitoring has recovered and is now OK.

$OUTPUT"
    fi

    echo "OK" > "$STATE_FILE"
fi

exit "$RET"

Le asignamos los permisos necesarios:

chmod 700 /root/.scripts/monitor-sanoid.sh

Lo ejecutamos a mano en ambos servidores:

/root/.scripts/monitor-sanoid.sh

Si todo ha ido bien, lo crontabeamos:

crontab -e
*/5 * * * * /root/.scripts/monitor-sanoid.sh

Troubleshooting:

Existen algunos logs que pueden arrojar luz en ciertos momentos en los que WebZFS falla sin mostrar avisos en la interfaz web:

tail -f /opt/webzfs/.config/webzfs/logs/*.log
tail -f /opt/webzfs/webzfs_tasks.log
tail -f /opt/webzfs/gunicorn.log