Introducción al uso de vagrant + libvirt + QEMU/KVM. Definición de redes.
En la entrada anterior: Introducción al uso de vagrant + libvirt + QEMU/KVM se hizo una introducción al uso de Vagrant para crear máquina virtuales usando libvirt y KVM. En esta entrada nos vamos a detener en los aspectos más interesantes para la definición de redes virtuales.
Red de mantenimiento
Como hemos visto en la entrada anterior, por defecto, las máquinas creadas por vagrant se conectan a una red de tipo NAT llamada vagrant-libvirt
cuya definición es la siguiente:
virsh -c qemu:///system net-dumpxml vagrant-libvirt
<network connections='1' ipv6='yes'>
<name>vagrant-libvirt</name>
<uuid>aa24398a-7495-45ef-bf88-5c2a49836c5c</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr1' stp='on' delay='0'/>
<mac address='52:54:00:fc:db:97'/>
<ip address='192.168.121.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.121.1' end='192.168.121.254'/>
</dhcp>
</ip>
</network>
Esta conexión es utilizada por vagrant para acceder a la máquina cuando ejecutamos vagrant ssh
y al ser de tipo NAT con DHCP, posibilita que nuestra máquina tenga acceso a internet. Como vemos la ruta por defecto de la máquina es la siguiente:
$ ip r
default via 192.168.121.1 dev eth0
192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.2
Podemos comprobar en el archivo /etc/network/interfaces
que la interfaz eth0 se configura de forma dinámica:
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
Podemos cambiar la red de mantenimiento si nos interesa, añadiendo al Vagrantfile
el nombre de la red a la que se debe conectar y su direccionamiento:
...
config.vm.provider :libvirt do |libvirt|
libvirt.management_network_name = "default"
libvirt.management_network_address = '192.168.122.0/24'
end
...
Tenemos que tener en cuenta que todas las máquinas van a tener una interfaz de red de tipo NAT, que le dan direccionamiento por DHCP y le posibilitan acceder al exterior. En determinados escenarios deberemos no tener en cuenta en esta interfaz, por ejemplo cambiando la ruta por defecto para que la máquina no salga por esta interfaz.
Redes privadas de tipo NAT con DHCP
Podemos hacer que una máquina se conecte a otra red privada de tipo NAT, configurando lo siguiente en el Vagrantfile
:
...
config.vm.network :private_network,
:type => "dhcp",
:libvirt__network_address => '192.168.200.0'
...
Al iniciar el escenario, se crea una red llamada vagrant-private-dhcp
con la siguiente definición:
<network connections='1' ipv6='yes'>
<name>vagrant-private-dhcp</name>
<uuid>989bc924-adba-42f5-9b29-3a0fe54b157c</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr2' stp='on' delay='0'/>
<mac address='52:54:00:a4:b9:99'/>
<ip address='192.168.200.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.200.1' end='192.168.200.254'/>
</dhcp>
</ip>
</network>
Podemos configurar el rango del DHCP, con los parámetros :libvirt__dhcp_start
y :libvirt__dhcp_stop
, y la ip que toma el host con :libvirt__host_ip
.
Podemos comprobar que la máquina creada ha configurado otra interfaz por DHCP en el fichero /etc/network/interfaces
:
auto eth1
iface eth1 inet dhcp
Redes privadas de tipo NAT con ip estática
Podemos configurar una red de tipo NAT pero indicando una ip estática en la máquina virtual creada, para ello añadimos al Vagrantfile
:
config.vm.network :private_network,
:libvirt__dhcp_enabled => false,
:ip => "10.20.30.40"
Al crear el escenario se crea una red cuyo nombre es igual al directorio donde esta el Vagrantfile
seguido de un número, en mi caso ej10
con la siguiente definición:
<network connections='1' ipv6='yes'>
<name>ej10</name>
<uuid>b1b9622b-1473-48f9-a3bb-c2f7b8fdc0e1</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr2' stp='on' delay='0'/>
<mac address='52:54:00:e7:36:46'/>
<ip address='10.20.30.1' netmask='255.255.255.0'>
</ip>
</network>
Y podemos comprobar que la segunda interfaz se ha configurado de forma estática en la máquina creada, mirando el fichero /etc/network/interfaces
:
auto eth1
iface eth1 inet static
address 10.20.30.40
netmask 255.255.255.0
Nota: Si no indicamos el parámetro :libvirt__dhcp_enabled => false
la red tendrá un servidor DHCP, pero el escenario seguirá funcionando de forma adecuada ya que la configuración de la interfaz se hace de forma estática.
Red aislada (isolated)
Para crear una red aislada entre dos máquinas, configuramos el siguiente Vagrantfile
:
Vagrant.configure("2") do |config|
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bullseye64"
nodo1.vm.hostname = "nodo1"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => "red1",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.10",
:libvirt__forward_mode => "none"
end
config.vm.define :nodo2 do |nodo2|
nodo2.vm.box = "generic/ubuntu2010"
nodo2.vm.hostname = "nodo2"
nodo2.vm.synced_folder ".", "/vagrant", disabled: true
nodo2.vm.network :private_network,
:libvirt__network_name => "red1",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.11",
:libvirt__forward_mode => "none"
end
end
Como son redes aisladas es importante ponerle un nombre (:libvirt__network_name
) para asegurarnos que las dos máquinas están conectas a la misma red. La red red1
se crea con la siguiente definición:
<network connections='2' ipv6='yes'>
<name>red1</name>
<uuid>e102c6f4-5837-41ea-9acd-a62b61563e79</uuid>
<bridge name='virbr2' stp='on' delay='0'/>
<mac address='52:54:00:c8:da:72'/>
<ip address='10.0.0.1' netmask='255.255.255.0'>
</ip>
</network>
Red aislada (very isolated)
Si nos damos cuenta a esta red aislada estará conectada los dos nodos y el host, para que el host no se conecte podemos indicar veryisolated
en el parámetro :libvirt__forward_mode
y se crearía la siguiente red:
<network connections='2' ipv6='yes'>
<name>red1</name>
<uuid>18911d36-10fa-4bb4-9605-d7fb7c397378</uuid>
<bridge name='virbr5' stp='on' delay='0'/>
<mac address='52:54:00:2c:94:d7'/>
</network>
Y nos aseguremos que sólo las máquinas estén conectada a esta red, el host no estará conectado.
Redes públicas
Para crear una red pública desde vagrant necesitamos un bridge externo (por ejemplo que se llame br0
) que este configurado en nuestro host. En el Vagrantfile
configuraremos una red pública de la siguiente manera:
...
config.vm.network :public_network,
:dev => "br0",
:mode => "bridge",
:type => "bridge"
En este caso podemos comprobar que la máquina tiene una segunda interfaz que está conectada a la red del host:
$ ip a
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:39:75:df brd ff:ff:ff:ff:ff:ff
altname enp0s6
altname ens6
inet 192.168.100.250/24 brd 192.168.100.255 scope global dynamic eth1
...
Desde el host podemos comprobar las interfaces conectadas al bridge externo:
$ brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.32a20d0ddc35 no enp5s0
vnet53
La interfaz vnet53
corresponde a la de la máquina virtual.
Conclusiones
En esta entrada hemos hecho una introducción a la definición de redes virtuales usando vagrant y libvirt/kvm. Como simpre si quieres seguir profundizando en el tema te sugiero la documentación de redes de libvirt/kvm: Networking y la documentación oficial del plugin de vagrant: vagrant-libvirt.
Leave a Comment
Your email address will not be published. Required fields are marked *