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