Exportando el servidor X a contenedores LXD

Supongamos la siguiente situación:
Estamos en nuestro equipo de desarrollo ejecutando Ubuntu desktop (esta solución la he validado con Ubuntu 16.04 y Ubuntu 18.04), tenemos el servicio de LXD operativo y queremos ejecutar una aplicación gráfica (como por ejemplo un IDE) dentro de un contenedor.

La solución pasa por utilizar el concepto de device passthrough que se muestra en traspaso de dispositivos en lxc para aplicarlo a lxd y traspasar los dispositivos relacionados al servidor X dentro del contenedor.

Mapeando el identificador de usuario al contenedor

Como primer paso, y por una única vez en la vida de nuestro sistema, debemos permitir que los procesos de root de los contenedores que vayamos a crear pueda mapearse con nuestro identificador de usuario. Esto se hace con el siguiente comando.

$ echo "root:$UID:1" | sudo tee -a /etc/subuid /etc/subgid
[sudo] contraseña para jose: 
root:1000:1

Crear el contenedor

Para este ejemplo crearemos un contenedor de nombre xtest con una imagen de Debian Stretch.

$ lxc launch images:debian/9 xtest
Creando xtest
Iniciando xtest

También, instalamos un entorno base mínimo para gestión de aplicaciones de escritorio.

$ lxc exec xtest -- apt update

[Update command output]

$ lxc exec xtest -- apt install x11-apps mesa-utils alsa-utils
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  bsdmainutils fontconfig-config fonts-dejavu-core groff-base kmod libasound2 libasound2-data libdrm-amdgpu1 libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libdrm2 libffi6
  libfftw3-single3 libfontconfig1 libfreetype6 libgdbm3 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libglew2.0 libglu1-mesa libgomp1 libice6 libllvm3.9 libpciaccess0
  libpipeline1 libpng16-16 libsamplerate0 libsensors4 libsm6 libtxc-dxtn-s2tc libx11-xcb1 libxaw7 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-sync1
  libxcursor1 libxdamage1 libxfixes3 libxft2 libxkbfile1 libxmu6 libxpm4 libxrender1 libxshmfence1 libxt6 libxxf86vm1 man-db ucf x11-common xbitmaps
Suggested packages:
  cpp wamerican | wordlist whois vacation groff libasound2-plugins libfftw3-bin libfftw3-dev glew-utils pciutils lm-sensors less www-browser
The following NEW packages will be installed:
  alsa-utils bsdmainutils fontconfig-config fonts-dejavu-core groff-base kmod libasound2 libasound2-data libdrm-amdgpu1 libdrm-intel1 libdrm-nouveau2 libdrm-radeon1
  libdrm2 libffi6 libfftw3-single3 libfontconfig1 libfreetype6 libgdbm3 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libglew2.0 libglu1-mesa libgomp1 libice6 libllvm3.9
  libpciaccess0 libpipeline1 libpng16-16 libsamplerate0 libsensors4 libsm6 libtxc-dxtn-s2tc libx11-xcb1 libxaw7 libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0
  libxcb-sync1 libxcursor1 libxdamage1 libxfixes3 libxft2 libxkbfile1 libxmu6 libxpm4 libxrender1 libxshmfence1 libxt6 libxxf86vm1 man-db mesa-utils ucf x11-apps
  x11-common xbitmaps
0 upgraded, 57 newly installed, 0 to remove and 0 not upgraded.
Need to get 27.7 MB of archives.
After this operation, 192 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
 
[Install command output]

Ajustes en el contenedor para soporte de aplicaciones gráficas

Ajustamos los mapeos dentro del contenedor según lo realizado en el primer punto.

$ lxc config set xtest raw.idmap "both $UID 1000"

Definimos la variable de entorno DISPLAY para que los procesos puedan hacer uso de las aplicaciones gráficas.

$ lxc config set xtest environment.DISPLAY ":0"

Transferimos los dispositivos asociados a los sockets que gestionan la comunicación con el servidor X.

$ lxc config device add xtest X0 disk path=/tmp/.X11-unix/X0 source=/tmp/.X11-unix/X0
Device X0 added to xtest
$ lxc config device add xtest Xauthority disk path=/root/.Xauthority source=${XAUTHORITY}
Device Xauthority added to xtest

Y finalmente, reiniciamos el contenedor.

$ lxc exec xtest -- poweroff
$ lxc start xtest

Validando la configuración

Una vez realizados todos los pasos anteriores, estamos en condiciones de ejecutar aplicaciones gráficas dentro del contenedor. Por ejemplo, si ejecutamos:

$ lxc exec xtest -- xclock

Veremos que se abre una ventana con un reloj analógico donde se ve la hora UTC del sistema (salvo que antes hayamos aplicado lo que se muestra en Localización y zona horaria en contenedores LXD).

José Administrator
Sorry! The Author has not filled his profile.
follow me

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *