Blog

LXC (Linux Containers) – Parte II – Creación de un contenedor

En el artículo anterior, vimos unos conceptos básicos sobre virtualización. En éste, vamos a crear un contenedor básico, con conexión a red, utilizando un “puente” (bridge), con nuestra interfaz de red. Nos servirá para enjaular aplicaciones y servicios, funcionando como una especie de chroot, pero mucho más versátil.

Dado que, tanto Red Hat, como Debian y Ubuntu, se encuentran en proceso de migración a systemd, y, el resto, están prácticamente todas migradas,  nos vendrá bien ver el ejemplo con una distribución que ya esté funcionando con él.

Primero, debemos instalar los paquetes necesarios. En Arch Linux sería:

sudo pacman -Syu lxc bridge-utils

Lo siguiente que vamos a hacer, es configurar la interfaz de de red. Para ello, vamos a utilizar netctl. Copiamos el perfil de ejemplo:

sudo cp /etc/netctl/examples/ /etc/netctl/bridge

Una vez hecho esto, vamos a editar el archivo creado, que adaptaremos a nuestra configuración. Para conocer cuál es nuestra interfaz de red:

ip link show

Ahora,  el archivo /etc/netctl/bridge, generamos nuestra configuración. En el ejemplo, las IPs quedarían de las siguiente manera:

  • El host -> 192.168.0.21
  • El bridge -> 192.168.0.22
  • La puerta de enlace -> 192.168.0.1
  • El contenedor -> 192.168.0.23

Suponemos que el host ya tiene conectividad y que fue configurado con netctl. Vamos a crear la interfaz para el bridge con el siguiente contenido (el archivo /etc/netctl/bridge):

Description="Example Bridge connection"
Interface=br0
Connection=bridge
BindsToInterfaces=(eth0)
IP=static
Address=192.168.0.22
Gateway=192.168.0.1

## Ignore (R)STP and immediately activate the bridge
#SkipForwardingDelay=yes
 

Suponemos que nuestra interfaz real es eth0. Ya, tan sólo falta levantar la interfaz:

sudo netctl start bridge

Una vez hecho esto, vamos a crear el contenedor. Podemos utilizar las plantillas de OpenVZ. El paquete LXC, dispone de varias plantillas para crearlos, que podemos ver en /usr/share/lxc/templates/. En  nuestro caso:

sudo lxc-create -n archninfa1 -t archlinux -- -P vim,dhclient

Hemos creado un contenedor llamado archninfa1, de tipo archlinux y, además del software base, le hemos añadido los paquetes vim y dhclient.

Las opciones que van después de —  son las específicas de la plantilla utilizada. Para que ver un listado de las opciones, bastará ejecutar:

lxc-create -t archlinux -h

El contenedor se ha creado en /var/lib/lxc/nombrecontenedor. El fichero de configuración, config, se encuentra dentro de este directorio y, en rootfs, es donde se hará el chroot, es decir, es directorio raíz.

Como udev no funciona dentro de los contenedores, debemos asegurarnos que se crean unos dispositivos mínimos. Para ello, creamos el archivo /var/lib/lxc/archninfa1/nodos, y le añadimos los dispositivos necesarios:

 #!/bin/bash
# LXC Autodev hook.
cd ${LXC_ROOTFS_MOUNT}/dev
mknod -m 666 null c 1 3
mknod -m 666 zero c 1 5
mknod -m 666 random c 1 8
mknod -m 666 urandom c 1 9
mkdir -m 755 pts
mkdir -m 1777 shm
mknod -m 666 tty c 5 0
mknod -m 600 console c 5 1
mknod -m 666 tty0 c 4 0
mknod -m 666 full c 1 7
mknod -m 600 initctl p
mknod -m 666 ptmx c 5 2

Como hemos creado los nodos a mano, añadimos un script para eliminarlos después. Creamos el archivo /var/lib/lxc/archninfa1/stop, con el siguiente contenido:

#!/bin/bash
rm -r /var/lib/lxc/archninfa1/rootfs.dev/*

Damos permisos de ejecución a los dos archivos:

sudo chmod +x /var/lib/lxc/archininfa1/{nodos,stop}

Una vez hecho esto, editamos el archivo de configuración y la adaptamos a nuestras necesidades, incluyendo los hooks que acabamos de crear y la configuración de red:

...
...
lxc.utsname=archninfa1
lxc.autodev=1
lxc.hook.autodev=/var/lib/lxc/archninfa1/nodos
lxc.tty=2
lxc.pts=1024
lxc.mount=/var/lib/lxc/archninfa1/fstab
lxc.cap.drop=sys_module mac_admin mac_override sys_time
lxc.kmsg=0
lxc.hook.post-stop = /var/lib/lxc/archninfa1/stop
lxc.stopsignal=SIGRTMIN+4

#networking
lxc.network.type=veth
lxc.network.link=br0
lxc.network.flags=up
lxc.network.name=eth0
lxc.network.mtu=1500
lxc.network.ipv4=192.168.0.23/24
lxc.network.ipv4.gateway=192.168.0.1
...
...

Y ya, tan solo debemos arrancar el contenedor. Para comprobar que todo va bien:

sudo lxc-start -n archninfa1

Para arrancar en modo demonio:

sudo lxc-start -d -n archninfa1

Para acceder al contenedor creado:

sudo lxc-console -n archninfa1

Para arrancarlo, en modo demonio, con systemd:

sudo systemctl start lxc@archninfa1

Si queremos que el contenedor arranque al inicio del sistema:

sudo systemctl enable lxc@archninfa1

También deberá estar el bridge creado, así que:

sudo systemctl enable netctl@bridge

¡Espero que os haya gustado! 😉

Un saludo!!

Mª José Montes – mjose@highsec.es – @MMontesDiaz

  1. David
    David03-01-2014

    De nuevo un interesante artículo. Veo que han cambiado algunas cosas desde que use Archlinux por última vez.

    Tendré que actualizarme y darle otra oportunidad.

    Gracias por el artículo.

    Saludos

Leave a Reply

*

    No Twitter Messages