El aislamiento de grupos de procesos formando una jaula o contenedor ha
sido una característica de ciertos sistemas operativos de la rama Unix desde
los años 80, en forma del programa
chroot (creado por Bill Joy, el que más
adelante sería uno de los padres de Java). La restricción de uso de recursos de
las jaulas chroot
, que ya hemos visto, se limitaba a la protección del
acceso a ciertos recursos del sistema de archivos, aunque son relativamente
fáciles de superar; incluso así, fue durante mucho tiempo la forma principal de
configurar servidores de alojamiento compartidos y sigue siendo una forma
simple de crear virtualizaciones ligeras. Las
jaulas BSD constituían un sistema
más avanzado, implementando una
virtualización a nivel de sistema operativo
que creaba un entorno virtual prácticamente indistinguible de una máquina real
(o máquina virtual real). Estas jaulas no solo impiden el acceso a ciertas
partes del sistema de ficheros, sino que también restringían lo que los
procesos podían hacer en relación con el resto del sistema. Tiene como
limitación, sin embargo, la obligación de ejecutar la misma versión del núcleo
del sistema.
En esta presentación explica como los espacios de nombres son la clave para la creación de contenedores y cuáles son sus ventajas frente a otros métodos de virtualización
El mundo Linux no tendría capacidades similares hasta bien entrados los años 90, con vServers, OpenVZ y finalmente LXC. Este último, LXC, se basa en el concepto de grupos de control o CGROUPS, una capacidad del núcleo de Linux desde la versión 2.6.24 que crea contenedores de procesos unificando diferentes capacidades del sistema operativo que incluyen acceso a recursos, prioridades y control de los procesos. Los procesos dentro de un contenedor están aislados de forma que solo pueden ver los procesos dentro del mismo, creando un entorno mucho más seguro que las anteriores jaulas. Estos CGROUPS han sido ya vistos en otro tema.
Dentro de la familia de sistemas operativos Solaris (cuya última versión libre se denomina illumos, y tiene también otras versiones como SmartOS) la tecnología correspondiente se denomina zonas. La principal diferencia es el bajo overhead que le añaden al sistema operativo y el hecho de que se les puedan asignar recursos específicos; estas diferencias son muy leves al tratarse simplemente de otra implementación de virtualización a nivel de sistema operativo.
Un contenedor es, igual que una jaula, una forma ligera de virtualización, en
el sentido que no requiere un hipervisor para funcionar ni, en principio,
ninguno de los mecanismos hardware necesarios para llevar a cabo
virtualización. Tiene la limitación de que la máquina invitada debe tener el
mismo kernel y misma CPU que la máquina anfitriona, pero si esto no es un
problema, puede resultar una alternativa útil y ligera a la misma. A diferencia
de las jaulas, combina restricciones en el acceso al sistema de ficheros con
otras restricciones aprovechando espacios de nombres y grupos de control. lxc
es la solución de creación de contenedores más fácil de usar hoy en día en
Linux.
Instala LXC en tu versión de Linux favorita. Normalmente la versión en desarrollo, disponible tanto en GitHub como en el sitio web está bastante más avanzada; para evitar problemas sobre todo con las herramientas que vamos a ver más adelante, conviene que te instales la última versión y si es posible una igual o mayor a la 1.0.
Esta virtualización ligera tiene, entre otras ventajas, una huella escasa: un ordenador normal puede admitir 10 veces más contenedores (o tápers) que máquinas virtuales; su tiempo de arranque es de unos segundos y, además, tienes mayor control desde fuera (desde el anfitrión) del que se pueda tener usando máquinas virtuales.
Esta sección tiene principalmente un interés histórico y desde el punto de vista de la creación de aplicaciones que manejen contenedores. En la empresa se usará principalmente Docker.
No todos los núcleos del sistema operativo pueden usar este tipo de contenedor
ligero; para empezar, dependerá de cómo esté compilado, pero también del
soporte que tenga el hardware. lxc-checkconfig
permite comprobar si está
preparado para usar este tipo de tecnología y también si se ha configurado
correctamente. Parte de la configuración se refiere a la instalación de
cgroups
, que hemos visto antes; el resto a los espacios de nombres y a
capacidades misceláneas relacionadas con la red y el sistema de ficheros.
Hay que tener en cuenta que si no aparece alguno de esas capacidades como activada, LXC no va a funcionar. Pero si no hay ningún problema y todas están enabled se puede usar lxc con relativa facilidad siempre que tengamos una distro como Ubuntu relativamente moderna:
sudo lxc-create -t ubuntu -n una-caja
crea un contenedor denominado una-caja
e instala Ubuntu en él. Esto
tardará un rato mientras se bajan una serie de paquetes y se
instalan. O se
puede usar una imagen similar a la que se usa en
EC2 de Amazon:
sudo lxc-create -t ubuntu-cloud -n nubecilla
que funciona de forma ligeramente diferente, porque se descarga un
fichero .tar.gz
usando wget
(y tarda también un rato). Podemos
listar los contenedores que tenemos disponibles con lxc-ls -f
, aunque
en este momento cualquier contenedor debería estar en estado
STOPPED
.
Para arrancar el contenedor y conectarse a él,
sudo lxc-start -n nubecilla
Dependiendo del contenedor que se arranque, habrá una configuración
inicial; en este caso, se configuran una serie de cosas y
eventualmente sale el login, que será para todas las máquinas creadas
de esta forma ubuntu
(también clave). Lo que hace esta orden es
automatizar una serie de tareas tales como asignar los CGROUPS
, crear
los namespaces que sean necesarios, y crear un puente de red tal como
hemos visto anteriormente. En general, creará un puente llamado
lxcbr0
y otro con el prefijo veth
.
Una vez arrancados los contenedores, si se lista desde fuera aparecerá de esta forma:
jmerelo@penny:~/txt/docencia/infraestructuras-virtuales/IV/documentos$ sudo lxc-list
RUNNING
contenedor
nubecilla
FROZEN
STOPPED
Y, dentro de la misma, tendremos una máquina virtual con estas apariencias:
Para el usuario del contenedor aparecerá exactamente igual que cualquier otro ordenador: será una máquina virtual que, salvo error o brecha de seguridad, no tendrá acceso al anfitrión, que sí podrá tener acceso a los mismos y pararlos cuando le resulte conveniente.
sudo lxc-stop -n nubecilla
Las órdenes que incluye el paquete permiten administrar las máquinas virtuales, actualizarlas y explican cómo usar otras plantillas de las suministradas para crear contenedores con otro tipo de sistemas, sean o no debianitas. Se pueden crear sistemas basados en Fedora; también clonar contenedores existentes para que vaya todo rápidamente.
Crear y ejecutar un contenedor basado en tu distribución y otro basado en otra distribución, tal como Fedora. Nota En general, crear un contenedor basado en tu distribución y otro basado en otra que no sea la tuya.
Fedora, al parecer, tiene problemas si estás en Ubuntu 13.04 o superior, así que en tal caso usa cualquier otra distro. Por ejemplo, Óscar Zafra ha logrado instalar Gentoo usando un script descargado desde su sitio, como indica en este comentario en el issue.
Los contenedores son la implementación de todas las tecnologías vistas anteriormente: espacios de nombres, CGroups y puentes de red y como tales pueden ser configurados para usar solo una cantidad determinada de recursos, por ejemplo la CPU. Para ello se usan los ficheros de configuración de cada una de las máquinas virtuales. Sin embargo, tanto para controlar como para visualizar los tápers (que así vamos a llamar a los contenedores a partir de ahora) es más fácil usar lxc-webpanel, un centro de control por web que permite iniciar y parar las máquinas virtuales, aparte de controlar los recursos asignados a cada una de ellas y visualizarlos, tal como se muestra a continuación.
La página principal te da una visión general de los contenedores instalados y desde ella se pueden arrancar o parar.
Cada solución de virtualización tiene sus ventajas e inconvenientes. La principal ventaja de los contenedores son el aislamiento de recursos y la posibilidad de manejarlos, lo que hace que se use de forma habitual en proveedores de infraestructuras virtuales. El hecho de que se virtualicen los recursos también implica que haya una diferencia en las prestaciones, que puede ser apreciable en ciertas circunstancias.
Al tema de contenedores del que se ha desgajado esto.
Si te interesa, puedes consultar cómo se virtualiza el almacenamiento que, en general, es independiente de la generación de una máquina virtual. También puedes ir directamente al tema de uso de sistemas en el que se trabajará con sistemas de virtualización completa.