domingo, 11 de agosto de 2013

Instalando Debian GNU/Linux en una Jaula de FreeBSD sobre ZFS

English version: Install Debian GNU/Linux on a FreeBSD Jail with ZFS

Continuo con el proceso de configurar un sistema FreeBSD recién instalado para conseguir un entorno producción con los servicios alojados en Jaulas.

Vamos a seguir trabajando con Debian y sus distribuciones basadas en Linux que proporcionan el Userland adecuado para cumplir el objetivo, no totalmente resuelto, de ejecutar binarios con formato Linux bajo FreeBSD confinadas en una Jaula

Consideraciones previas.

La compatibilidad binaria para Linux que ofrece FreeBSD 9 se limita a las aplicaciones de 32 bits. FreeBSD ofrece un interface binario, que no una "emulación", con compatibilidad con el kernel de linux hasta la versión 2.6.16. Por tanto a la hora de seleccionar la versión de Debian Linux debemos tener presente estas limitaciones.

Creando nuestra Jaula

La implementación de una Jaula de Debian GNU/Linux es similar a una Jaula de Debian GNU/kfreeBSD, sin embargo, posee diferencias significativas que es necesario remarcar.

1.- Instalamos la herramienta Debootstrap, que instala Debian en subdirectorio dentro  de otro sistema.
root@morsa:/root # portsnap fetch update
root@morsa:/root # portmaster  sysutils/debootstrap
2.- Definimos el sistema de ficheros  donde vamos a instalar la Jaula.
root@morsa:/root # zfs create -o mountpoint=/jailz fbsdzpool1/jailz
root@morsa:/root # zfs create fbsdzpool1/jailz/deb-master
root@morsa:/root # mkdir /jailz/etc
3.- Cargamos los módulos necesarios para la compatibilidad binaria con Linux.
root@morsa:/root # kldload fdescfs linprocfs linsysfs tmpfs lindev 
4.- Habilitamos las Jaulas y la compatibilidad con Linux.
root@morsa:/root # echo 'jail_enable="YES"' >> /etc/rc.conf
root@morsa:/root # echo 'linux_enable="YES"' >> /etc/rc.conf
5.- Solo en caso de instalar squeeze, cambiamos el nivel de compatibilidad declarado a 2.6.18. 
root@morsa:/root # echo 'compat.linux.osrelease=2.6.18' >> /etc/sysctl.conf
6.- En el fichero de configuración /jailz/etc/jail.conf incluimos la entrada:

// Comienza fragmento
deb-master {
  path = /jailz/deb-master;
  allow.mount;
  mount.devfs;
  host.hostname = deb-master;
  mount.fstab="/jailz/etc/fstab.deb-master";
  ip4.addr = 127.0.0.10;
  interface = lo0;
  exec.start = "/etc/init.d/rc 3";
  exec.stop = "/etc/init.d/rc 0";
}
// Fin de fragmento

7.- Definimos los puntos de montaje para la Jaula en /jailz/etc/fstab.deb-master:

// Comienza el Fichero /jailz/etc/fstab.deb-master
linsys   /jailz/deb-master/sys         linsysfs  rw          0 0
linproc  /jailz/deb-master/proc        linprocfs rw          0 0
tmpfs    /jailz/deb-master/lib/init/rw tmpfs     rw,mode=777 0 0
// Fin del Fichero /jailz/etc/fstab.deb-master

8.-Con debootstrap instalamos Debian GNU/Linux, versiones lenny o squeeze, en la ruta de la Jaula.
root@morsa:/root # debootstrap --foreign --arch=i386 lenny /jailz/deb-master http://archive.debian.org/debian/
I: Retrieving Release
W: Cannot check Release signature; keyring file not available /usr/share/keyring
s/debian-archive-keyring.gpg
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on http://archive.debian.org/debian...
I: Retrieving libacl1 2.2.47-2
I: Validating libacl1 2.2.47-2
I: Retrieving adduser 3.110
I: Validating adduser 3.110
I: Retrieving apt-utils 0.7.20.2+lenny2
I: Validating apt-utils 0.7.20.2+lenny2
I: Retrieving apt 0.7.20.2+lenny2
....
I: Extracting login...
I: Extracting passwd...
I: Extracting libslang2...
I: Extracting initscripts...
I: Extracting sysv-rc...
I: Extracting sysvinit-utils...
I: Extracting sysvinit...
I: Extracting tar...
I: Extracting tzdata...
I: Extracting bsdutils...
I: Extracting mount...
I: Extracting util-linux...
I: Extracting zlib1g...
9.- Dento de la Jaula borramos los ficheros de configuración sysvinit_*.
root@morsa:/jailz/etc # ls /jailz/deb-master/var/cache/apt/archives/sysvinit_*
/jailz/deb-master/var/cache/apt/archives/sysvinit_2.86.ds1-61_i386.deb
root@morsa:/jailz/etc # rm /jailz/deb-master/var/cache/apt/archives/sysvinit_*

 10.- Montamos las sistemas de ficheros de la Jaula, en este caso se hace después de la instalación con debootstrap.
root@morsa:/root # mount -t linprocfs none /jailz/deb-master/proc
root@morsa:/root # mount -t devfs none /jailz/deb-master/dev
root@morsa:/root # mount -t linsysfs none /jailz/deb-master/sys
root@morsa:/root # mount -t tmpfs none /jailz/deb-master/lib/init/rw 
11.- Ejecutamos una shell con chroot dentro de la ruta de la Jaula.
root@morsa:/root # chroot /jailz/deb-master /bin/bash
12.- Para completar la configuración de la Jaula, en la shell iniciada dentro del entorno chroot, ejecutamos :
I have no name!@morsa:/# dpkg --force-depends -Ei /var/cache/apt/archives/*.deb
13.- Salimos de la shell anterior y desmontamos los sistemas de ficheros previamente montados en el paso 10. 
root@morsa:/root # umount /jailz/deb-master/proc
root@morsa:/root # umount /jailz/deb-master/dev
root@morsa:/root # umount /jailz/deb-master/sys
root@morsa:/root # umount /jailz/deb-master/lib/init/rw
En el probable caso de que no se pueda desmontar /jailz/deb-master/dev porque el sistema de ficheros esté ocupado, ejecutamos :

# fstat | grep deb-master
# kill -9 PID (Para cada proceso listado en el paso anterior)
O bien, se reinicia el Sistema.

Nunca hay que arrancar la Jaula sin haber limpiado los procesos y desmontado /jailz/deb-master/dev.

14.- Es necesario deshabilitar rsyslog dentro de la Jaula, pues no esta soportado por el modulo de compatibilidad para Linux. 

Por ello, antes de arrancar la jaula, para cada directorio de la ruta /jailz/deb-master/etc/rcX.d (donde X toma los valores de 0 a 6) renombramos los scripts de arranque del servicio.
# mv S10rsyslog _S10rsyslog
# mv K90rsyslog _K90rsyslog
15.- Iniciamos la Jaula, comprobamos que está arrancada y nos conectamos a ella.
root@morsa:/root # jail -f /jailz/etc/jail.conf -c deb-master
deb-master: created
Starting periodic command scheduler: crond.

root@morsa:/root # jls
   JID  IP Address      Hostname                      Path
     1  127.0.0.10      deb-master                   /jailz/deb-master
root@morsa:/root # jexec 1 /bin/bash

deb-master:/# uname -a
Linux deb-master 2.6.16 FreeBSD 9.1-RELEASE-p4 #0: Mon Jun 17 11:42:37 UTC 2013 i686 GNU/Linux

16.- Editamos el fichero /etc/apt/sources.list y corregimos su contenido.
// Inicio del fragmento
deb http://archive.debian.org/debian/ lenny main non-free contrib
// Fin de fragmento 

17.- Actualizamos la lista de paquetes.
deb-master:/# apt-get update
Get:1 http://archive.debian.org lenny Release.gpg [1034B]
Get:2 http://archive.debian.org lenny Release [99.6kB]
Get:3 http://archive.debian.org lenny/main Packages [6872kB]
Get:4 http://archive.debian.org lenny/non-free Packages [124kB]
Get:5 http://archive.debian.org lenny/contrib Packages [94.3kB]
Fetched 7191kB in 11s (649kB/s)
Reading package lists... Done
18.- Paramos la Jaula, los mensajes de error se deben a que los procesos dentro de la jaula no pueden ejecutar ciertas operaciones.
root@morsa:/root # jail -f /jailz/etc/jail.conf -r deb-master
umount2: Operation not permitted
umount: fbsdzpool1/jailz: must be superuser to umount
umount2: Operation not permitted
umount: fbsdzpool1/ROOT/91_30062013/usr: must be superuser to umount
umount2: Operation not permitted
umount: fbsdzpool1/ROOT/91_30062013/usr: must be superuser to umount
umount2: Operation not permitted
umount: fbsdzpool1/ROOT/91_30062013/var: must be superuser to umount
umount2: Operation not permitted
umount: fbsdzpool1/ROOT/91_30062013/var: must be superuser to umount
failed.
mount: fbsdzpool1/ROOT/91_30062013: unknown device
Will now halt.
ifdown: shutdown usbus0: Invalid argument
ifdown: shutdown ath0: Invalid argument
ifdown: shutdown usbus1: Invalid argument
ifdown: shutdown lo0: Invalid argument
ifdown: shutdown lo0: Invalid argument
ifdown: shutdown eth1: Invalid argument
deb-master: removed
 19.- Hacemos un snapshot de la Jaula recién instalada.
root@morsa:/root # zfs snapshot fbsdzpool1/jailz/deb-master@debootstrap

Ahora, disponemos de una Jaula Master, desde la que podemos generar nuevas jaulas a partir de clones de ZFS, después añadimos una nueva entrada a /jailz/jail.conf con el correspondiente fichero /jailz/etc/fstab.newjail.
# zfs clone fbsdzpool1/jailz/deb-master@deboostrap fbsdzpool1/jailz/newjail

Sobre esas Jaulas clonadas, podemos comenzar a instalar aplicaciones 32 bits con su formato elf propio de linux.

 

Consideraciones finales

Todas las consideraciones finales acerca de la instalación en una Jaula de Debian GNU/kfreeBSD son igualmente aplicables a este caso.

Con este procedimiento he instalado Userlands de las versiones lenny y squeeze; sin embargo recomiendo utilizar la versión lenny. La compatibilidad con Linux que proporcióna FreeBSD  es para la versión de kernel 2.6.16 y la mínima versión de kernel requerida por squeeze es  2.6.18; y aunque funciona bastante bien, aquellas aplicaciones que utilizan caracteristicas propias de la 2.6.18 no funcionan en absoluto.

Como apunte final, para habilitar el acceso a internet desde la Jaula, necesario para instalar paquetes, podemos habilitar el módulo pf y hacer NAT con las direcciones IP de las Jaulas, para ello ejecutamos lo siguiente:

root@morsa:/root # kldload pf
root@morsa:/root # echo 'pf_enable="YES"' >> /etc/rc.conf
root@morsa:/root # echo "nat on wlan0 from 127.0.0.10 to any -> (wlan0)" >> /etc/pf.conf

No hay comentarios:

Publicar un comentario en la entrada

Vuestros comentarios son bien recibidos, os animo a contribuir proponiendo temas que os interesen para desarrollar en este blog.