Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Creación de zonas Solaris (y problemas con la red)

Última Actualización: 28 de Julio de 2009 - Martes

Tras el primer intento fallido y el segundo exitoso, tengo un sistema Solaris 10 instalado en OVH.

Ahora hay que montarle "Zonas" encima.

Las zonas Solaris son contenedores con el rendimiento de la ejecución nativa y la seguridad de las máquinas virtuales. Básicamente consiste en que los procesos pertenecientes a una zona no pueden afectar ni interrelacionarse con procesos de otras zonas, incluso aunque su usuario sea el administrador o "root". Si a eso le añades que puedes fijar límites en la CPU, memoria y "swap" consumida, en el uso de la red, espacio en disco, etc., tenemos un entorno seguro y eficiente. Podemos delegar la gestión de una zona a un usuario, con privilegios de administrador o "root" en la zona, sin comprometer la seguridad de la máquina o del resto de zonas.

Hasta Solaris 10 update 6 el uso de zonas estaba reñido con la funcionalidad de "Live Upgrade" de Solaris, sobre todo si se usaba ZFS. Estas limitaciones han quedado eliminadas en Solaris 10 Update 6, así que podemos hacer un uso bastante liberal de las zonas, siempre que tengamos cierto cuidado.

[/]# dispadmin -d FSS
[/]# cd /datos
[datos]# mkdir zones; chmod 700 zones; cd zones
[datos]# zfs create -omountpoint=none datos/zones/NOMBRE/dataset
[zones]# zonecfg -z NOMBRE
NOMBRE: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg> create
zonecfg:NOMBRE> set zonepath=/datos/zones/NOMBRE
zonecfg:NOMBRE> set autoboot=true
zonecfg:NOMBRE> add fs
zonecfg:NOMBRE:fs> set dir=/usr/local
zonecfg:NOMBRE:fs> set special=/usr/local
zonecfg:NOMBRE:fs> set type=lofs
zonecfg:NOMBRE:fs> add options [ro,nodevices]
zonecfg:NOMBRE:fs> end
zonecfg:NOMBRE> add dataset
zonecfg:NOMBRE:dataset> set name=datos/zones/NOMBRE/dataset
zonecfg:NOMBRE:dataset> end
zonecfg:NOMBRE> add inherit-pkg-dir
zonecfg:NOMBRE:inherit-pkg-dir> set dir=/opt
zonecfg:NOMBRE:inherit-pkg-dir> end
zonecfg:NOMBRE> add net
zonecfg:NOMBRE:net> set address=IP/24
zonecfg:NOMBRE:net> set physical=gani0
zonecfg:NOMBRE:net> set defrouter=ROUTER
zonecfg:NOMBRE:net> end
zonecfg:NOMBRE> verify
zonecfg:NOMBRE> commit
zonecfg:NOMBRE> exit

[zones]# zoneadm -z NOMBRE install
A ZFS file system has been created for this zone.
Preparing to install zone <NOMBRE>.
Creating list of files to copy from the global zone.
Copying <2918> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <1338> packages on the zone.
Initialized <1338> packages on zone.
Zone <NOMBRE> is initialized.
Installation of these packages generated errors: <SUNWpostgr-82-server-data-root
SUNWpostgr-83-server-data-root SUNWpostgr-82-libs SUNWpostgr-82-client
SUNWpostgr-82-server SUNWpostgr-82-contrib SUNWpostgr-82-devel>
The file </datos/zones/NOMBRE/root/var/sadm/system/logs/install_log> contains a log of the zone installation.

[zones]# zoneadm list -icv
  ID NAME             STATUS     PATH                           BRAND    IP
   0 global           running    /                              native   shared
   - NOMBRE           installed  /datos/zones/NOMBRE            native   shared
[zones]# zoneadm -z NOMBRE boot
[zones]# zlogin -C NOMBRE
[Connected to zone 'NOMBRE' console]

Select a Language

  0. English
  1. Italian
  2. Spanish

Please make a choice (0 - 2), or press h or ? for help: 0

Select a Locale

   0. English (C - 7-bit ASCII)
   1. Catalan, Spain (ISO8859-1)
   2. Catalan, Spain (ISO8859-15 - Euro)
   3. Cyprus (Greek) (UTF-8)
   4. Greece (ISO8859-7)
   5. Greece (UTF-8)
   6. Malta (English) (UTF-8)
   7. Malta (UTF-8)
   8. Portugal (ISO8859-1)
   9. Portugal (ISO8859-15 - Euro)
  10. Portugal (UTF-8)
  11. Spain (Catalan) (UTF-8)
  12. Go Back to Previous Screen

Please make a choice (0 - 12), or press h or ? for help: 0

What type of terminal are you using?
 1) ANSI Standard CRT
 2) DEC VT52
 3) DEC VT100
 4) Heathkit 19
 5) Lear Siegler ADM31
 6) PC Console
 7) Sun Command Tool
 8) Sun Workstation
 9) Televideo 910
 10) Televideo 925
 11) Wyse Model 50
 12) X Terminal Emulator (xterms)
 13) CDE Terminal Emulator (dtterm)
 14) Other
Type the number of your choice and press Return: 3

Creating new rsa public/private host key pair
Creating new dsa public/private host key pair
Configuring network interface addresses: gani0.
[... configuración de red, dns, timezone, clave root, etc ...]
System identification is completed.

rebooting system due to change(s) in /etc/default/init


[NOTICE: Zone rebooting]


SunOS Release 5.10 Version Generic_141415-05 64-bit
Copyright 1983-2009 Sun Microsystems, Inc.  All rights reserved.
Use is subject to license terms.
Hostname: NOMBRE
Reading ZFS config: done.

NOMBRE console login:
[...Cortamos la sesión de consola...]
[zones]# zlogin NOMBRE
[Connected to zone 'NOMBRE' pts/10]
Last login: Tue Jul 28 01:14:25 on pts/10
Sun Microsystems Inc.   SunOS 5.10      Generic January 2005
# netservices limited
restarting syslogd
restarting sendmail
restarting wbem
dtlogin needs to be restarted. Restart now? [Y] y
restarting dtlogin
# zfs list
NAME                           USED  AVAIL  REFER  MOUNTPOINT
datos                         45.3G   632G  37.5K  /datos
datos/zones                    493M   632G    20K  /datos/zones
datos/zones/NOMBRE             493M   632G   493M  /datos/zones/NOMBRE
datos/zones/NOMBRE/dataset      18K   632G    18K  none
# zfs set mountpoint=/datos datos/zones/NOMBRE/dataset
# zfs list
NAME                           USED  AVAIL  REFER  MOUNTPOINT
datos                         45.3G   632G  37.5K  /datos
datos/zones                    493M   632G    20K  /datos/zones
datos/zones/NOMBRE             493M   632G   493M  /datos/zones/NOMBRE
datos/zones/NOMBRE/dataset      18K   632G    18K  /datos
# df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
[...]
datos/zones/NOMBRE/dataset
                     662621668     75213 662546455   1% /datos

[...Cortamos la sesión...]

[/]# df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
[...]
datos/zones/NOMBRE/dataset
                     662621692     75213 662546479   1% /datos/zones/NOMBRE/root/datos

Lo primero que haremos es configurar el sistema operativo para que use planificación de CPU FSS (Fair Share Scheduler). Ésto nos permitirá asignar prioridades a las zonas que, a su vez, puede definir prioridades entre sus diferentes proyectos. Seguidamente creamos el "dataset" ZFS que contendrá esa zona y las zonas futuras.

Lo siguiente es crear la configuración de la zona. Como configuración especial, mapeo el "/usr/local" de la máquina nativa (la zona "global") a la nueva zona, para poder beneficiarnos del software instalado sin tener que reinstalarlo de nuevo. Naturalmente, como ese directorio se usa en la zona "global", lo mapeo en modo "solo lectura", para que que las zonas no puedan cambiarlo, con los riesgos de seguridad que ello supondría. Es decir, si queremos instalar nuevo software, habrá que hacerlo en la zona "global" (y será visible en la zona, mediante el mapeo). Esta decisión es cuestionable, pero en este caso concreto me parece preferible.

A continuación mapeo un "dataset" ZFS, para que la zona pueda administrarlo de forma libre (incluyendo crear nuevos "datasets"), configuro un directorio de instalación de paquetes extra (para ahorrar espacio en disco) y defino la red.

El siguiente paso es instalar la zona, que crea su "dataset" ZFS y replica la configuración básica de la zona "global", incluyendo los paquetes y parches asociados. Es de señalar que con la configuración utilizada, los ficheros en sí se mantienen en la zona "global", y se utilizan desde allí; lo único que se copia en la nueva zona son los metadatos de los mismos. Así que la operación es rápida y consume poco espacio de disco.

Se observa que han fallado varios paquetes, relacionados con la base de datos "Postgresql". Leyendo el log, el problema es que no existe el usuario "postgres" en la nueva zona. Ésto parece ser un bug, pero como no voy a usar la base de datos, lo ignoro.

Una vez que se instala una zona, hay que inicializar su configuración. Para ello entramos en su consola mediante el comando "zlogin", donde nos preguntará el idioma, el "locale", el tipo de terminal, la zona horaria, detalles de red, la clave de "root", etc. Una vez que introduzcamos esa información, la zona se reiniciará. Una vez online (un par de segundos), volvemos a entrar con "zlogin" a través de un "tty" normal, comprobamos que estamos en la zona y la configuramos para que ningún servicio esté accesible desde el exterior (configuración segura). Montamos el "dataset" delegado y comprobamos cómo se ve dentro y fuera de la zona. Hemos terminado. La zona está lista para su uso. ¿O no?.

Zonas y problemas con la red

La configuración de zona empleada se llama "Shared IP". Ésto no significa que compartamos la IP de la zona "global", sino que compartimos su tarjeta de red y su pila IP. En la versión actual de Solaris 10 (Update 7), este detalle tiene bastantes limitaciones, como el no poder utilizar "ipfilter" dentro de la zona o, lo peor de todo, problemas con la ruta por defecto de la zona.

En pocas palabras, y resumiendo un problema LARGO de explicar, si la IP de la zona no está en la misma red que la ruta por defecto de la zona global, no tendremos red. Al menos no de forma simple e indolora.

Éste es mi caso con OVH, ya que para la zona estoy usando una "IP Failover".

¿La solución?. Ninguna satisfactoria. Puedes asignar una IP privada y realizar NATing a través del "ipfilter" de la zona global. Puedes añadir una ruta por defecto espuria y jugar con la tabla ARP, pero como nuestro router es un router virtual montado con dos máquinas en alta disponibilidad, su dirección ARP puede cambiar... Si instalamos una segunda tarjeta de red y la asignamos a la zona resolvemos el problema, pero no es una opción disponible en el hosting, y -en cualquier caso- necesitaríamos tantas tarjetas de red como zonas.

La opción elegida, poco satisfactoria pero que funciona, es aprovechar que en OVH el acceso a las "IP Failover" externas a nosotros se gestiona por "proxy ARP", así que podemos poner como ruta por defecto una de ellas, que el tráfico pasará a través del router correcto... mientras la "IP Failover" a la que apuntamos esté en otro RACK... Es un riesgo, pero un riesgo controlado y documentado.

En la zona "global" habrá dos rutas por defecto, uno correspondiente a sí misma y otro a la zona. Las rutas son distintas, a IPs diferentes, pero su dirección MAC es la misma, así que van al mismo router y no causan problemas aunque Solaris balancee ambas rutas por "round-robin".

Es una solución chapucera, que funciona por la forma concreta que tiene OVH de trabajar, pero funciona. Es de señalar que el proyecto crossbow soluciona todos estos problemas, ya que cada zona recibe una interfaz de red completamente virtualizada, aunque use la misma tarjeta física. Con ese proyecto, la topología de red es arbitraria, e incluso permite hacer shapping y controlar el tráfico entre las zonas, cortafuegos individualizado...

No puedo esperar a poder usar "Crossbow". Ya está disponible en OpenSolaris, pero no está claro si va a ser portado a Solaris 10 o tendremos que esperar a un hipotético futuro Solaris 11.

De momento todo lo que se puede hacer, aparte de utilizar OpenSolaris, es documentar todo esto con cuidado y tenerlo muy presente.


Historia

  • 27/jul/09: Primera versión de esta página.



Python Zope ©2009 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS