LXD es una herramienta para administrar contenedores Linux LXC, es desarrollado por Canonical, creadores de Ubuntu. LXC es una tecnología de virtualización a nivel de sistema operativo basada en contenedores, combinando espacios de nombres aislados y los “cgroups” del kernel de Linux para crear entornos aislados donde ejecutar código. Como dato curioso, la popular tecnología de virtualización Docker tuvo su origen en los contenedores LXC.
Uno de los objetivos de los contenedores de sistema, como los LXC, es tener todo el poder de un sistema operativo en un entorno virtualizado pero sin todo el peso que supone ejecutar una máquina virtual. De hecho se estima que un servidor es capaz de ejecutar de 10 a 15 veces más contenedores que máquinas virtuales con la misma carga.
1. Características de un contenedor LXC/LXD
- Seguridad: Los contenedores LXD se ejecutan en espacios aislados y solo pueden acceder a recursos limitados.
- Escalabilidad: LXD permite gestionar contenedores individuales o clusters distribuidos.
- Usabilidad: LXD ofrece una API clara y sencilla y un cliente de línea de comandos.
- Control de Recursos: Permite definir límites de CPU, memoria RAM, uso de red, almacenamiento y recursos del kernel.
2. Cuándo usar contenedores LXC/LXD
La tecnología LXD permite crear contenedores de sistemas Linux ideales para su uso en la nube. Por ejemplo, en lugar de instalar un único sistema o configuración directamente sobre un VPS o un Servidor Dedicado en la nube, podemos crear múltiples contenedores dentro del mismo, aprovechando de una mejor manera los recursos al compartirlos en diferentes sistemas operativos o aplicaciones que corren cada una en un contenedor.
El objetivo principal de usar contenedores de sistema con LXC/LXD es el de virtualizar todo un sistema operativo Linux con aplicaciones que tengan ciclos de vida medios o largos, lo que contrasta con los contenedores Docker, donde el enfoque está puesto en contenedores de corta duración que contienen una sola aplicación. Por ejemplo: Si deseamos virtualizar un servidor de comunicaciones completo que requiere de múltiples aplicaciones ejecutándose en conjunto, pero ahorrando recursos de cómputo, un contenedor LXD es ideal. Mientras que si deseamos abstraer una aplicación web para facilitar la automatización de sus ciclos de vida cortos al requerir múltiples actualizaciones frecuentes, utilizaríamos contenedores Docker.
3. Instalación y configuración inicial de LXD
Para empezar a usar LXC/LXD el paso mas sencillo es instalar un paquete snap con LXD en un servidor o instancia Ubuntu o Debian, una buena opción es un Droplet Basic de 1 vCPU y 2GB de RAM de DigitalOcean. En Ubuntu 20.04 el soporte LXD ya viene pre-instalado como paquete snap, de modo que solo hará falta configurarlo. Para verificar su disponibilidad ejecutamos el siguiente comando.
snap list
Name Version Rev Tracking Publisher Notes
core18 20200724 1885 latest/stable canonical✓ base
lxd 4.0.3 16922 4.0/stable/… canonical✓ -
snapd 2.45.3.1 8790 latest/stable canonical✓ snapd
Para crear la configuración inicial, debemos instalar los paquetes necesarios para el soporte de ZFS y luego ejecutar la inicialización de LXD.
sudo apt update
sudo apt install -y zfsutils-linux
sudo lxd init
Debemos a continuación contestar una serie de preguntas que definirán el entorno LXD de nuestro host.
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
Los siguientes seis pasos tienen que ver con el almacenamiento o ‘ storage pool’. Estas son las respuestas que debes dar:
Presiona ENTER para configurar un nuevo storage pool.
Presiona ENTER para aceptar el nombre del storage por defecto.
Presiona ENTER para aceptar el valor zfs para backend del storage.
Presiona ENTER para crear un nuevo pool ZFS.
Digita ‘no’ cuando te pregunte si deseas usar un block device, ya que en esta ocasión no hemos configurado un volumen o Block Storage adicional a nuestro servidor o instancia cloud.
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]: zfs
Create a new ZFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing block device? (yes/no) [default=no]: no
LXD nos preguntará luego si queremos conectar a un servidor MAAS (Metal As A Server), el MAAS es software que permite manejar un servidor bare-metal como una máquina virtual. Como estamos ejecutando LXD en modo standalone, aceptaremos el valor por defecto de no.
Would you like to connect to a MAAS server? (yes/no) [default=no]: no
Los siguientes pasos van a definir la configuración de red del entorno de contenedores. Contestamos ‘yes’ para crear una red local tipo bridge que le dará acceso de red a nuestros contenedores, la llamaremos lxdbr0, le asignaremos una red IPV4 automática y ninguna red IPV6, le diremos que LXD no estará disponible en red y que si queremos actualizar las imágenes automáticamente. Por ultimo elegimos no obtener la salida de este comando en formato YAML.
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
What should the new bridge be called? [default=lxdbr0]: lxdbr0
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
Would you like LXD to be available over the network? (yes/no) [default=no]: no
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: no
La configuración que hemos elegido es solo la opción más básica, en otro artículo veremos como personalizar estas opciones para escenarios mas avanzados, como por ejemplo definir una red local en un segmento personalizado, o activar el acceso de red para administrar visualmente nuestros contenedores desde otro equipo. Así mismo podríamos usar la salida en formato YAML para crear un script que automatice el proceso.
4. Crear un contenedor LXD
Ahora que hemos configurado LXD exitosamente, estamos listos para crear nuestro primer contenedor. En LXD la administración se realiza con el comando lxc
seguido de una acción como list
, launch
, start
, stop
o delete
. Por ejemplo, el comando:
lxc list
Nos mostrará una lista detallada de los contenedores del sistema.
To start your first container, try: lxc launch ubuntu:18.04
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
A continuación crearemos un contenedor que ejecute el servidor web Nginx sobre una imagen de Ubuntu 20.04, aunque podemos elegir otros Linux, incluyendo el ligero Alpine tan comúnmente usado con Docker. Para esto usaremos el comando lxc launch
seguido del shortcut de la imagen ubuntu:20.04
que también podríamos llamar con el nombre de la imagen ubuntu:bionic
lxc launch ubuntu:20.04 webserver
Creating webserver
Starting webserver
Una vez creado podemos listar el contenedor y veremos sus detalles, incluyendo su IP local dentro de la red creada para LXD suministrada por el servidor DHCP de LXD, al agregar –columns ns4 mostraremos solo las columnas name, state e IPV4.
lxc list --columns ns4
+-----------+---------+------------------------------------+
| NAME | STATE | IPV4 |
+-----------+---------+------------------------------------+
| webserver | RUNNING | ip_local_del_contenedor (eth0) |
+-----------+---------+------------------------------------+
Ahora podemos ingresar al contenedor e instalar en el los paquetes necesario, en este caso Nginx. Para esto usamos el comando lxc exec seguido del nombre del contenedor y luego el comando a ejecutar, en este caso: bash.
lxc exec webserver bash
Una vez dentro del contenedor veremos un promtp como el siguiente:
root@webserver:#
Y entonces podemos proceder a instalar los paquetes que deseemos.
apt update
apt install nginx
Y una vez instalado procedemos a iniciar el servidor Nginx.
systemctl enable nginx
systemctl start nginx
Si te has preguntado cómo vamos a acceder al servidor web si el contenedor sólo tiene una dirección IP local, estas en lo cierto. Para poder lograr acceder al Nginx en el contenedor que hemos llamado ‘webserver’ debemos crear un dispositivo de acceso tipo proxy que enrute el puerto 80 a nuestro contenedor, lo que se logra con el siguiente comando.
lxc config device add webserver miacceso80 proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
Ahora podemos acceder desde un navegador apuntando a la dirección IP de nuestro host (http://ip_servidor_host), y debemos ver la página de bienvenida por defecto de Nginx.
5. Detener, Reiniciar y/o Eliminar un contenedor LXD
Para detener un contenedor usamos el comando lxc stop seguido del nombre del contenedor, como se muestra a continuación:
lxc stop webserver
Podemos usar el comando lxc List para verificar que el contenedor se ha detenido.
lxc list
+-----------+---------+------+------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-----------+---------+------+------+------------+-----------+
| webserver | STOPPED | | | PERSISTENT | 0 |
+-----------+---------+------+------+------------+-----------+
Si queremos reiniciarlo nuevamente ejecutamos el comando lxc start seguido del nombre del contenedor.
lxc start webserver
Pero si lo que deseamos es eliminar el contenedor, entonces usamos el comando lxc delete sobre un contenedor previamente detenido.
lxc delete webserver
Conclusión
Hemos aprendido a configurar LXD en un servidor con Ubuntu 20.04 y a crear un contenedor básico, al que le hemos dado acceso a un puerto específico. Ahora estamos listos para pasar a crear soluciones mas avanzadas como: Automatizar la creación de contenedores LXD con un script, Administrar Remotamente contenedores LXD, o Crear una imagen LXD personalizada.