img

Objetivo:

En el siguiente artículo, veremos una serie de Talleres sobre la virtualización en Linux, de distintas formas, usando desde QEMU/KVM, libvirt, pasando incluso por contenedores LXC.

También veremos distintas formas de gestión de redes, volúmenes, instancias e incluso tipos de clonación e instantáneas de máquinas virtuales.

Taller 1: Gestión del almacenamiento en QEMU/KVM + libvirt.

1. Muestra los pool de almacenamientos con virsh que tienes definido. ¿De qué tipo son?. ¿Qué se guarda en cada uno de ellos?. Muéstralos también con virt-manager.

Los pool son de tipo dir (los que vamos a usar). Se guardan ficheros que pueden ser raw o qcow2 (el que usamos).

Para ver la lista de los pool que tengo en mi máquina es:

virsh -c qemu:///system pool-list --details

Devolviendo:

 Nombre      Estado       Inicio automático   Persistente   Capacidad    Alojamiento   Disponible
---------------------------------------------------------------------------------------------------
 default     ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 Descargas   ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 ISO         ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 srv         ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB

Otra forma de poder verlo es desde el propio Virt Manager:

img

2. Con virsh crea un nuevo pool de almacenamiento de tipo dir, que se llame discos y que los ficheros se guarden en el directorio /srv/discos. Inicia el nuevo pool de almacenamiento. Comprueba que se ha creado el nuevo pool.

virsh -c qemu:///system pool-define-as discos dir --target /srv/discos
virsh -c qemu:///system pool-build discos
virsh -c qemu:///system pool-start discos
virsh -c qemu:///system pool-list --details
andres@debian:~$ virsh -c qemu:///system pool-define-as discos dir --target /srv/discos
El grupo discos ha sido definido

andres@debian:~$ virsh -c qemu:///system pool-build discos
El pool discos ha sido compilado

andres@debian:~$ virsh -c qemu:///system pool-start discos
Se ha iniciado el grupo discos

andres@debian:~$ virsh -c qemu:///system pool-list --details
 Nombre      Estado       Inicio automático   Persistente   Capacidad    Alojamiento   Disponible
---------------------------------------------------------------------------------------------------
 default     ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 Descargas   ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 discos      ejecutando   no                  si            456,44 GiB   21,91 GiB     434,53 GiB
 ISO         ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB
 srv         ejecutando   si                  si            456,44 GiB   21,91 GiB     434,53 GiB

3. Muestra con virsh los volúmenes (imágenes de discos) que tienes creado en el pool de almacenamiento default. Comprueba con virt-manager los volúmenes que tienes creados.

Para ver los volúmenes en el pool default:

virsh -c qemu:///system vol-list default --details
andres@debian:~$ virsh -c qemu:///system vol-list default --details
 Nombre          Ruta                                    Tipo      Capacidad   Alojamiento
--------------------------------------------------------------------------------------------
 prueba1.qcow2   /var/lib/libvirt/images/prueba1.qcow2   archivo   10,00 GiB   8,02 GiB
 win10.qcow2     /var/lib/libvirt/images/win10.qcow2     archivo   30,00 GiB   4,89 MiB

Y desde virt-manager:

img

4. Con virsh crea un nuevo volumen en el pool de almacenamiento discos que se llame disco1.qcow2 y de tamaño 1Gb.

He creado el volumen y luego lo he listado tanto con vol-list como viendo el directorio /srv/discos:

virsh -c qemu:///system vol-create-as discos disco1.qcow2 --format qcow2 1G
virsh -c qemu:///system vol-list discos --details
sudo ls -l /srv/discos/
andres@debian:~$ virsh -c qemu:///system vol-create-as discos disco1.qcow2 --format qcow2 1G
Se ha creado el volumen disco1.qcow2

andres@debian:~$ virsh -c qemu:///system vol-list discos --details
 Nombre         Ruta                       Tipo      Capacidad   Alojamiento
------------------------------------------------------------------------------
 disco1.qcow2   /srv/discos/disco1.qcow2   archivo   1,00 GiB    196,00 KiB 

andres@debian:~$ sudo ls -l /srv/discos/
total 196
-rw------- 1 root root 196624 sep 26 08:56 disco1.qcow2

5. Con qemu-img crea un fichero de imagen en el directorio /srv/discos que se llame disco2.qcow2 con 2Gb de tamaño. Conviértelo a un volumen y muestra los volúmenes en el pool de almacenamiento discos para comprobar que se ha creado de forma correcta.

Lo primero es crear la imagen del disco y luego actualizar el pool para que se convierta a volumen.

sudo qemu-img create -f qcow2 disco2.qcow2 2G
sudo qemu-img info disco2.qcow2
andres@debian:/srv/discos$ sudo qemu-img create -f qcow2 disco2.qcow2 2G
Formatting 'disco2.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2147483648 lazy_refcounts=off refcount_bits=16

andres@debian:/srv/discos$ sudo qemu-img info disco2.qcow2
image: disco2.qcow2
file format: qcow2
virtual size: 2 GiB (2147483648 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false

Pero aún no sale en el pool discos, para que aparezca habría que refrescar el pool discos, pero en mi caso ya me aparecía refrescado. Si se crea uno nuevo copiando con cp, si hay que refrescar el pool. El resultado final es:

virsh -c qemu:///system pool-refresh discos
virsh -c qemu:///system vol-list discos --details
virsh -c qemu:///system pool-refresh discos


andres@debian:/srv/discos$ virsh -c qemu:///system vol-list discos --details
 Nombre         Ruta                       Tipo      Capacidad   Alojamiento
------------------------------------------------------------------------------
 disco1.qcow2   /srv/discos/disco1.qcow2   archivo   1,00 GiB    196,00 KiB
 disco2.qcow2   /srv/discos/disco2.qcow2   archivo   2,00 GiB    196,00 KiB

6. ¿Qué características tienen los ficheros de imágenes qcow2? Lista los volúmenes del pool de almacenamiento discos visualizando la capacidad del disco y el tamaño que ocupa realmente en disco.

Son archivos dinámicos, es decir, que cuando se crean van aumentando de tamaño progresivamente conforme lo van necesitando. La diferencia con los raw, es que los raw, si son de 10gb por ejemplo, gastan inmediatamente ese tamaño en disco, y los qcow2, aunque se le de un tamaño de 10gb, irán ocupando poco a poco el espacio, aunque en la práctica tienen un rendimiento inferior que los raw porque aparte de las operaciones que hace, hay que sumarle las del aumento de tamaño.

virsh -c qemu:///system vol-list discos --details
andres@debian:/srv/discos$ virsh -c qemu:///system vol-list discos --details
 Nombre         Ruta                       Tipo      Capacidad   Alojamiento
------------------------------------------------------------------------------
 disco1.qcow2   /srv/discos/disco1.qcow2   archivo   1,00 GiB    196,00 KiB
 disco2.qcow2   /srv/discos/disco2.qcow2   archivo   2,00 GiB    196,00 KiB

7. Añade a la máquina linux con la que estás trabajando el disco1 utilizando virsh y el disco2 utilizando virt-manager. Formatea los disco y móntalos de forma persistente.

Para listar las máquinas de mi equipo es:

virsh -c qemu:///system list --all
andres@debian:/srv/discos$ virsh -c qemu:///system list --all
 Id   Nombre    Estado
-------------------------
 -    prueba1   apagado
 -    win10     apagado

Y para asociar el volumen a la máquina:

virsh -c qemu:///system attach-disk prueba1 /srv/discos/disco1.qcow2 vdb --driver=qemu --type disk --subdriver qcow2 --persistent
andres@debian:/srv/discos$ virsh -c qemu:///system attach-disk prueba1 /srv/discos/disco1.qcow2 vdb --driver=qemu --type disk --subdriver qcow2 --persistent
El disco ha sido asociado exitosamente

img

img

Ahora, para iniciar la máquina, lo primero es activar la red default con:

virsh net-start default

Y encender la maquina con:

virsh -c qemu:///system start prueba1

Luego hay que crear una partición con gdisk y luego darle un sistema de ficheros a los discos vdb1 y vdc1 con mkfs.ext4, y montarlos (mnt/vdb y mnt/vdc en mi caso):

mkfs.ext4 /dev/vdb1
mkfs.ext4 /dev/vdc1
mount /dev/vdb1 /mnt/vdb
mount /dev/vdc1 /mnt/vdc

Por último hay que hacer permanente el montaje modificando el archivo fstab (/etc/fstab) añadiendo:

img

img

8. Redimensiona el disco1 a 2 Gb usando virsh, redimensiona el disco2 a 3Gb usando qemu-img. Finalmente redimensiona el sistema de ficheros de cada uno de los discos.

virsh -c qemu:///system vol-resize disco1.qcow2 2G --pool discos
sudo qemu-img resize /srv/discos/disco2.qcow2 3G
virsh -c qemu:///system vol-resize disco1.qcow2 2G --pool discos
El tamaño de volumen 'disco1.qcow2' se ha cambiado correctamente a 2G

sudo qemu-img resize /srv/discos/disco2.qcow2 3G
Image resized.

Al hacer un lsblk ahora se ve como ha cambiado el tamaño del disco, pero aún no he hecho la redimensión del sistema, pero se ve como los discos han aumentado de tamaño.(vdb y vdc)

img

Ahora para redimensionar el sistema de ficheros para que coincida con el tamaño de los discos, lo primero es desmontar los dicos:

sudo umount /dev/vdb1
sudo umount /dev/vdc1

Y con los discos ya desmontados, para aumentar el sistema de ficheros, lo primero que he hecho es usar el comando e2fsck para reparar el sistema de archivos, y luego resize para aumentarlo y por ultimo montarlo, de la siguiente manera:

sudo e2fsck -f /dev/vdb
sudo resize2fs /dev/vdb
sudo mount /dev/vdb /mnt/vdb
sudo e2fsck -f /dev/vdb

sudo resize2fs /dev/vdb
resize2fs 1.47.0 (5-Feb-2023)
Resizing the filesystem on /dev/vdb to 524288 (4k) blocks.
The filesystem on /dev/vdb is now 524288 (4k) blocks long

sudo mount /dev/vdb /mnt/vdb

Y como se ve en la imagen ahora el disco vdb ocupa 2gb:

img

Ahora he hecho lo mismo con el disco2 vdc para que ocupe 3gb y este es el resultado final:

img

9. Crea un nuevo volumen nuevo_disco.img de tipo raw y tamaño 10Gb en el pool discos. Lista los volúmenes del pool de almacenamiento discos visualizando la capacidad del disco y el tamaño que ocupa realmente en disco. ¿Cuánto espacio ocupa realmente el volumen nuevo_disco.img?.

Para crear el disco raw en el pool discos de 10GB es:

virsh -c qemu:///system vol-create-as discos nuevo_disco.raw --format raw 10G
virsh -c qemu:///system vol-create-as discos nuevo_disco.raw --format raw 10G
Se ha creado el volumen nuevo_disco.raw

Para ver que se ha creado el disco:

virsh -c qemu:///system vol-list discos --details
virsh -c qemu:///system vol-list discos --details
 Nombre            Ruta                          Tipo      Capacidad   Alojamiento
------------------------------------------------------------------------------------
 disco1.qcow2      /srv/discos/disco1.qcow2      archivo   2,00 GiB    2,57 MiB
 disco2.qcow2      /srv/discos/disco2.qcow2      archivo   3,00 GiB    3,82 MiB
 nuevo_disco.raw   /srv/discos/nuevo_disco.raw   archivo   10,00 GiB   10,00 GiB

El disco nuevo raw de 10gb ocupa 10gb o eso pone en el alojamiento que es el espacio ocupado en disco, y por ejemplo en los qcow2 de más arriba, su alojamiento es mucho menor porque van ocupando espacio progresivamente.

img

Taller 2: Clonación e instantáneas de máquinas virtuales

1. Utiliza la herramienta virt-clone para clonar tu máquina linux. Llámala máquina-clonada. Realiza los cambios necesarios en la nueva máquina para que no se llame igual que la original.

Para clonar la máquina con nombre diferente (clona todos los discos pero mantiene configuraciones de la original):

virt-clone --connect=qemu:///system --original prueba1 --name maquina-clonada --file /var/lib/libvirt/images/vol_prueba1.qcow2 --auto-clone
andres@debian:~$ virt-clone --connect=qemu:///system --original prueba1 --name maquina-clonada --file /var/lib/libvirt/images/vol_prueba1.qcow2 --auto-clone
Allocating 'vol_prueba1.qcow2'                                           | 7.1 GB  00:03:47 ... 

El clon 'maquina-clonada' ha sido creado exitosamente.

Habría que modificar el archivo /etc/hosts con la máquina clonada. Después de este punto he eliminado todo y he seguido con una maquina sin tanto lio de discos.

2. Crea una plantilla a partir de la máquina que acabamos de crear en el punto anterior. Llámala plantilla-linux. Recuerda que no debería poder inicializar la máquina que hemos creado la plantilla al poner el disco en sólo lectura.

Antes de empezar hace falta instalar el paquete libguestfs-tools para poder usar virt-sysprep, que es el encargado de eliminar la información de la máquina para poder clonarla y luego quitarle los permisos al disco para que no pueda iniciar, ya que esta máquina no debe iniciarse nunca.

sudo virt-sysprep -d maquina-clonada --hostname plantilla-linux
andres@debian:~$ sudo virt-sysprep -d maquina-clonada --hostname plantilla-linux
[   0.0] Examining the guest ...
[  49.0] Performing "abrt-data" ...
[  50.2] Performing "backup-files" ...
[  57.4] Performing "bash-history" ...
[  57.5] Performing "blkid-tab" ...
[  57.6] Performing "crash-data" ...
[  57.6] Performing "cron-spool" ...
[  57.8] Performing "dhcp-client-state" ...
[  57.8] Performing "dhcp-server-state" ...
[  57.8] Performing "dovecot-data" ...
[  57.8] Performing "ipa-client" ...
[  57.9] Performing "kerberos-hostkeytab" ...
[  57.9] Performing "logfiles" ...
[  58.4] Performing "machine-id" ...
[  58.4] Performing "mail-spool" ...
[  58.4] Performing "net-hostname" ...
[  58.5] Performing "net-hwaddr" ...
[  58.5] Performing "net-nmconn" ...
[  58.5] Performing "pacct-log" ...
[  58.6] Performing "package-manager-cache" ...
[  58.6] Performing "pam-data" ...
[  58.6] Performing "passwd-backups" ...
[  58.7] Performing "puppet-data-log" ...
[  58.7] Performing "rh-subscription-manager" ...
[  58.7] Performing "rhn-systemid" ...
[  58.8] Performing "rpm-db" ...
[  58.8] Performing "samba-db-log" ...
[  58.8] Performing "script" ...
[  58.8] Performing "smolt-uuid" ...
[  58.8] Performing "ssh-hostkeys" ...
[  58.8] Performing "ssh-userdir" ...
[  58.9] Performing "sssd-db-log" ...
[  58.9] Performing "tmp-files" ...
[  59.0] Performing "udev-persistent-net" ...
[  59.1] Performing "utmp" ...
[  59.1] Performing "yum-uuid" ...
[  59.1] Performing "customize" ...
[  59.1] Setting a random seed
[  59.2] Setting the machine ID in /etc/machine-id
[  59.2] Setting the hostname: plantilla-linux
[  64.2] Performing "lvm-uuids" ...
sudo chmod -w /var/lib/libvirt/images/vol_prueba1.qcow2

Luego hay que cambiarle el nombre a la maquina de prueba1 a plantilla para identificarla facilmente.

virsh -c qemu:///system domrename maquina-clonada plantilla-linux
virsh -c qemu:///system list --all
andres@debian:~$ virsh -c qemu:///system domrename maquina-clonada plantilla-linux
Domain successfully renamed

andres@debian:~$ virsh -c qemu:///system list --all
 Id   Nombre            Estado
---------------------------------
 -    plantilla-linux   apagado
 -    prueba1           apagado
 -    win10             apagado

Ahora, al iniciar la maquina con los permisos quitados aparece el siguiente error, evitando que pueda iniciarla:

img

3. Realiza una clonación completa usando virt-manager de la plantilla que has creado. La nueva máquina la llamará clone-full. Accede a esta nueva máquina por ssh.

En virt-manager haciendo click derecho -> clonación:

img

Con la máquina clonada “clone-full” por culpa del sysprep no permite el acceso por ssh por lo que hay que iniciarla y regenerar las claves ssh y de paso darle un nombre de host.

img

img

Y como se ve en las imágenes, ya se puede hacer el acceso por ssh.

img

El primer paso es comprobar el tamaño del disco de la plantilla con:

virsh -c qemu:///system domblkinfo plantilla-linux vda --human
andres@debian:~/Descargas$ virsh -c qemu:///system domblkinfo plantilla-linux vda --human
Capacidad:      10,000 GiB
Ubicación:     7,182 GiB
Físico:        7,181 GiB

El siguiente paso es crear un nuevo volumen de tamaño similar al disco de la plantilla:

sudo virsh -c qemu:///system vol-create-as discos clonebs.qcow2 10G --format qcow2 --backing-vol /var/lib/libvirt/images/vol_prueba1.qcow2 --backing-vol-format qcow2
sudo virsh -c qemu:///system vol-list discos
andres@debian:~/Descargas$ sudo virsh -c qemu:///system vol-create-as discos clonebs.qcow2 10G --format qcow2 --backing-vol /var/lib/libvirt/images/vol_prueba1.qcow2 --backing-vol-format qcow2 
Se ha creado el volumen clonebs.qcow2

andres@debian:~/Descargas$ sudo virsh -c qemu:///system vol-list discos
 Nombre          Ruta
--------------------------------------------
 clonebs.qcow2   /srv/discos/clonebs.qcow2
 disco1.qcow2    /srv/discos/disco1.qcow2

Y para comprobar que tiene activado el backingStore:

virsh -c qemu:///system vol-dumpxml clonebs.qcow2 discos
andres@debian:~/Descargas$ virsh -c qemu:///system vol-dumpxml clonebs.qcow2 discos
...
  <backingStore>
    <path>/var/lib/libvirt/images/vol_prueba1.qcow2</path>
    <format type='qcow2'/>
    <permissions>
...

Aunque hay otra forma con qemu-img (La ruta es de mi pool discos en /srv/discos):

sudo qemu-img info /srv/discos/clonebs.qcow2
andres@debian:~/Descargas$ sudo qemu-img info /srv/discos/clonebs.qcow2
image: /srv/discos/clonebs.qcow2
...
backing file: /var/lib/libvirt/images/vol_prueba1.qcow2
backing file format: qcow2
...

En mi caso el disco es clonebs.qcow2 y el volumen es vol_prueba1.qcow2, sabiendo esto, ahora hay que crear la máquina a partir de la imagen con backing store con virt-install:

virt-install --connect qemu:///system \
                         --virt-type kvm \
                         --name clone-link \
                         --os-variant debian10 \
                         --disk path=/srv/discos/clonebs.qcow2 \
                         --memory 1024 \
                         --vcpus 1 \
                         --import
andres@debian:~/Descargas$ virt-install --connect qemu:///system \
                         --virt-type kvm \
                         --name clone-link \
                         --os-variant debian10 \
                         --disk path=/srv/discos/clonebs.qcow2 \
                         --memory 1024 \
                         --vcpus 1 \
                         --import

Empezando la instalación...
Creando dominio...                                               |    0 B  00:00:00
Running graphical console command: virt-viewer --connect qemu:///system --wait clone-link

Y para ver el tamaño que ocupa realmente:

virsh -c qemu:///system domblkinfo clone-link vda --human
andres@debian:~/Descargas$ virsh -c qemu:///system domblkinfo clone-link vda --human
Capacidad:      10,000 GiB
Ubicación:     691,574 MiB
Físico:        691,625 MiB

Y para hacerlo con virt-clone, primero he creado otro volumen:

virsh -c qemu:///system vol-create-as discos borrar.qcow2 10G --format qcow2 --backing-vol /var/lib/libvirt/images/vol_prueba1.qcow2 --backing-vol-format qcow2
andres@debian:~/Descargas$ virsh -c qemu:///system vol-create-as discos borrar.qcow2 10G --format qcow2 --backing-vol /var/lib/libvirt/images/vol_prueba1.qcow2 --backing-vol-format qcow2 
Se ha creado el volumen borrar.qcow2

Con el volumen creado ahora es usar virt-clone:

virt-clone --connect=qemu:///system --original plantilla-linux --name clone-link2 --file /srv/discos/borrar.qcow2 --preserve-data
virsh -c qemu:///system domblkinfo clone-link2 vda --human
virsh -c qemu:///system list --all
andres@debian:~/Descargas$ virt-clone --connect=qemu:///system --original plantilla-linux --name clone-link2 --file /srv/discos/borrar.qcow2 --preserve-data

El clon 'clone-link2' ha sido creado exitosamente.
andres@debian:~/Descargas$ virsh -c qemu:///system domblkinfo clone-link2 vda --human
Capacidad:      10,000 GiB
Ubicación:     196,000 KiB
Físico:        192,156 KiB

andres@debian:~/Descargas$ virsh -c qemu:///system list --all
 Id   Nombre            Estado
------------------------------------
 4    clone-link        ejecutando
 -    clone-full        apagado
 -    clone-link2       apagado
 -    plantilla-linux   apagado
 -    prueba1           apagado
 -    win10             apagado

Para el caso de la máquina “clone-link2”, ocupa tan poco espacio porque tiene hecho el backing store, por lo que al usar la imagen de la plantilla en modo lectura, en la imagen nueva solo se guardan los cambios del sistema del archivo, y lo malo es que sin la imagen de la plantilla base no funciona.

5. Crea un directorio en cualquiera de las máquinas y realiza una instantánea de la máquina virtual. Borra el directorio y vuelve al estado anterior de la máquina recuperando la instantánea que hemos creado (lo puedes hacer con cualquier herramienta).

El proceso es arrancar la red default, y arrancar la máquina de antes llamada “clone-full”.

Me he conectado por ssh y creado el directorio “pruebas”. Luego he hecho la instantánea con virsh (atomic para evitar corrupciones al crear la máquina):

img

Y para hacerlo con qemu-img (debe estar parada):

sudo qemu-img info /var/lib/libvirt/images/vol_prueba1-clone.qcow2

Para crear la snapshot:

virsh -c qemu:///system snapshot-create-as clone-full --name instantánea1 --description "Creada carpeta importante en clone-full" --atomic
andres@debian:~$ virsh -c qemu:///system snapshot-create-as clone-full --name instantánea1 --description "Creada carpeta importante en clone-full" --atomic
Ha sido creada la captura instantánea instantánea1 del dominio

Y para ver las instantáneas creadas de una máquina:

virsh -c qemu:///system snapshot-list clone-full
andres@debian:~$ virsh -c qemu:///system snapshot-list clone-full
 Nombre         Hora de creación            Estado
-----------------------------------------------------
 instantánea1   2023-10-06 09:55:59 +0200   running

img

Ahora he borrado el directorio “pruebas”:

img

Y para ver el listado de snapshots y volver al estado anterior de la instantánea:

img

virsh -c qemu:///system snapshot-revert clone-full instantánea1

Al volver a conectarme a la máquina, se ve como se ha recuperado el directorio pruebas que habia borrado:

img

Nota: En mi caso, estos son los discos y el cambio en el uso.

clonebs.qcow2 = clone2.qcow2
vol_prueba1.qcow2 = vol1.qcow2 

6. Crear Nuevas Máquinas Rápidamente:

Iniciar la red default:

virsh -c qemu:///system net-start default

Mostrar información sobre el disco de la máquina virtual plantilla-kvm-andres, para crear un volumen del mismo tamaño:

virsh -c qemu:///system domblkinfo plantilla-kvm-andres vda --human

Crear un nuevo volumen llamado nombre.qcow2 de 10 GB con formato qcow2, utilizando como plantilla el volumen kvm-andres.qcow2:

sudo virsh -c qemu:///system vol-create-as default nombre.qcow2 10G --format qcow2 --backing-vol /var/lib/libvirt/images/kvm-andres.qcow2 --backing-vol-format qcow2

Crear una nueva máquina virtual , 1GB de RAM, 1 CPU, y el disco nombre.qcow2:

virt-install --connect qemu:///system \
             --virt-type kvm \
             --name nombremaquina \
             --os-variant debian10 \
             --disk path=/var/lib/libvirt/images/nombre.qcow2 \
             --memory 1024 \
             --vcpus 1 \
             --import
  • Dependiendo del uso, hay que modificar los nombres tanto del volumen nuevo creado, como del disco de la plantilla.

Una vez dentro:

echo "nombrenuevo" > /etc/hostname

ssh-keygen -A

reboot

Averiguar la ip de la máquina con (o desde Virt Manager, o con ip a):

virsh -c qemu:///system domifaddr clonacion1

Le vuelvo a enviar la clave pública ssh desde el host:

ssh-copy-id usuario@ip

Hecho esto ya tenemos acceso para conectarnos por ssh:

ssh usuario@ip

Taller 3: Gestión de redes en QEMU/KVM + libvirt.

1. Crea distintos tipos de redes con virsh:

1.1 Una red privada de tipo NAT:

        Nombre: red-nat
        Nombre del bridge: virbr1
        Direccionamiento: 192.168.125.0/24
        Dirección del host (puerta de enlace): 192.168.125.1
        Rango DHCP: 192.168.125.2 - 192.168.125.100*

El archivo de la red default esta en: /usr/share/libvirt/networks/default.xml . He creado otro archivo llamado red-nat.xml con el siguiente contenido:

 <network>
   <name> red_nat </name>
   <bridge name='virbr1'/>
   <forward/>
   <ip address='192.168.125.1' netmask='255.255.255.0'>
     <dhcp>
       <range start='192.168.125.2' end='192.168.125.100'/>
     </dhcp>
   </ip>
 </network>

Con el archivo creado, ahora hay que crear la red (hacerlo desde /usr/share/libvirt/networks) con:

sudo virsh -c qemu:///system net-define red-nat.xml
andres@debian:/usr/share/libvirt/networks$ sudo virsh -c qemu:///system net-define red-nat.xml
La red red_nat se encuentra definida desde red-nat.xml

Quedando así:

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-list --all
 Nombre    Estado     Inicio automático   Persistente
-------------------------------------------------------
 default   activo     no                  si
 red_nat   inactivo   no                  si

Y para iniciar la red: (si se cambia start por autostart se hace permanente).

virsh -c qemu:///system net-start red_nat

Para ver los datos sobre la red-nat:

virsh -c qemu:///system net-info red_nat
andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-info red_nat
Nombre:         red_nat
UUID:           497bcbbc-7b4e-418e-9ffd-b41c47345c69
Activar:        no
Persistente:    si
Autoinicio:     no
Puente:         virbr1

Y para comprobar que se ha creado el bridge (antes hay que iniciar la red), se usa el comando brctl que pertenece al paquete bridge-utils.

virsh -c qemu:///system net-start red_nat
sudo brctl show
andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-start red_nat
La red red_nat se ha iniciado

andres@debian:/usr/share/libvirt/networks$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.525400094174	yes		
virbr1		8000.525400728d68	yes		

Y con estos pasos tengo creada la red-nat.

1.2 Una red privada aislada:

        Nombre: red-aislada
        Nombre del bridge: virbr2
        Direccionamiento: 192.168.126.0/24
        Dirección del host (puerta de enlace): 192.168.126.1
        Rango DHCP: 192.168.126.2 - 192.168.126.100*

He creado el archivo red-aislada.xml con el siguiente contenido:

<network>
  <name>red_aislada</name>
  <bridge name='virbr2'/>
  <ip address='192.168.126.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.126.2' end='192.168.126.100'/>
    </dhcp>
  </ip>
</network>

El mismo proceso, definir la red, arrancarla y al final se ve como ya está virbr2 creado. (Hice primero el virbr3 y luego virbr2).

virsh -c qemu:///system net-define red-aislada.xml
virsh -c qemu:///system net-start red_aislada
sudo brctl show
andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-define red-aislada.xml
La red red_aislada se encuentra definida desde red-aislada.xml

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-start red_aislada
La red red_aislada se ha iniciado

andres@debian:/usr/share/libvirt/networks$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.525400094174	yes		
virbr1		8000.525400728d68	yes		
virbr2		8000.5254008bb4ee	yes		
virbr3		8000.525400532a95	yes

1.3 Una red privada muy aislada:

        Nombre: red-muy-aislada
        Nombre del bridge: virbr3

Para esta red, es seguir los mismos pasos, he creado otro archivo llamado red-muy-aislada.xml , y le he dejado solamente este contenido:

<network>
<name>red_muy_aislada</name>
<bridge name='virbr2'/>
</network>

Y para crearla e iniciarla:

sudo nano /usr/share/libvirt/networks/red-muy-aislada.xml
virsh -c qemu:///system net-define red-muy-aislada.xml
virsh -c qemu:///system net-start red_muy_aislada
sudo brctl show
andres@debian:/usr/share/libvirt/networks$ sudo nano /usr/share/libvirt/networks/red-muy-aislada.xml
andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-define red-muy-aislada.xml
La red red_muy_aislada se encuentra definida desde red-muy-aislada.xml

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-start red_muy_aislada 
La red red_muy_aislada se ha iniciado

andres@debian:/usr/share/libvirt/networks$ sudo brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.525400094174	yes		
virbr1		8000.525400728d68	yes		
virbr3		8000.525400532a95	yes

Para activar las redes y configurarlas para que se inicien de forma automática, es utilizar el comando:

virsh -c qemu:///system net-autostart red

virsh -c qemu:///system net-autostart red_aislada
virsh -c qemu:///system net-autostart red_muy_aislada
virsh -c qemu:///system net-autostart red_nat
virsh -c qemu:///system net-list --all
andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-list --all
 Nombre            Estado   Inicio automático   Persistente
-------------------------------------------------------------
 default           activo   no                  si
 red_aislada       activo   no                  si
 red_muy_aislada   activo   no                  si
 red_nat           activo   no                  si

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-autostart red_aislada
La red red_aislada ha sido marcada para iniciarse automáticamente

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-autostart red_muy_aislada
La red red_muy_aislada ha sido marcada para iniciarse automáticamente

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-autostart red_nat
La red red_nat ha sido marcada para iniciarse automáticamente

andres@debian:/usr/share/libvirt/networks$ virsh -c qemu:///system net-list --all
 Nombre            Estado   Inicio automático   Persistente
-------------------------------------------------------------
 default           activo   no                  si
 red_aislada       activo   si                  si
 red_muy_aislada   activo   si                  si
 red_nat           activo   si                  si

Para la siguiente parte, vamos a trabajar con dos máquinas virtuales. Las máquinas las vamos a llamar cliente1 y cliente2.

Antes vamos a comprobar como que han quedado todas las redes definidas:

virsh -c qemu:///system net-list --all

2. Desconecta la máquina cliente1(clone-full) de la red default y conéctala a la red red-nat. Obtén de nuevo una dirección y comprueba la dirección IP que ha tomado, que tiene acceso a internet y que la dirección del host (puerta de enlace) corresponde a la 192.168.125.1.

Para desconectar la máquina de la red default (hay que mirar la mac):

virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:b3:ae:95 --persistent
andres@debian:~$ virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:b3:ae:95 --persistent 
La interfaz ha sido desmontada exitosamente

Y para añadir la maquina a la red_nat:

virsh -c qemu:///system attach-interface clone-full network red_nat --model virtio --persistent
andres@debian:~$ virsh -c qemu:///system attach-interface clone-full network red_nat --model virtio --persistent
La interfaz ha sido asociada exitosamente

img

Y ahora para comprobar que ha cogido ip he hecho (me he conectado por ssh):

virsh -c qemu:///system domifaddr clone-full
andres@debian:~$ virsh -c qemu:///system domifaddr clone-full
 Nombre     dirección MAC       Protocol     Address
-------------------------------------------------------------------------------
 vnet4      52:54:00:07:e6:a0    ipv4         192.168.125.52/24

img

img

La configuración ha sido desconectando la interfaz de la red default, y conectandola a la red_nat, luego de eso, se ha configurado correctamente.

root@clone-full:~# ip r
default via 192.168.125.1 dev enp1s0 proto dhcp src 192.168.125.52 metric 100 
192.168.125.0/24 dev enp1s0 proto kernel scope link src 192.168.125.52 metric 100

img

img

Para esta parte he utilizado 2 máquinas de los talleres anteriores, como clone-full y clone-link. He desconectado la maquina clone-full de la red default, y la he conectado a la red_nat.

Luego he iniciado la máquina y he comprobado su puerta de enlace y su conectividad a internet haciendo un ping a los dns de google.

Lo primero que he hecho es desconectar al cliente2 (clone-link) de la red default, y lo he conectado a la red_aislada.

virsh -c qemu:///system domifaddr clone-link
virsh -c qemu:///system detach-interface clone-link network --mac 52:54:00:b6:02:55 --persistent
virsh -c qemu:///system net-list
virsh -c qemu:///system attach-interface clone-link network red_aislada --model virtio --persistent
andres@debian:~$ virsh -c qemu:///system domifaddr clone-link
 Nombre     dirección MAC       Protocol     Address
-------------------------------------------------------------------------------
 vnet5      52:54:00:b6:02:55    ipv4         192.168.122.39/24

andres@debian:~$ virsh -c qemu:///system detach-interface clone-link network --mac 52:54:00:b6:02:55 --persistent 
La interfaz ha sido desmontada exitosamente

andres@debian:~$ virsh -c qemu:///system net-list 
 Nombre            Estado   Inicio automático   Persistente
-------------------------------------------------------------
 default           activo   no                  si
 red_aislada       activo   si                  si
 red_muy_aislada   activo   si                  si
 red_nat           activo   si                  si

andres@debian:~$ virsh -c qemu:///system attach-interface clone-link network red_aislada --model virtio --persistent
La interfaz ha sido asociada exitosamente

img

El siguiente paso es añadir una interfaz al cliente1(clone-full) para conectarlo a la red_aislada:

andres@debian:~$ virsh -c qemu:///system attach-interface clone-full network red_aislada --model virtio --persistent
La interfaz ha sido asociada exitosamente

img

Ahora en el archivo /etc/network/interfaces he declarado la interfaz enp1s0 y he reiniciado el servicio, y ya ha cogido ip.

auto enp1s0
iface enp1s0 inet dhcp
root@clone-full:~# systemctl restart networking.service

img

img

Lo siguiente que he hecho es verificar si hay ping entre clone-full (192.168.126.57) y clone-link (192.168.126.31 en ese momento), con la puerta de enlace y a internet(a los dns de google 8.8.8.8 en la misma imagen que al cliente2 clone-link).

img

img

img

img

Ahora para poder hacer ping desde Cliente2(clone-link) a Cliente1 (clone-full) habria que entrar por ssh, pero si la máquina no esta configurada, hay que entrar normal y darle el nombre de host y activar la key ssh y reiniciar la máquina para que acepte la entrada por ssh:

echo "clone-link" > /etc/hostname
ssh keygen -A

Y por último desde cliente2 (clone-link) se ve en la siguiente imagen como puede hacer ping al cliente1(clone-full) y a la puerta de enlace, pero NO a internet.

img

4. Desconecta todas las interfaces de las dos máquinas. Conéctalas a la red red-muy-aislada. Configura de forma estática sus direcciones y comprueba que pueden hacer ping entre ellas, sin embargo no pueden hacer ping ni al host, ni al exterior.

Para comprobar las interfaces, y eliminarlas todas:

virsh -c qemu:///system domifaddr clone-full
virsh -c qemu:///system domifaddr clone-link

virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:07:e6:a0 --persistent
virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:cb:46:22 --persistent
virsh -c qemu:///system detach-interface clone-link network --mac 52:54:00:86:1b:78 --persistent
andres@debian:~$ virsh -c qemu:///system domifaddr clone-full
 Nombre     dirección MAC       Protocol     Address
-------------------------------------------------------------------------------
 vnet7      52:54:00:07:e6:a0    ipv4         192.168.125.52/24
 vnet8      52:54:00:cb:46:22    ipv4         192.168.126.57/24

andres@debian:~$ virsh -c qemu:///system domifaddr clone-link
 Nombre     dirección MAC       Protocol     Address
-------------------------------------------------------------------------------
 vnet6      52:54:00:86:1b:78    ipv4         192.168.126.31/24

andres@debian:~$ virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:07:e6:a0 --persistent 
La interfaz ha sido desmontada exitosamente

andres@debian:~$ virsh -c qemu:///system detach-interface clone-full network --mac 52:54:00:cb:46:22 --persistent 
La interfaz ha sido desmontada exitosamente

andres@debian:~$ virsh -c qemu:///system detach-interface clone-link network --mac 52:54:00:86:1b:78 --persistent 
La interfaz ha sido desmontada exitosamente

Ahora para ver las redes y para añadir las dos máquinas a la red_muy_aislada:

virsh -c qemu:///system net-list --all
virsh -c qemu:///system attach-interface clone-full network red_muy_aislada --model virtio --persistent
virsh -c qemu:///system attach-interface clone-link network red_muy_aislada --model virtio --persistent
andres@debian:~$ virsh -c qemu:///system net-list --all
 Nombre            Estado   Inicio automático   Persistente
-------------------------------------------------------------
 default           activo   no                  si
 red_aislada       activo   si                  si
 red_muy_aislada   activo   si                  si
 red_nat           activo   si                  si

andres@debian:~$ virsh -c qemu:///system attach-interface clone-full network red_muy_aislada --model virtio --persistent
La interfaz ha sido asociada exitosamente

andres@debian:~$ virsh -c qemu:///system attach-interface clone-link network red_muy_aislada --model virtio --persistent
La interfaz ha sido asociada exitosamente

Luego hay que configurar las ips de manera estática en cada máquina y para ello hay que modificar el archivo /etc/nework/interfaces, en este caso les he dado las 192.168.0.2 y la 0.3:

img

img

img

Y como se ve en las imágenes hay conectividad entre ambas máquinas pero no hay salida a internet.

img

img

5. Crea un puente externo, llamado br0 como se explica en el apartado Creación de un Puente Externo con Linux Bridge. Crea una red de tipo Puente que nos permita conectar las máquinas a este bridge, llámala red-externa. Conecta el cliente1 a esta red y obtén direccionamiento, comprueba que se configura con una IP del direccionamiento de nuestra red local 172.22.0.0/16 (ha obtenido la dirección del servidor DHCP de nuestro instituto). Comprueba que podemos acceder a esta máquina desde cualquier máquina conectada a la misma red.

He creado el puente br0 como en los apuntes con NetworkManager, y he usado la máquina cliente1 (debian-full). Al iniciar la máquina y volver a dejar el direccionamiento dinámico (dejar en auto el interfaces y reiniciar el servicio ya ha cogido una ip de 172.22):

img

En el archivo /etc/network/interfaces hay que dejarlo para que coja dhcp:

img

La máquina cliente1 (debian-full) se ve como ha cogido una ip 172.22:

img

Y como se en la imagen, desde mi máquina anfitriona, hace ping también:

img

Taller 4: Trabajando con contenedores LXC:

1. Instala LXC.

sudo apt install lxc

2. Crea un contenedor LXC con la última distribución de Ubuntu. Lista los contenedores. Inicia el contenedor y comprueba la dirección IP que ha tomado. ¿Tiene conectividad al exterior?. Sal del contenedor y ejecuta un apt update en el contenedor sin estar conectado a él.

Para crear el contenedor ubuntu (jammy):

sudo lxc-create -n c_ubuntu -t ubuntu -- -r jammy

img

Para listar los contenedores:

sudo lxc-ls
andres@debian:/var/cache/lxc$ sudo lxc-ls
c_ubuntu 

img

Ahora es momento de arrancar el contenedor y comprobar que esta funcionando:

sudo lxc-start c_ubuntu
sudo lxc-ls -f
andres@debian:/var/cache/lxc$ sudo lxc-start c_ubuntu
andres@debian:/var/cache/lxc$ sudo lxc-ls -f
NAME     STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED 
c_ubuntu RUNNING 0         -      10.0.3.249 -    false 

img

Para ver la ip que ha tomado el contenedor:

lxc-attach c_ubuntu -- ip a
andres@debian:/var/cache/lxc$ sudo lxc-attach c_ubuntu -- ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if17:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:76:32:a1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.3.249/24 metric 100 brd 10.0.3.255 scope global dynamic eth0
       valid_lft 3413sec preferred_lft 3413sec
    inet6 fe80::216:3eff:fe76:32a1/64 scope link 
       valid_lft forever preferred_lft forever

img

Para poder hacer un apt update sin estar conectado (ejecutar comandos desde fuera del contenedor):

sudo lxc-attach c_ubuntu -- apt update

img

3. Modifica la configuración del contenedor, y limita el uso de memoria a 512M y que use una sola CPU.

Para poder modificar los contenedores, primero hay que habilitar la modificación de memoria en los grupos de control, añadiendo al archivo /etc/default/grub en la parte GRUB_CMDLINE_LINUX_DEFAULT el valor cgroup_enable=memory.

img

Para modificar el contenedor hay que hacerlo en su archivo de configuración en /var/lib/lxc/c_ubuntu/config y añadir lo siguiente:

lxc.cgroup2.memory.max = 512M
lxc.cgroup2.cpuset.cpus = 0

img

Luego habiendo reiniciado el contenedor, se comprueba con:

lxc-attach c_ubuntu -- free -h

sudo lxc-attach c_ubuntu -- cat /proc/cpuinfo

img

img

4. Comprueba que se ha creado un bridge llamado lxcbr0 donde está conectado el contenedor. Cambia la configuración del contenedor para desconectar de este bridge y conectarlo a la red red-nat que creaste en el taller anterior. Toma de nuevo direccionamiento y comprueba de nuevo la dirección IP, y que sigue teniendo conectividad al exterior.

sudo lxc-start c_ubuntu
andres@debian:~$ sudo lxc-ls -f
NAME     STATE   AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED 
c_ubuntu RUNNING 0         -      -    -    false

En el archivo de configuración de mi contenedor c_ubuntu en /var/lib/lxc/c_ubuntu/config sale esto:

lxc.net.0.type = veth
lxc.net.0.hwaddr = 00:16:3e:76:32:a1
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up

Pero como quiero conectar este contenedor a la rednat tengo que cambiar donde pone lxcbr0 por el nombre del puente de esa red que es virbr1, que para saber esto hay que ir a virt manager, hacer boton derecho en qemu/kvm -> redes virtuales y elegir la que es.

img

Quedando asi:

lxc.net.0.type = veth
lxc.net.0.hwaddr = 00:16:3e:76:32:a1
lxc.net.0.link = virbr1
lxc.net.0.flags = up

Ahora he entrado al contenedor y lo he reiniciado:

root@debian:/var/lib/lxc/c_ubuntu# lxc-attach c_ubuntu
root@cubuntu:/var/lib# reboot

Al reiniciar ya tiene internet y puede salir al exterior:

img

img

5. Añade una nueva interfaz de red al contenedor y conéctala a la red red-externa que creaste en el taller anterior. Toma direccionamiento en esta nueva interfaz y comprueba que esta en el direccionamiento del instituto.

Para añadirle al contenedor otra interfaz hay que ir al archivo de configuración en /var/lib/lxc/c_ubuntu/config y añadir (la mac es inventada y br0 es la red externa que se ve con nm-connection-editor):

lxc.net.1.type = veth
lxc.net.1.hwaddr = 00:16:3e:76:32:b1
lxc.net.1.link = br0
lxc.net.1.flags = up

Después he reiniciado el contenedor y he hecho dhclient para renovar la ip:

andres@debian:/var/lib/lxc$ sudo lxc-stop c_ubuntu
andres@debian:/var/lib/lxc$ sudo lxc-start c_ubuntu
andres@debian:/var/lib/lxc$ sudo lxc-attach c_ubuntu

Y ya aparece la nueva interfaz llamada eth1 y con la ip 172 de la red externa:

img

img

6. Crea en el host el directorio /opt/web, crea el fichero index.html y monta este directorio en el directorio /srv/www del contenedor.

He creado el archivo /opt/web/index.html en el host. En el contenedor el directorio /srv/www.

Al final del archivo de configuración he añadido:

lxc.mount.entry=/opt/web_ubuntu srv/www none bind 0 0

Y luego he parado y arrancado el contenedor, y desde dentro de este, he ido al directorio /srv/www y comprobado el archivo index.html:

img