Cómo utilizar contenedores de Linux con LXC y LXD

En los buenos viejos tiempos, instalar un sistema operativo significaba juntar todos los componentes de hardware, encender su nueva computadora con un disco de instalación en una unidad periférica y dejar que el proceso de instalación fuera libre. El tiempo total transcurrido podría oscilar entre horas y semanas.

En estos días puedo decirme a mí mismo: "No me importaría probar eso en un servidor que ejecuta una versión particular de CentOS" y, dependiendo de una serie de variables y suponiendo que la imagen original ya se haya descargado, puedo tener una sistema virtual listo en 30 segundos. Sus resultados exactos pueden variar, pero no tanto.

Puede ver cómo funciona todo esto en mi nuevo curso Pluralsight "Optimización del sistema Linux", en el que se basa este artículo.

¿Qué ha estado impulsando todo este cambio? Virtualización. Y, en particular, la virtualización de contenedores.

Un sistema operativo virtualizado es un sistema de archivos que contiene todas las bibliotecas de software, binarios y archivos de configuración que necesitaría para iniciar una máquina tradicional. Es solo que este sistema de archivos en particular no se almacena en la partición raíz o de arranque que su computadora leería al encenderse, sino en alguna otra parte de su volumen de almacenamiento.

Y "encender" su computadora virtual ocurre cuando algún software hábilmente engaña a los archivos haciéndoles creer que se están ejecutando por sí mismos en su propio hardware, cuando en realidad están compartiendo espacio y recursos con el sistema operativo host y, quizás, con algún otro computadoras virtuales.

En términos generales, existen dos tipos de sistemas de software que se utilizan para la administración de la virtualización de servidores: hipervisor y contenedor.

Los hipervisores proporcionan una capa de abstracción que permite a las VM invitadas crear un entorno aislado con acceso al hardware del sistema que emula un servidor bare metal. Esto significa que las VM de hipervisor se pueden construir desde cualquier sistema operativo compatible con su hardware subyacente. Pero también significa que utilizarán más espacio y más memoria y recursos informáticos.

Virtualización de contenedores

Los contenedores, por otro lado, comparten el kernel del sistema operativo de la computadora host y existen dentro de espacios cuidadosamente asegurados y aislados administrados por herramientas del sistema como cgroups. Debido a que comparten el kernel, la memoria y los recursos del sistema consumidos por los contenedores pueden ser realmente mínimos, sin ningún desperdicio. Y, como verá, las velocidades que obtendrá al ejecutar aplicaciones de contenedor serán impresionantes.

Gran parte de la atención relacionada con los contenedores en los últimos años se ha centrado en Docker y, más recientemente, en la herramienta de orquestación de contenedores de Google, Kubernetes. De hecho, Kubernetes es ideal para arquitecturas de microservicios a escala empresarial.

Pero hay una implementación más antigua y, posiblemente, más madura del modelo de contenedor que no ha ido a ninguna parte. El Linux Container Project, LXC, y su conjunto de herramientas más reciente, LXD, tienen fortalezas que muchos dirían que lo convierten en un mejor candidato para algunos casos de uso que Kubernetes. En particular, LXC sobresale en la construcción de entornos de espacio aislado ligeros y rápidos para pruebas y desarrollo de aplicaciones.

En este artículo, le mostraré cómo instalar LXD, cómo preparar y lanzar un contenedor simple ejecutando el ultra pequeño Alpine Linux, y luego cómo abrir una sesión de shell dentro de su nuevo contenedor. También explicaré cómo encontrar y lanzar múltiples versiones de otras distribuciones.

Una cosa que puedo decirles de inmediato es que cada vez que enseño LXC, los estudiantes responden con asombro de lo poderoso y eficiente que puede ser el uso de contenedores.

Cuando terminemos con todo esto, podrá encender máquinas para probar de forma práctica lo que sea que esté aprendiendo o trabajando en cuestión de segundos. Cuando un experimento sale mal, puede apagar instantáneamente y quitar un contenedor y construir otro para reemplazarlo. Simplemente ya no hay excusa para no aprender.

Construcción de contenedores LXD

Vamos a hacer que LXC funcione en una nueva instalación de una máquina Ubuntu 18.04. En esta demostración, instalaremos e inicializaremos un entorno LXD y luego usaremos la versión LXD de la interfaz de línea de comandos LXC para descargar e iniciar un contenedor Alpine Linux. Confirmaremos que todo funcionó y luego echaremos un vistazo para ver cómo está poblado el entorno.

Voy a usar el administrador de paquetes instantáneos para instalar LXD porque esa es ahora la recomendación oficial. Y no solo para LXD, eso sí: todo tipo de aplicaciones se están desplazando hacia administradores alternativos como snap o AppImmage y Flatpak. Todavía amo mi aptitud para Debian, pero no puedes luchar contra el mundo entero.

$ sudo snap install lxd 

LXD, que, nuevamente, es un conjunto de herramientas actualizado diseñado para administrar la API LXC, viene en un paquete que incluye todas las dependencias regulares de LXC. Un comando de instalación y listo.

Es importante inicializar el entorno LXC con el comando lxd init. Puede configurar las cosas usted mismo manualmente, pero es más probable que lo haga bien de esta manera. El proceso de inicio le hará un montón de preguntas y, al menos por ahora, las respuestas predeterminadas funcionarán.

$ sudo lxd init 

Una vez hecho esto, estamos listos para construir su primer contenedor. Cualquiera sea la distribución y versión de Linux que queramos, necesitaremos encontrar y descargar la imagen. El proyecto LXC mantiene un repositorio de una gran variedad de imágenes en images.linuxcontainers.org. Puede ver que generalmente hay varias versiones de cada distribución, lo que le permite crear contenedores que funcionarán con casi cualquier software que pueda lanzar.

Voy a usar la última versión de Alpine Linux porque es muy pequeña. Siéntase libre de usar cualquier imagen que desee, incluidos los grandes como Ubuntu y CentoOS. Alpine, por supuesto, se descargará muy rápidamente.

Pero antes de hacer eso, debería decirte cómo averiguar la sintaxis de la línea de comandos necesaria para obtener tu imagen.

Como puede ver en esta captura de pantalla del sitio web de LXD, puede obtener tres piezas de información que necesitará de la página en sí: el nombre de la distribución, Alpine, en este caso, el número de lanzamiento, 3.10, y la arquitectura. . Estamos detrás de amd64.

Ahora estamos listos para activar la descarga ejecutando el launchcomando:

$ sudo lxc launch images:alpine/3.10/amd64 demo 

Observe cómo la sintaxis es "lxc" a pesar de que técnicamente es una interfaz LXD. "images" le dice a LXC que nuestra imagen vive en el repositorio público que vimos anteriormente. Nuestros tres bits de datos: el nombre de la distribución, el número de versión y la arquitectura, se ingresan separados por barras diagonales. Usaré "demo" como el nombre de mi contenedor. Eso debería ser todo lo que necesitamos.

Puede ver lo pequeño que es Alpine por la rapidez con que se descarga. Mi conexión a Internet no es tan rápida y no he jugado ningún juego con la grabación. Para confirmar que funcionó, ejecutaré "lxc ls" para listar todos los contenedores instalados actualmente. Solo hay uno. Y su estado actual es "en ejecución".

sudo lxc ls +------+---------+----------------------+------------+-----------+ | NAME | STATE | IPV4 | TYPE | SNAPSHOTS | +------+---------+----------------------+------------+-----------+ | demo | RUNNING | 10.125.45.119 (eth0) | PERSISTENT | 0 | +------+---------+----------------------+------------+-----------+ 

Puede abrir una sesión raíz sin iniciar sesión en un contenedor utilizando el comando "lxc exec". Simplemente especifique el nombre del contenedor y luego dígale a LXC que desea ejecutar un shell usando el intérprete sh (es posible que prefiera /bin/bashsi está trabajando con un contenedor Ubuntu o CentOS, su llamada de cualquier manera). Como podrá ver por sí mismo si lo está siguiendo en casa, tenemos un símbolo del sistema de Linux normal y todo lo que Linux-y ahora es posible.

$ sudo lxc exec demo sh ~ # 

You could also run a single command without opening a full shell by typing the command instead of this sh.

$ sudo lxc exec demo ls / bin etc lib mnt proc run srv tmp var dev home media opt root sbin sys usr 

You can bail out of the shell any time you like using exit and return to your host. Here, besides listing running containers, I can also list any storage pools. The default pool that was created during initialization is there, and we can see where the disk image is stored. /var/lib/lxd is, by default, where all LXC resources are kept.

$ sudo lxc storage ls +---------+-------------+--------+--------------------------------+---------+ | NAME | DESCRIPTION | DRIVER | SOURCE | USED BY | +---------+-------------+--------+--------------------------------+---------+ | default | | btrfs | /var/lib/lxd/disks/default.img | 3 | +---------+-------------+--------+--------------------------------+---------+ 

I can similarly list all my networks. There happen to be a few network bridges on this system (I've been playing around a bit, as you can see). There's also the physical enp0s3 bridge used by the host Ubuntu server. Although between you and me, that one's not physical either, as this is actually a VM running in Oracle's Virtual Box.

$ lxc network ls +---------+----------+---------+-------------+---------+ | NAME | TYPE | MANAGED | DESCRIPTION | USED BY | +---------+----------+---------+-------------+---------+ | enp0s3 | physical | NO | | 1 | +---------+----------+---------+-------------+---------+ | lxdbr0 | bridge | YES | | 1 | +---------+----------+---------+-------------+---------+ | mynet | bridge | YES | | 0 | +---------+----------+---------+-------------+---------+ | testbr0 | bridge | YES | | 1 | +---------+----------+---------+-------------+---------+ 

If we needed to, we could easily add a new virtual interface to our container using the "lxc network attach" command. Here, I'll specify the physical network and then the name of our container.

$ lxc network attach enp0s3 demo 

With that done, you could open a new shell in the container to see what's changed. There should now be an eth1 interface listed. You may need to reboot for all the changes to take full effect. By doing that you can also marvel at just how fast this thing can reboot itself - for all intents and purposes, it'll happen faster than you can type your exec command to open a new shell.

Enjoy your new environment!

This article is based on content in my Pluralsight course, "Linux System Optimization." There's much more administration goodness in the form of books, courses, and articles available at bootstrap-it.com.