En el artículo Jails en FreeBSD presenté un esquema de jails a partir del cual sería posible actualizar el sistema base de todos los Jails en una única operación. Este se basaba en separar el filesystem de los jails en dos partes: una compartida de sólo lectura (sistema base) y otra privada de lectura/escritura (configuraciones, paquetes y directorios de trabajo). En este artículo voy a detallar el proceso de upgrade de un host con múltiples jails.



El planteo es el siguiente: se requiere migrar los jails de una versión mayor a la siguiente (en este caso de 10.x a 11.0) y actualizar sus ports.

El procedimiento es relativamente sencillo y se divide en tres partes: 1- actualizar el host, 2- crear el nuevo sistema base para los jails, y actulizar los paquetes en cada jail. Gracias a este esquema, se evita tener que actualizar uno por uno el sistema base de cada jail: se hace una sola vez para todos. Esto también sirve para actualizar entre versiones menores.

Es importante destacar que un jail nunca puede correr un sistema base cuya versión mayor sea más actual que la del host. Esto se debe a que un kernel previo no es compatible con un sistema base más moderno (recordar que los jails comparten el mismo kernel que el host, pues se trata de virtualización a nivel sistema operativo). Por ello la versión del host siempre debe ir siempre igual (o más adelante) que la de los jails. Sin embargo, un kernel más actualizado (por ejemplo un kernel 11.x) funciona perfectamente para un jail con una versión de sistema base previa (10.x). He hecho esta prueba y lo he comprobado antes de actualizar los jails (un host 11.0 soporta correctamente jails con sistema base versión 10.3).

Actualizar el host

El primer paso entonces, consiste en migrar el host. Actualizar el host FreeBSD según se indica en las instrucciones del release announcement.

Partiendo de la versión 10.3, actualizar el sistema base a la versión 11 de la siguiente forma:

# freebsd-update upgrade -r 11.0-RELEASE
# freebsd-update install
# reboot
# freebsd-update install

Luego actualizar los ports y paquetes del host:

# portsnap fetch extract
# pkg-static install -f pkg
# pkg update && pkg upgrade
# portmaster -a -y
# freebsd-update install

En este punto, el sistema base corre la versión FreeBSD 11.0, y los jails la versión 10.3. Este esquema es compatible y funciona perfectamente, tal como mencioné anteriormente.

Cuando se actualiza el kernel y se están utilizando sistemas de archivos ZFS, es necesario actualizar la versión de dichos sistemas de archivos, para soportar características adicionales introducidas por el nuevo kernel.

Cómo actualizar un sistema de archivos ZFS

El comando zpool status permite recuperar el estado de los filesystems ZFS:

# zpool status

En su salida, este comando indica si un pool ZFS requiere actualización. También es posible recurrir directamente al comando zpool upgrade:

# zpool upgrade

El cual directamente lista los sistemas de archivos ZFS que requieren actualización.

Para actualizar un pool (por ejemplo "zroot") ejecutar:

# zpool upgrade zroot

Este comando actualiza la versión de ZFS (para introducir nuevas características disponibles en el kernel actual) sin afectar el normal funcionamiento del sistema de archivos ni desmontar ningún dataset.

Tener en cuenta que una vez que se actualiza un pool ZFS, este dejará de funcionar con versiones de kernel anterior al actual. Tal vez parezca un detalle menor, pero puede afectar en el caso de recuperación o backup (si el pool es replicado y enviado a otros sistema FreeBSD con una versión de kernel previa).

Al tratarse de un pool que aloja el sistema de archivos raíz, es necesario actualizar el sector de booteo del disco involucrado:

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0

Luego, actualizar el resto de los pooles:

# zpool upgrade zjails

Crear el nuevo template para los jails

La creación del nuevo sistema base para los jails es similar (o casi idéntica) al proceso de creación de los jails inicial. Cambiar al directorio base y crear una nueva versión del sistema raíz para los jails:

root@fbsd11:~ # cd /zjails/jail/
root@fbsd11:/zjails/jail # mkdir mroot-11.0

Guardar copias de respaldo de las imágenes del sistema base (base.txz) y fuentes (src.txz) previas, y descargar las correspondientes a la nueva versión de FreeBSD:

root@fbsd11:/zjails/jail # mv base.txz base-10.3.txz
root@fbsd11:/zjails/jail # mv src.txz src-10.3.txz
root@fbsd11:/zjails/jail # fetch https://download.freebsd.org/ftp/releases/amd64/amd64/11.0-RELEASE/base.txz
root@fbsd11:/zjails/jail # fetch https://download.freebsd.org/ftp/releases/amd64/amd64/11.0-RELEASE/src.txz
root@fbsd11:/zjails/jail # mv base.txz base-11.0.txz
root@fbsd11:/zjails/jail # mv src.txz src-11.0.txz 

Extraer el sistema base y los fuentes de FreeBSD:

root@fbsd11:/zjails/jail # cd mroot-11.0/
root@fbsd11:/zjails/jail/mroot-11.0 # tar xzf ../base-11.0.txz 
root@fbsd11:/zjails/jail/mroot-11.0 # tar xzf ../src-11.0.txz

Actualizar el sistema base:

root@fbsd11:/zjails/jail/mroot-11.0 # freebsd-update -b /zjails/jail/mroot-11.0/ fetch
root@fbsd11:/zjails/jail/mroot-11.0 # freebsd-update -b /zjails/jail/mroot-11.0/ install

Y eliminar los directorios no compartidos (privados a cada jail):

root@fbsd11:/zjails/jail/mroot-11.0 # chflags -R 0 var
root@fbsd11:/zjails/jail/mroot-11.0 # rm -R etc var root usr/local tmp

Finalmente, recrear los enlaces simbólicos a directorios de lectura/escritura privados:

root@fbsd11:/zjails/jail/mroot-11.0 # ln -s s/etc etc
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s s/home home
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s s/root root
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s ../s/usr-local usr/local
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s ../s/usr-X11R6 usr/X11R6
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s ../../s/distfiles usr/ports/distfiles
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s ../../s/packages usr/ports/packages
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s s/tmp tmp
root@fbsd11:/zjails/jail/mroot-11.0 # ln -s s/var var

Actualizar los jails

Finalizada la creación del nuevo mroot (sistema FreeBSD base compartido por todos los jails), se debe proceder con la actualización de los mismos.

Detener los jails:

# service jail stop
# service jailsffss stop

Recordar que el servicio jailsffss es de mi autoría y está definido en el artículo Jails en FreeBSD. Fue creado para lograr montar los sistemas de archivos de los jails cuando éstos están contenidos dentro de datasets ZFS.

Cambiar al nuevo mroot:

root@fbsd11:/zjails/jail/mroot-11.0 # cd ..
root@fbsd11:/zjails/jail # mv mroot mroot-10.3
root@fbsd11:/zjails/jail # mv mroot-11.0 mroot
root@fbsd11:/zjails/jail # mv mroot-10.3/usr/ports mroot/usr/

Notar que (para ahorrar espacio y vnodos) se mueve el arbol de ports desde la versión anterior a la versión actual.

Reiniciar los jails:

root@fbsd11:/zjails/jail # service jailsffss start
Mounting jails filesystems...
root@fbsd11:/zjails/jail # service jail start
Starting jails: www db.
root@fbsd11:/zjails/jail # jls
   JID  IP Address      Hostname                      Path
     3  192.168.39.204  fbsd10-www.linuxito.com       /zjails/jail/www
     4  192.168.39.205  fbsd10-db.linuxito.com        /zjails/jail/db

Actualizar los paquetes en cada jail

El último paso consiste en actualizar los ports y paquetes en cada jail. Primero, desde el host, actualizar el árbol de ports (para todos los jails):

root@fbsd11:/zjails/jail # portsnap -p /zjails/jail/mroot/usr/ports fetch extract

Este comando se realiza una única vez para todos los jails, pues el árbol de ports es compartido para todos.

Luego sí es necesario actualizar los paquetes en cada jail, uno por uno:

pkg-static install -f pkg
pkg update && pkg upgrade
portmaster -a -y

Es posible hacerlo por SSH o utilizando jexec desde el host. Si portmaster no se encuentra instalado, ejecutar:

# cd /usr/ports/ports-mgmt/portmaster
# make install clean

Referencias

Cómo actualizar FreeBSD 10.x a 11

FreeBSD 11.0-RELEASE Announcement


Tal vez pueda interesarte


Compartí este artículo