Vagrant + libvirt - Configuración Completa de Networking y Almacenamiento
Resumen de una línea
Guía para usar Vagrant con libvirt/KVM en Linux, cobriendo configuración de redes, almacenamiento persistente y casos de uso prácticos.
¿Por Qué Vagrant + libvirt en Linux?
Comparativa de Providers en Linux
| Aspecto | VirtualBox | libvirt | Docker |
|---|---|---|---|
| Hardware | Virtualización completa | KVM nativo | Container |
| Rendimiento | 70-80% nativo | 95%+ nativo | 99%+ nativo |
| Recursos Host | ~1.5GB RAM por VM | ~512MB RAM por VM | ~50MB RAM |
| SO realista | ✅ Completo | ✅ Completo | ❌ Container |
| Daemon requerido | ❌ VirtualBox service | ✅ libvirtd | ✅ Docker daemon |
| Linux integration | External | Kernel nativo | External |
Conclusión: libvirt + Vagrant = eficiencia de KVM + automatización Vagrant
Instalación Vagrant + libvirt
Prerequisitos (Ubuntu/Debian)
# 1. KVM + libvirt
sudo apt-get install qemu qemu-kvm libvirt-daemon-system libvirt-clients
# 2. Vagrant
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get install vagrant
# 3. Plugin libvirt para Vagrant
vagrant plugin install vagrant-libvirt
# 4. Usuario en grupo libvirt (sin sudo)
sudo usermod -aG libvirt,kvm $USER
newgrp libvirtVerificar Instalación
vagrant plugin list
# vagrant-libvirt (0.x.x, system plugins)
virsh -c qemu:///system list
# Conecta a libvirt daemon
vagrant box list
# Muestra boxes descargadasConfiguración de Redes en Vagrant + libvirt
Tipos de Red en libvirt
┌─ Host
│
├─ Virbr0 (virtual bridge)
│ ├─ DHCP nativo
│ └─ VMs conectadas (NAT)
│
├─ Virbr1+ (bridges virtuales personalizados)
│ └─ Redes aisladas entre VMs
│
└─ Bridge físico (vmbr0)
└─ VMs accesibles desde host físicamente
1. Red NAT (Por Defecto)
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2004"
config.vm.provider "libvirt" do |libvirt|
# Esta es la red por defecto (virbr0 NAT)
# Acceso a internet ✅
# Acceso desde host: SSH solo via localhost:22
end
endCaracterísticas:
- ✅ Acceso saliente a internet
- ❌ No accesible desde host (excepto port forwarding)
- Múltiples VMs pueden coexistir
2. Red Privada (Host-only)
config.vm.network "private_network",
ip: "192.168.121.10",
libvirt__network_name: "vagrant-net"Resultado:
Host: 192.168.121.1 (gateway)
VM: 192.168.121.10
Ping: ✅ Funciona
SSH: ✅ ssh vagrant@192.168.121.10
Internet: ✅ Funciona (ruta via host)
Múltiples Redes Privadas:
config.vm.network "private_network", ip: "192.168.121.10"
config.vm.network "private_network", ip: "10.0.0.10"
# VM tiene 3 interfaces: eth0 (NAT), eth1 (192.168.121.x), eth2 (10.0.0.x)3. Red Pública (Bridge con Interfaz Host)
config.vm.network "public_network",
ip: "192.168.1.100",
netmask: "255.255.255.0",
gateway: "192.168.1.1",
dns_servers: ["8.8.8.8"],
libvirt__network_name: "default" # O tu bridge personalizadoResultado:
Host: 192.168.1.50 (en LAN)
VM: 192.168.1.100 (en LAN, ip fija)
Ping host: ✅ VM ve host
Ping VM: ✅ Host ve VM
Internet: ✅ Directo
4. Multi-VM con Networking
Vagrant.configure("2") do |config|
# Crear bridge personalizado para VMs comunicadas entre sí
config.vm.define "web" do |web|
web.vm.box = "generic/ubuntu2004"
web.vm.hostname = "web.local"
web.vm.network "private_network", ip: "192.168.121.10"
web.vm.provision "shell", inline: "apt-get update && apt-get install -y nginx"
end
config.vm.define "db" do |db|
db.vm.box = "generic/ubuntu2004"
db.vm.hostname = "db.local"
db.vm.network "private_network", ip: "192.168.121.20"
db.vm.provision "shell", inline: "apt-get update && apt-get install -y mysql-server"
end
config.vm.define "cache" do |cache|
cache.vm.box = "generic/ubuntu2004"
cache.vm.hostname = "cache.local"
cache.vm.network "private_network", ip: "192.168.121.30"
cache.vm.provision "shell", inline: "apt-get update && apt-get install -y redis-server"
end
end
# Resultado:
# web → 192.168.121.10 (Nginx)
# db → 192.168.121.20 (MySQL)
# cache → 192.168.121.30 (Redis)
#
# Todas se comunican internamente via IPs privadasUso:
vagrant up web db cache
# En la VM web:
vagrant ssh web
ping 192.168.121.20 # ✅ Ping a DB
mysql -h 192.168.121.20 -u root # ✅ Conectar a BD remotaAlmacenamiento Persistente en Vagrant + libvirt
Problema: Datos Efímeros
vagrant destroy
↓
Todos los datos de la VM → ❌ Eliminados
Solución: Volúmenes persistentes desacoplados de la VM
1. Volúmenes Adicionales (Block devices)
config.vm.provider "libvirt" do |libvirt|
# Volumen adicional de 10GB
libvirt.storage :file,
:size => '10G',
:type => 'qcow2'
# Segundo volumen de 5GB
libvirt.storage :file,
:size => '5G',
:type => 'qcow2'
end
# En la VM:
lsblk
# sda Disco OS
# sdb Primer volumen (10GB)
# sdc Segundo volumen (5GB)Setup del Volumen:
vagrant ssh
# En la VM:
sudo mkfs.ext4 /dev/sdb
sudo mkdir -p /data
sudo mount /dev/sdb /data
sudo chown vagrant:vagrant /data
df -h # ✅ /data disponiblePersistencia automática (Vagrantfile):
config.vm.provision "shell", inline: <<-SHELL
mkfs.ext4 -F /dev/sdb 2>/dev/null
mkdir -p /data
mount /dev/sdb /data
echo "/dev/sdb /data ext4 defaults 0 0" >> /etc/fstab
chown vagrant:vagrant /data
SHELL2. Carpetas Compartidas con NFS
config.vm.synced_folder ".", "/vagrant", type: "nfs"Ventajas:
- Más rápido que Guest Additions
- Compartir datos host-VM transparente
Requisito:
# Host: NFS server
sudo apt-get install nfs-kernel-server3. Snapshot: Backup Rápido
# Crear snapshot antes de cambios
virsh snapshot-create-as VM_NAME backup-preupgrade
# Listar snapshots
virsh snapshot-list VM_NAME
# Revertir
virsh snapshot-revert VM_NAME backup-preupgradeCasos Prácticos
Caso 1: Stack LEMP Completo
Vagrant.configure("2") do |config|
# Stack: Linux (Ubuntu) + Nginx + MySQL + PHP
config.vm.box = "generic/ubuntu2004"
config.vm.hostname = "lemp.local"
# Red privada (acceso desde host)
config.vm.network "private_network", ip: "192.168.121.50"
# Volumen persistente para MySQL
config.vm.provider "libvirt" do |libvirt|
libvirt.storage :file, :size => '20G', :type => 'qcow2'
end
# Carpeta compartida para código PHP
config.vm.synced_folder "code/", "/var/www/html", type: "nfs"
# Provisioning
config.vm.provision "shell", path: "provision-lemp.sh"
endCaso 2: Cluster Kubernetes Local
Vagrant.configure("2") do |config|
# Master
config.vm.define "k8s-master" do |master|
master.vm.box = "generic/ubuntu2004"
master.vm.hostname = "k8s-master"
master.vm.network "private_network", ip: "192.168.121.100"
master.vm.vm.provider "libvirt" do |libvirt|
libvirt.cpus = 4
libvirt.memory = 4096
end
master.vm.provision "shell", path: "init-master.sh"
end
# Workers
(1..2).each do |i|
config.vm.define "k8s-worker-#{i}" do |worker|
worker.vm.box = "generic/ubuntu2004"
worker.vm.hostname = "k8s-worker-#{i}"
worker.vm.network "private_network", ip: "192.168.121.#{110 + i}"
worker.vm.provision "shell", path: "init-worker.sh"
end
end
endTroubleshooting Común
Error: “No host memory available”
# Solución: Reducir RAM por VM
config.vm.provider "libvirt" do |libvirt|
libvirt.memory = 1024 # 1GB en lugar de 2GB
libvirt.cpus = 1 # 1 CPU en lugar de 2
endNFS timeout en carpetas compartidas
# Verificar NFS está ejecutándose
sudo systemctl status nfs-kernel-server
# Reiniciar NFS
sudo systemctl restart nfs-kernel-server
# O cambiar a rsync (más lento pero confiable)
config.vm.synced_folder ".", "/vagrant", type: "rsync",
rsync__exclude: [".git/", "node_modules/", ".DS_Store"]VM no tiene acceso a internet
# Verificar route
vagrant ssh
ip route
# Debe mostrar: default via 192.168.121.1 dev eth0
# Si no, reiniciar net
sudo netplan apply
sudo systemctl restart systemd-networkdRelaciones
Conecta con
- Vagrant - Introducción y Conceptos Fundamentales — Conceptos base
- KVM (Kernel-based Virtual Machine) — Backend de virtualización
- Redes en KVM - libvirt — Networking avanzado
- Almacenamiento en KVM - virt-manager — Volúmenes QCOW2, snapshots
- Ansible — Provisioning alternativo a shell scripts
Mejora a
- Introducción a la Virtualización con KVM - libvirt — Automatización de VMs
- Instalación y Configuración de virt-manager — Alternativa GUI (vs IaC)