Laboratorio multi maquina con Vagrant

Cuando quieres hacer pruebas que involucran varios servidores, seria muy cómodo poder montar varias maquinas virtuales en tu PC para no tener ningún coste de hosting durante las pruebas.

Laboratorio multi maquina con Vagrant

Vagrant es una herramienta gratuita que te permite crear rápidamente máquinas virtuales nuevas de la nada. Incluso puede hacer girar varias máquinas virtuales al mismo tiempo.

Este artículo es un tutorial paso a paso para pasar de la nada a tener un Laboratorio multi maquina con Vagrant

El objetivo 

Al final de este tutorial, tendremos 3 máquinas virtuales, una llamada “master” y dos nodos, que pueden encontrarse entre sí a través de sus nombres de host. A excepción de Vagrant y Oracle VirtualBox, no se requiere ningún software externo para realizar el tutorial.

La configuración que vamos a crear es sólo una base sobre la que puedes obtener la infraestructura para hacer algo significativo.

Si sólo te interesa el resultado final, salta a la sección “Poniendo todo junto“.

Notas antes de empezar tu laboratorio multi maquina con Vagrant

Para poder seguir este tutorial, es útil que tengas un conocimiento básico de lo siguiente:

  • Cómo interactuar con la línea de comandos de su sistema operativo – ya que Vagrant se controla desde la línea de comandos.
  • Para qué sirve SSH.
  • Qué son las máquinas virtuales en general.

Si quieres convertirte en un Ingenios@ de Sistemas, consigue gratis el eBook y aprende como configurar tu laboratorio virtual para poder aprender.

Para Vagrant te recomiendo que tengas una conexión rápida a internet. Las VMs creadas por Vagrant se descargan de internet y suelen ser de 600 MB o más. Una conexión de internet lenta funcionará pero tendrás que esperar mucho tiempo para que las descargas terminen.

En cuanto a las versiones de software, este tutorial fue probado con Vagrant 2.2.19 y VirtualBox 6.1.

Instalación 

Para poder utilizar Vagrant se necesitan dos cosas: El propio Vagrant y un hipervisor.

Como hipervisor, puedes elegir entre VirtualBox, VMWare (Fusion) e Hyper-V.

La opción más sencilla es VirtualBox. Es gratuito y está disponible en todas las plataformas.

Si tienes VMWare Fusion instalado en tu Mac, ten en cuenta que el proveedor de VMWare para Vagrant cuesta dinero – incluso si ya tienes una licencia de VMWare Fusion. Si no quieres gastar dinero, simplemente usa VirtualBox. Se puede instalar junto con VMWare Fusion.

Para verificar que Vagrant está instalado, escriba en la línea de comandos:

vagrant -v

Resultado

Vagrant 2.2.19

Interactuar con tu primera máquina virtual 

Para iniciar tu primera VM, primero crea un directorio vacío en algún lugar y posicionate en el con la línea de comandos.

A continuación, ejecuta el siguiente comando:

vagrant init bento/ubuntu-20.04

Y una vez que has obtenido la respuesta de que se ha creado un fichero Vagrant en el directorio, puedes arrancar la maquina

vagrant up

Esto iniciará una máquina virtual con Ubuntu 20.04..

Nota: Si estás usando Hyper-V en lugar de VirtualBox, tienes que llamar a vagrant up –provider=hyperv en lugar de sólo vagrant up. Alternativamente, puedes querer configurar Hyper-V como el proveedor por defecto para Vagrant. Ver este artículo sobre cómo hacer esto.

Para entrar en la máquina virtual, ejecuta:

vagrant ssh

Para salir de la VM, pulsa Ctrl + D.

Para detener y eliminar todo el VM, ejecuta:

vagrant destroy -f

Esto eliminará la VM y todos sus recursos (es decir, el disco duro virtual de la maquina) de su ordenador, por lo que todo lo que hayas instalado en esta maquina se perderá.

El archivo Vagrant 

Cuando llamaste antes a vagrant init hashicorp/precise64, Vagrant creó un archivo llamado Vagrantfile en el directorio actual.

Este archivo es todo lo que Vagrant necesita para hacer su trabajo.

El archivo creado por vagrant init contiene mucha documentación y es un buen punto de partida para personalizar la VM.

Sin embargo, a efectos de este tutorial, vamos a reducir el archivo a su mínima expresión:

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-20.04"
end

En la segunda línea puedes ver el valor que pasaste antes a vagrant init: bento/ubuntu-20.04

Este es el nombre de la imagen base ( piensa: disco duro virtual) utilizada para la creación de la VM. Dicha imagen se llama caja en la terminología de Vagrant.

Cuando Vagrant crea una VM a partir de una caja (imagen base), en realidad crea una copia de esta imagen. Por lo tanto, cualquier cambio realizado dentro de la VM se pierde cuando la VM es destruida (a través de vagrant destroy). Una VM no puede modificar su imagen base.

Elección de la caja adecuada (imagen de base) 

Las cajas Vagrant se descargan por defecto del sistema Atlas de HashiCorp. Todas las cajas disponibles se pueden buscar aquí:

Para un único sistema operativo específico suele haber muchas cajas entre las que elegir. Por ejemplo, la búsqueda de una caja de Ubuntu 20.04 devuelve (entre otras):

  • generic/ubuntu2004
  • ubuntu/focal64
  • bento/ubuntu-20.04
  • abi/ubuntu2004

Desafortunadamente, las cajas en Atlas difieren en calidad ya que cualquiera puede subir una caja. Una caja de baja calidad te impide utilizar las características de Vagrant, como establecer el nombre de host de la VM o crear una red privada.

Durante mis pruebas encontré que las cajas de ubuntu/… tienen una calidad muy baja (lo cual es sorprendente dado que son creadas por Canonical, la compañía detrás de Ubuntu).

Además, HashiCorp (la compañía detrás de Vagrant) sólo proporciona cajas para Ubuntu 18.04. Así que tampoco pueden ser seleccionados como fuente de cajas de alta calidad.

La documentación de Vagrant sobre las cajas oficiales recomienda utilizar las cajas del espacio de nombres bento.

Durante mis pruebas (limitadas) funcionaron sin problemas y por eso son mi recomendación también. Los usaremos para el resto del tutorial. Puedes encontrarlos aquí:

Actualización de una VM después de que el archivo de Vagrant haya cambiado 

La modificación de un Vagrantfile mientras tu VM se está ejecutando no tiene ningún efecto sobre la VM en ejecución.

Para “sincronizar” la VM con su Vagrantfile, puedes

  1. ejecutar el comando vagrant reload o
  2. ejecutar vagrant destroy -f seguido de vagrant up

Para simplificar las cosas, te recomiendo que utilices la segunda opción para este tutorial.

Nota: Si estás utilizando el aprovisionamiento (ver más abajo) y has cambiado los datos de aprovisionamiento, necesitas llamar a vagrant reload –provision en el primer caso.

Multi-Máquina: La manera ingenua 

Hasta ahora siempre hemos empezado con una sola máquina virtual.

También podemos iniciar múltiples VMs con un solo Vagrantfile. Esto se llama Multi-Máquina.

La forma más fácil (o más ingenua) de crear una máquina múltiple es con un Vagrantfile como este:

Vagrant.configure("2") do |config|
  config.vm.define "master" do |subconfig|
    subconfig.vm.box = "bento/ubuntu-16.04"
  end

  config.vm.define "nodo1" do |subconfig|
    subconfig.vm.box = "bento/ubuntu-16.04"
  end

  config.vm.define "nodo2" do |subconfig|
    subconfig.vm.box = "bento/ubuntu-16.04"
  end
end

Esto creará 3 VMs (master, nodo1, nodo2).

Para acceder por ssh a cualquiera de las máquinas virtuales, basta con especificar su nombre. Por ejemplo, para hacer ssh en el nodo1, ejecuta:

vagrant ssh nodo1

Para destruir todas las máquinas virtuales, basta con llamar:

vagrant destroy -f

Este es exactamente el mismo comando que para una sola VM.

Multi-Máquina: La manera inteligente 

El anterior Vagrantfile multimáquina tenía mucho código repetido.

La misma configuración también puede describirse de forma más “programática”:

BOX_IMAGE = "bento/ubuntu-20.04"
NODE_COUNT = 2

Vagrant.configure("2") do |config|
  config.vm.define "master" do |subconfig|
    subconfig.vm.box = BOX_IMAGE
  end
  
  (1..NODE_COUNT).each do |i|
    config.vm.define "nodo#{i}" do |subconfig|
      subconfig.vm.box = BOX_IMAGE
    end
  end
end

Aquí tenemos:

  • Se ha movido el nombre de la caja a una constante (BOX_IMAGE).
  • Convertimos las definiciones “nodoX” en un bucle for each donde NODE_COUNT describe el número de nodos a crear.

Conexión de las máquinas virtuales a través de la red 

La configuración de la sección anterior creó 3 VMs. Sin embargo, hasta ahora estas VMs no tenían forma de comunicarse entre sí.

Importante: Antes de hacer esta sección, por favor ejecuta vagrant destory -f. Esto facilita las cosas.

Para solucionar esto necesitamos tres cosas.

En primer lugar, cada VM necesita un nombre de host único. Por defecto, cada una de las VMs tiene el mismo nombre de host (vagrant). Para cambiar esto, tenemos que añadir una configuración como la siguiente a cada definición de VM en el Vagrantfile:

subconfig.vm.hostname = "a.host.name"

A continuación, necesitamos una forma de obtener la dirección IP de un nombre de host. Para ello, utilizaremos el DNS – o mDNS para ser más precisos.

En Ubuntu, mDNS es proporcionado por Avahi. Para instalar Avahi en cada nodo, utilizaremos la función de aprovisionamiento de Vagrant.

Antes del último final en el Vagrantfile, añadiremos este bloque de código:

config.vm.provision "shell", inline: <<-SHELL
  apt-get install -y avahi-daemon libnss-mdns
SHELL

Esto llamará a apt-get install -y avahi-daemon libnss-mdns en cada VM.

Nota: Por defecto, el aprovisionamiento sólo se realiza la primera vez que se sube un vagrant.

Por último, tenemos que conectar las máquinas virtuales a través de una red privada.

Para cada VM, necesitamos añadir una configuración como esta (donde cada VM tendrá una dirección ip diferente):

subconfig.vm.network :private_network, ip: "10.0.0.10"

Juntando todo lo mencionado en la sección anterior se obtiene un Vagrantfile como este:

Poniendo todo junto

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
BOX_IMAGE = "bento/ubuntu-20.04"
NODE_COUNT = 2

Vagrant.configure("2") do |config|
  config.vm.define "master" do |subconfig|
    subconfig.vm.box = BOX_IMAGE
    subconfig.vm.hostname = "master"
    subconfig.vm.network :private_network, ip: "10.0.0.10"
  end
  
  (1..NODE_COUNT).each do |i|
    config.vm.define "node#{i}" do |subconfig|
      subconfig.vm.box = BOX_IMAGE
      subconfig.vm.hostname = "node#{i}"
      subconfig.vm.network :private_network, ip: "10.0.0.#{i + 10}"
    end
  end

  # Install avahi on all machines  
  config.vm.provision "shell", inline: <<-SHELL
    apt-get install -y avahi-daemon libnss-mdns
  SHELL
end

Ahora puedes ejecutar vagrant up y luego hacer vagrant ssh en cualquiera de las VMs:

vagrant ssh nodo1

Desde ahí puedes hacer ping a cualquier otra VM usando su nombre de host (más .local al final):

ping nodo2.local

ya tienes tu laboratorio de tres maquinas, ahora ya puedes experimentar con sistemas mas complejos, cluster de base de datos, cluster de almacenamientos, sincronización de ficheros entre maquinas, balanceo de carga, todo lo que se te ocurra.

¡Que tengas un Ingenioso día!

¡que tengas un ingenioso día!

Contrata tu plan Ingenios@ de Sistemas por 5€ al mes y responderé a todas tus preguntas sobre tecnología en el menor tiempo posible. Pasa a formar parte de la comunidad Ingenios@s de Sistemas y disfruta de contenido exclusivo y aprende sobre sistemas Open Source, Blockchain, SmarContract, Web3, Inteligencia Artificial y Reaidad Virtual, súbete al tren de la Revolución 4.0

Si quieres estar al día y no perderte nada Suscribete al Podcast Ingenios@s de Sistemas, un episodio diario que te mantendrá informado y formado en esta vertiginosa carrera.

Deja un comentario

Share to...