Aislar entornos de desarrollo con contenedores LXD

Hablaré sobre un enfoque para organizar entornos de desarrollo locales aislados en mi estación de trabajo. El enfoque se desarrolló bajo la influencia de los siguientes factores:

  • Diferentes idiomas requieren diferentes IDE y cadenas de herramientas;
  • Diferentes proyectos pueden utilizar diferentes versiones de cadenas de herramientas y bibliotecas.

El enfoque consiste en desarrollar dentro de contenedores LXD que se ejecutan localmente en una computadora portátil o estación de trabajo con la salida de gráficos redirigida al host.

Configuración de ejemplo Ubuntu 20.04.

Al final del artículo se ofrecen reflexiones sobre las opciones y los motivos.

1. Instalación LXD

В Ubuntu 20.04 LXD ya no está disponible para su instalación como paquete deb, solo a través de snap:

$ snap install lxd

Después de la instalación, debe realizar la inicialización:

$ lxd init

El único parámetro que cambio es storage bakend - Yo suelo dir como el más simple. Como no uso fotografías ni copias, las advertencias en documentación No me asustan:

De manera similar, el backend del directorio debe considerarse como una opción de último recurso.
Es compatible con todas las funciones principales de LXD, pero es terriblemente lento e ineficiente ya que no puede funcionar.
copias instantáneas o instantáneas y, por lo tanto, necesita copiar todo el almacenamiento de la instancia cada vez.

2. Configuración del perfil LXD

Perfiles en LXD — estos son conjuntos de parámetros aplicados a varios contenedores. Para mis necesidades, el único perfil creado por defecto me basta default con los siguientes cambios:

  • $ lxc profile device add default X0 disk source=/tmp/.X11-unix/X0 path=/tmp/.X11-unix/X0 — para que las aplicaciones en contenedores puedan interactuar con el servidor host X11;
  • $ lxc profile set default environment.DISPLAY :0 - para que la variable ambiental DISPLAY se instaló correctamente en contenedores;
  • $ lxc profile set default raw.idmap "both 1000 1000" - por lo correcto mapeo de identificadores.

3. Crear y configurar un contenedor

Crear un contenedor basado en una imagen images:ubuntu/20.04:

$ lxc launch images:ubuntu/20.04 dev1

Prefiero imágenes del repositorio. https://images.linuxcontainers.org, ya que tienen menos software preinstalado. Por esta razón agregué el prefijo images: al nombre de la imagen. La creación de un contenedor basado en una imagen del repositorio de Ubuntu se puede realizar de la siguiente manera: $ lxc launch ubuntu/20.04 dev1.

Acceso al shell raíz del contenedor:

$ lxc exec dev1 -- bash

Instalaré Firefox y VS Code (desde el repositorio de acuerdo a las instrucciones):

$ apt update
$ apt install curl gpg firefox

$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
$ install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list

$ apt update
$ apt install code

Incluiré un contenedor para mayor claridad.

poweroff

Bonus! Es bastante fácil colocar una GPU en un contenedor para que las aplicaciones que se ejecutan en él puedan usar la tarjeta gráfica. Para hacer esto necesitas:

  • añadir dispositivo $ lxc config device add dev1 mygpu gpu;
  • Instale los controladores de la tarjeta de video en el contenedor, los mismos que están instalados en el host.

4. Usando un contenedor

Si el contenedor aún no se está ejecutando, debe iniciarlo:

lxc start dev1

Ejecutar VS Code como usuario no root Ubuntu:

lxc exec dev1 -- sudo --login --user ubuntu code

Inicie Firefox:

lxc exec dev1 -- sudo --login --user ubuntu firefox

Las ventanas de la aplicación se mostrarán en el host, pero se ejecutarán dentro del contenedor, de forma similar al reenvío de gráficos mediante ssh.

No cierro manualmente los contenedores en ejecución porque no le veo mucho sentido: me limito a cerrar las ventanas de las aplicaciones en ejecución.

5. Заключение

Prefiero no utilizar un sistema operativo host para el desarrollo, ya que esto requeriría instalar herramientas de desarrollo, depurar versiones de bibliotecas, configurar componentes del sistema de una manera específica y otras manipulaciones. Todo esto puede provocar un comportamiento inesperado en otro software que no sea de desarrollo, o incluso en todo el sistema operativo. Por ejemplo, los cambios en la configuración de OpenSSL pueden hacer que el sistema operativo deje de iniciarse correctamente.

Probé diferentes herramientas para aislar entornos de desarrollo:

  • las máquinas virtuales (KVM, VirtualBox, etc.) son la opción más obvia, pero consumen muchos más recursos, aunque no existen otras opciones para desarrollar en Windows (si el host es Linux);
  • herramientas de desarrollo en la nube que se ejecutan en una máquina local (Cloud9 en un contenedor o máquina virtual, Eclipse Che, etc.): no están desarrolladas para este modo de operación, requieren configuración y mantenimiento adicionales, es mejor usarlas para el fin previsto propósito - en la nube;
  • Los contenedores Docker nuevamente están destinados a otra cosa; en mi opinión, no son muy convenientes para crear prototipos rápidamente utilizando software que aún no está empaquetado en contenedores separados.

El enfoque elegido me impresiona por su simplicidad y su baja barrera de entrada. En los propios contenedores, puede utilizar enfoques específicos del proyecto: instalar y configurar todo manualmente, o utilizar la automatización (Puppet, Ansible, etc.), incluso implementar Infraestructura basada en Docker. También uso contenedores LXD para ejecutar software específico que requiere instalar una gran cantidad de dependencias o una versión diferente del sistema operativo; en este caso, puede crear un contenedor con la versión del sistema operativo deseada, por ejemplo. $ lxc launch images:ubuntu/16.04 dev16.

Es importante recordar que, en términos de aislamiento, la contenedorización tiene una superficie de ataque mayor en comparación con la virtualización: el host y el contenedor comparten un único núcleo, una vulnerabilidad que puede permitir que el malware escape del contenedor. Al experimentar con software dudoso, es mejor utilizar mecanismos de aislamiento más adecuados.

Enlaces de interés

Fuente: habr.com

Añadir un comentario