Montar tus entornos de desarrollo con virt-manager

Durante el tiempo que estuve -por motivos profesionales- trasteando con plataformas de provisión de máquinas virtuales basadas en web, como OpenNebula, OpenStack y demás, nunca me imaginé que en realidad pudiera ser tan fácil como es con virt-manager. Aunque tiene truco, porque supongo que todo lo que sufrí peleando con OpenNebula me sirvió para adquirir algunos conocimientos que me han ayudado a saber como configurar bien virt-manager con KVM.

En el mundo del desarrollo web se han puesto de moda tropecientas tecnologías de virtualización o contenedores para llevarte los entornos de desarrollo y replicarlos en cualquier parte. Todas te prometerán el oro y el moro y la vida eterna, pero al final como lo que tú te montes y comprendas, nada. Lo digo porque estuve probando la máquina virtual Homestead para Laravel basada en Vagrant y al final aquéllo se convirtió en un engendro lento e inmanejable.

Tener un servidor aparte -cuya CPU tenga extensiones de virtualización- y con una cantidad generosa de RAM -vamos a hablar como mínimo de 4GiB para tener varias, pero con 2 GiB tiramos- es muy ventajoso para el desarrollo web, ya que te permitirá tener entornos aislados para tus aplicaciones y jugar un poco con el servidor, para convertirte en un afamado DevOps de esos que también están de moda, llenar tus bolsillos de dólares y trabajar en bañador desde Bali.

Hypes aparte, creo que es fundamental tener unos buenos conocimientos del sistema operativo y del software que da el servicio (Apache, Nginx, etc.) para tener una visión más completa de tu tarea como programador. Puede ser la diferencia entre tirarte horas buscando un error que no estaba en tu código (por ejemplo un fallo en la configuración de algún servidor) o saber al menos por donde pueden venir los tiros y buscar fuera de tu código.

Primero necesitamos una máquina que soporte virtualización a nivel de CPU, cualquier procesador de Intel o AMD relativamente moderno la soportará. El mio es de 2009 por ejemplo. Una buena manera de empezar a averiguarlo es esta:

cat /proc/cpuinfo | egrep '(vmx|svm)'

Si te devuelve algún resultado, vamos bien. Si no, todavía no desesperes, asegúrate buscando en la página del fabricante que tu micro tiene las extensiones y si las tiene, seguramente las tienes desactivadas en la BIOS. Cada marca tiene su propio flag indicando que tiene extensiones de virtualización. El flag vmx corresponde a Intel y svm a AMD. Mi procesador es un AMD Athlon(tm) X2 240, nada del otro mundo ;). Lo he tenido muchos años como equipo multimedia de salón y ahora ha cambiado de curro.

Mi configuración se basa en un Devuan Jessie [1] como host/anfitrión/servidor y máquinas virtuales (MVs) Devuan igualmente. Los mismos pasos funcionarán exactamente en Debian Jessie y seguramente en derivados como Ubuntu, sin mucha modificación o ninguna. No voy a detallar aquí consejos de seguridad para dejar bien el servidor, pero si quieres date un paseo por las entradas “Me voy a mi nube” [2] [3].

Instalamos el software necesario:

apt-get install virt-manager virt-goodies virt-top virt-viewer avahi-daemon bridge-utils ssh-askpass-gnome

Aparcamos un momento el software y vamos a dejar preparada la red. En este caso, se debe ocupar el sistema operativo, no debe haber ningún rastro de NetworkManager o similar. Es cierto que si quieres no tienes porque inhabilitar o desinstalar el NetworkManager del anfitrión, pero no lo vamos a necesitar y nos lo podemos ahorrar. Si el servicio NetworkManager detecta que una interfaz de red está configurada en /etc/network/interfaces ya no la tocará.

Así que tenemos que configurar la red al viejo estilo y además en modo puente. Esta es una de las mejores formas de configurar la interfaz de red física, porque vamos a conseguir que cualquier ordenador vea las máquinas virtuales con direcciones de nuestra propia red, a la vez que el anfitrión también conserva una dirección de la misma red. Y todo por la misma tarjeta de red física. Es como si asignásemos un número arbitrario de direcciones IP a la misma tarjeta física de red. Esto se consigue con el puente de red, que no es nada difícil de configurar ¡si sabes como! ;) Lo bueno es que con este escenario conseguimos:

  1. Que los clientes vean a las máquinas virtuales como máquinas de su propia red
  2. Que el anfitrión vea a las MVs y viceversa, como dentro de su propia red
  3. Y más interesante todavía, que las MVs se vean entre ellas
  4. Opcionalmente, que tus MVs puedan verse desde Internet

Es importante saber que esto lo podemos conseguir solo con una tarjeta de red física Ethernet, no wireless, ya que estas última no soportan bridging. Además, será recomendable que tanto tu router/switch como tu tarjeta y tu cable de red (aconsejo UTP5-e) te permitan sincronizarte a Gbit. Para comprobarlo simplemente lanza:

sudo ethtool eth0 | grep Speed

Si te ha sincronizado a 100Mb/s funcionará el tinglado, pero lo recomendable es alcanzar 1000Mb/s. En mi caso, debido al sitio donde tengo que tener el anfitrión debo conectarme mediante un par de dispositivos PLC y eso me baja la velocidad, pero todo funciona razonablemente bien.

Abrimos el archivo /etc/network/interfaces y ponemos una configuración tal que así:


auto br0
iface br0 inet static
address 192.168.0.160
network 192.168.0.0
netmask 255.255.255.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameservers 178.32.196.201 91.218.115.155
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
post-up ip link set br0 address 00:19:66:be:b5:ae

Tenemos que asegurarnos de eliminar o comentar cualquier referencia a eth0, no hay que tocarla, no se debe levantar ni con DHCP ni con dirección asignada estáticamente ni de ninguna otra manera, ya que el sistema se encargará de configurarla cuando vea que forma parte del puente. La única parque que quizá queráis modificar es la de address, que asigna la IP para el puente, esa es la dirección por la que accederemos a partir de ahora al anfitrión. Al cambiarla, también habría que modificar network, netmask, broadcast y gateway para que estén en consonancia. La última parte es útil porque fija una MAC para el puente y así la podremos utilizar para reservar en el router una IP “fija” para el puente. Lo explicaremos más adelante. Por cierto, los DNS los he cogido de opennicproject.org, pasa de que Google o tu proveedor te rastreen o capen.

La otra parte en la configuración de la red es contarle al kernel que permita IP forwarding. Voy a confesar que no se si es absolutamente necesario o si solo sirve en caso de quieras que el anfitrión haga de router para las MVs -que no es el caso- pero como puede ser útil y no molesta, lo ponemos. El archivo /etc/sysctl.conf es donde se configuran variables para pasarle al kernel. Lo editamos y descomentamos la siguiente línea:

net.ipv4.ip_forward=1

Los cambios ya son permanentes cada vez que reinicies, pero podemos activarlos sin tener que reiniciar de manera inmediata:

sudo sysctl -p

El cambio que sí es necesario implica variables que no podemos poner en el archivo anterior, me da la sensación de hay que aplicarlos después de la carga del módulo del kernel bridge. Por eso, veréis que si reiniciais el sistema e invocáis sysctl -p el puente funcionará bien, pero no antes. Para hacerlo permanente nos aprovechamos del sistema udev y creamos un archivo llamado /etc/udev/rules.d/99-bridge.rules y ponemos la siguiente regla:

ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"

Esto le informa dice al subsistema udev que cuando cargue el módulo bridge ejecute lo que haya en /etc/sysctl.d/bridge.conf, que es un archivo que también tenemos que crear y poner lo siguiente:

net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

Ya va estando listo todo lo principal. Antes de reiniciar y crear nuestra primera MV, vamos a hacer algunos ajustes más. El sistema virt-manager trae un estupendo cliente gráfico para gestionar las MVs, pero para usarlo con un usuario sin privilegios añadiremos tal usuario a los grupos libvirt y libvirt-qemu:

sudo usermod -a -G libvirt,libvirt-qemu usuario

El usuario usuario será uno que debes crear en el anfitrión para no tener que conectarte a él como root. Con esto, ha llegado el momento de reiniciar. Cuando esté, vamos a intentar conectarnos de forma remota por ssh redirigiendo las X para poder usar el cliente virt-manager del anfitrión sin tener que estar delante de él. De esta manera, el servidor no tiene por qué tener instalado un entorno de escritorio, aunque sí un sistema X11 mínimo con los paquetes xserver-xorg y x11-server-utils. Desde nuestro propio equipo lanzamos:

ssh -X usuario@anfitrion virt-manager

Es recomendable crear una entrada en el /etc/hosts del cliente para no tener que escribir siempre la IP del servidor y efectuar el intercambio de claves ssh para que no te pida siempre la clave del usuario usuario [4]. Si todo va bien y los servicios están levantados deberíamos ver esta ventana. Recordad que aunque veamos la ventana en nuestro PC, todas las acciones se están ejecutando en el servidor, es la “magia” de X11.

Cliente virt-manager
Cliente virt-manager

Crear una MV nueva es tan sencillo como Archivo > Nueva máquina virtual. Hay muchas opciones que hay que investigar. Para crear la máquina a partir de un archivo ISO de instalación éste deberá estar presente previamente en el disco del servidor, podemos descargarlo por ejemplo en /var/lib/libvirt/images/.

Seleccionando la ISO
Seleccionando la ISO

Es esencial indicar que queremos utilizar el puente br0 que habíamos creado antes para gestionar la red.

Configurando la red
Configurando la red

Cuando terminemos de crear la máquina el mismo cliente virt-manager nos mostrará la “pantalla” de la MVs a través del protocolo de pantalla remota SPICE, así podremos realizar fácilmente la instalación de Devuan en el disco duro virtual.

Personalmente me gusta configurar la red con direcciones dinámicas, pero asegurándome de que siempre reciben la misma. Para ello, cuando instalemos la MV nos aseguraremos de que la red se configura por DHCP. Luego nos tendremos que anotar la IP asignada por el router/switch (que no será otro que el mismo que usas cada día, que te puso tu proveedor, ya que recordemos que hay visibilidad) y la MAC que se le ha asignado. Cualquier router decente tiene fijación de IP. Solo tendrás que buscar la opción y configurar que para la MAC M quieres que siempre se asigne la IP I.

Tus MVs pueden sera ahora también accesibles desde internet fácilmente. Al ser visibles desde el router, solo tienes que redirigir el puerto exterior a un puerto interior de la MV, de esta manera, y completándolo con algún servicio de DNS dinámico como [5], podrás tener un acceso desde internet a tus servicios para poder mostrar tus proyectos o tener una nube privada bastante barata, aprovechando esa conexión tan rápida que te puso tu proveedor. Con una buena conexión de fibra de 300 Mbit de subida tus servicios irán como un cohete.

Por último, si quieres que la MV arranque automáticamente cada vez que inicies el anfitrión, tenemos el comando virsh, que entre otras cosas realiza esta tarea de forma limpia:

sudo virsh autostart NombreMV

¡PUBLICIDAD!

Si cuentas con un router más bien perruno, porque tu compañía sea de esa calaña, pregúntame por un router que me sobra, el Fritzbox 3272, con el firmware completamente actualizado y tal vez lleguemos a un acuerdo. Es alucinante todo lo que te permite https://es.avm.de/productos/fritzbox/fritzbox-3272/ y puedes usarlo conectándolo al humilde trasto que te puso tu proveedor.

Referencias

  1. Devuan
  2. Me voy a mi nube I
  3. Me voy a mi nube II
  4. Passwordless SSH
  5. nsupdate.info
  6. Ubuntu KVM networking
  7. Libvirt bridged networking

Responder

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