Introducción a Vagrant

per Victor Carceler darrera modificació 2021-07-15T17:17:17+02:00

logo-hashicorp.svg

Vagrant es una herramienta libre para la creación y el trabajo con entornos de desarrollo. Estos entornos de desarrollo se sustentan sobre alguna herramienta de virtualización como VirtualBox, libvirt o Docker, por lo que en la práctica Vagrant nos va a permitir definir en un fichero Vagrantfile nuestra infraestructura.

A partir del fichero Vagrantfile la herramienta vagrant se encargará de:

  • Descargar las imágenes necesarias
  • Construir las MVs con la configuración especificada
  • Ejecutar las tareas necesarias para instalar software en su interior, crear usuarios, ...
  • La gestión (creación, encendido, guardado, detención y destrucción) de las MVs
  • Compartir el directorio del proyecto con las MVs
  • Gestionar el acceso con ssh

De esta manera es muy sencillo desplegar infraestructura a partir de un fichero y, cuando ya no sea necesaria, borrar el directorio del proyecto y dejar la máquina límpia.

Un directorio para el proyecto

Para cada proyecto vagrant utiliza un directorio, como ejemplo podemos crear el directorio ubuntu-focal para trabajar con una MV de Ubuntu 20.04 Focal Fossa.

[vcarceler@alumne-1-58 ~]$ mkdir ubuntu-focal
[vcarceler@alumne-1-58 ~]$ cd ubuntu-focal/

La configuración del proyecto se escribe en el fichero Vagrantfileque podemos crear directamente con el comando vagrant init <box> indicando una de las MVs que se encuentran en Vagrant Cloud. Por ejemplo, la distribución Ubuntu mantiene imágenes oficiales en https://app.vagrantup.com/ubuntu.

[vcarceler@alumne-1-58 ubuntu-focal]$ vagrant init ubuntu/focal64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
[vcarceler@alumne-1-58 ubuntu-focal]$ ll
total 4
-rw-rw-r--. 1 vcarceler vcarceler 3020 15 jul. 14:23 Vagrantfile
[vcarceler@alumne-1-58 ubuntu-focal]$

Ahora podemos levantar toda la infraestructura (añadiendo el parámetro --provider=virtualbox porque en algunas máquinas el provider por defecto es libvirt) con vagrant up:

[vcarceler@alumne-1-58 ubuntu-focal]$ vagrant up --provider=virtualbox
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/focal64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/focal64' version '20210709.0.0' is up to date...
==> default: Setting the name of the VM: ubuntu-focal_default_1626352374768_57256
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
default: /vagrant => /home/vcarceler/ubuntu-focal
[vcarceler@alumne-1-58 ubuntu-focal]$

Este comando descarga (las máquinas descargadas se guardan en ~/.vagrant.d/) —si es necesario— la máquina utilizada, crea una MV en VirtualBox, la configura, la enciende y la prepara con la clave pública del host para poder iniciar sesión con ssh.

[vcarceler@alumne-1-58 ubuntu-focal]$ vagrant ssh
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-77-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Thu Jul 15 12:38:47 UTC 2021

  System load:  0.0               Processes:               110
  Usage of /:   3.2% of 38.71GB   Users logged in:         0
  Memory usage: 19%               IPv4 address for enp0s3: 10.0.2.15
  Swap usage:   0%


1 update can be applied immediately.
To see these additional updates run: apt list --upgradable


vagrant@ubuntu-focal:~$ 

Además por defecto se ha compartido el directorio del proyecto (~/ubuntu-focal) entre la máquina física y la máquina virtual. Así resulta muy sencillo compartir ficheros pues el directorio del proyecto estará montado en la MV en el directorio /vagrant:

vagrant@ubuntu-focal:~$ ll /vagrant
total 8
drwxrwxr-x 1 vagrant vagrant 38 Jul 15 12:32 ./
drwxr-xr-x 20 root root 4096 Jul 15 12:33 ../
drwxrwxr-x 1 vagrant vagrant 32 Jul 15 12:32 .vagrant/
-rw-rw-r-- 1 vagrant vagrant 3020 Jul 15 12:23 Vagrantfile
vagrant@ubuntu-focal:~$

El comando vagrant status nos mostrará información sobre el estado de nuestras MVs y las podremos detener con vagrant halt o suspender con vagrant suspend. En cualquier caso se podrán volver a encender con vagrant up.

Cuando ya no sean necesarias las MVs se podrán borrar con vagrant destroy.

Algunas opciones básicas de Vagrantfile

El entorno que prepara vagrant está definido en el fichero Vagrantfile del proyecto. Se puede consultar la documentación sobre los ficheros Vagrantfile en https://www.vagrantup.com/docs/vagrantfile.

El fichero Vagrantfile creado de manera automática en el paso anterior tiene muchas líneas comentadas que muestran cómo realizar algunas operaciones sencillas.

Memoria asignada a la MV

La configuración por defecto de nuestro Vagrantfile no especifica la cantidad de memoria para nuestra máquina virtual así que se utiliza 1GiB.

Pero podemos descomentar las siguientes líneas de nuestro fichero Vagrantfile y cambiar especificar el valor de memoria para nuestra máquina.

   config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
# vb.gui = true

# Customize the amount of memory on the VM:
vb.memory = "2048"
end

Preparar la MV una vez creada

Una vez creada la MV a partir de la imagen oficial se tendrá que preparar de alguna manera para que cumpla la función esperada por el usuario.

Para esta tarea vagrant utiliza diferentes provisioners entre los que se encuentra el shell y Ansible. Con ellos se puede especificar cualquier tarea automática que se deba realizar para preparar las MVs.

Por ejemplo, si quisiéramos instalar un servidor web Apache en nuestra MV podremos encontrar un ejemplo comentado en nuestro Vagrantfile.

Si descomentamos las siguientes líneas:

  config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y apache2
SHELL

Se instalará el servidor web Apache de manera automática al crear el entorno, aunque sin añadir una redirección para un puerto o una nueva interfaz todavía no será posible acceder al servidor web desde nuestra máquina.

Redirección de puertos

La manera más sencilla de acceder a un servicio, como nuestro servidor Apache, que se ejecuta en la MV consiste en redirigir el tráfico de un puerto de nuestra máquina física a la MV.

Como ya resulta habitual encontraremos un ejemplo preparado en nuestro Vagrantfile que precisamente redirige el tráfico del puerto 8080 TCP de nuestra máquina física al puerto 80 TCP de la MV.

Para hacer visible el servidor Apache de la MV en http://localhost:8080 de la máquina física únicamente tendremos que descomentar la siguiente línea:

  # Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
config.vm.network "forwarded_port", guest: 80, host: 8080

Red privada

También es posible añadir una nueva interfaz de red a la MV en una red privada diferente de la red a la que está conectado el ordenador anfitrión.

Descomentando la siguiente línea del fichero Vagrantfile:

  # Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"

Se añadirá una nueva interfaz de red a la MV con la IP 192.168.33.10 y en el equipo anfitrión se añadirá automáticamente una interfaz de red vboxnet0 (si es la primera) con la IP 192.168.33.1 para permitir la comunicación.

La red privada también puede servir para comunicar diferentes MVs que se ejecutan en el equipo.

Vagrant sabe como configurar la red en diferentes sistemas operativos, por ejemplo en nuestro Ubuntu 20.04 se ha añadido el fichero /etc/netplan/50-vagrant.yaml con la configuración de la nueva interfaz:

---
network:
version: 2
renderer: networkd
ethernets:
enp0s8:
addresses:
- 192.168.33.10/24

También será posible asignar las direcciones de manera automática utilizando:

config.vm.network "private_network", type: "dhcp"