Tecnología de virtualización LXC/LXD/Incus

Ver las máquinas virtuales en red lechuga?

TODO

Backup y restore de lxd
https://www.cyberciti.biz/faq/how-to-backup-and-restore-lxd-containers/

Fuentes de información

https://www.ubuntu.com/cloud/lxd
https://linuxcontainers.org/lxd/getting-started-cli/
https://www.stgraber.org/2013/12/27/lxc-1-0-container-storage/
https://help.ubuntu.com/lts/serverguide/lxd.html

Gestión apparmor para los containers

Enlaces

https://forum.proxmox.com/threads/is-it-possible-to-run-a-nfs-server-within-a-lxc.24403/

El apparmor sólo se ejecuta en el host, y es donde saldrán los bloqueos de acciones denegadas o complaints.

Acceso a un servidor incus remoto

https://linuxcontainers.org/incus/docs/main/remotes/

Listar sistemas remotos
incus remote list

En servidor, autorizar un cliente remoto (guardar el token)
incus config trust add pepino

En cliente, añadir un servidor (usar el token generado en paso anterior)
incus remote add brocoli 192.168.1.140

Activar el servidor incus remoto
incus remote switch brocoli

Acceso VGA a la máquina virtual
incus console maquina-virtual --type=vga

Autoarranque

Activar el autoarranque
incus config set container_name boot.autostart true

Modificar la prioridad al autoarranque ( Mayor valor, mayor prioridad )
incus config set container_nae boot.autostart.priority 100

Espacio de almacenamiento de los contenedores

Se llaman "Storage pools"

el backing store es btrfs como subvolumen del punto raiz de montaje.

Guia BTRFS en lechuga: Gestión sistema BTRFS

Pool almacenamiento INCUS por defecto en brocoli
incus storage list

Gestión de pools de almacenamiento
https://linuxcontainers.org/incus/docs/main/howto/storage_pools/

Muestra

incus storage list
+-----------+-------------+--------+------------------------------------------------+---------+
|   NAME    | DESCRIPTION | DRIVER |                     SOURCE                     | USED BY |
+-----------+-------------+--------+------------------------------------------------+---------+
| default   |             | btrfs  | /var/snap/lxd/common/lxd/storage-pools/default | 32      |
+-----------+-------------+--------+------------------------------------------------+---------+
| pool_crit |             | btrfs  | /mnt/pool_crit/pool-lxd                        | 0       |
+-----------+-------------+--------+------------------------------------------------+---------+

Mover un container de pool de almacenamiento

# Mover de pool (es necesario cambiar el nombre)
lxc move some_container some_container-moved --storage pool_crit
# devolvemos el nombre anterior, ya en el nuevo pool
lxc move some_container-moved some_container

Montar en un contenedor un directorio del host

Atención!! No usar para subdirectorios de dispositivos montados en el host, no funcionará el autoarranque!

To mount host's /share/c1 onto /opt in the container
incus config device add [<remote>:]container1 <device-name> disk source=/share/c1 path=mnt/c1

Hay que tener el cuenta los permisos mapeados del contenedor al host, segun https://www.stgraber.org/2014/01/17/lxc-1-0-unprivileged-containers/

Ver el mapeo de subgid y subuid
cat /etc/sub*

Ejecutar comando a lo largo de todos los containers

Comando de consulta de configuración

x=$(incus list -c n | awk '{ print $2}'  | sed -e '/^$/d' -e '/^NAME/d')
for c in $x
do
   echo "*** VM: $c ***"
   for v in boot.autostart boot.autostart.priority boot.autostart.delay
   do
      echo "Key: $v => $(incus config get $c $v)"
   done
      echo ""
done

Comando de ejecución

x=$(incus list -c n | awk '{ print $2}'  | sed -e '/^$/d' -e '/^NAME/d')
for c in $x
do
   echo "*** VM: $c ***"
   incus [[comandos incus]] $c
done

# for en una línea:
for c in $x; do incus file push /mnt/pool_crit/repo_configs_lechuga/etc/bash.bashrc $c/etc/; done

Red

Acceder a contenedores con incusbr0

Estos contenedores tienen direcciones IP propias en el rango 10.0.0.0.

Acceder al servidor web (puerto 80) del contenedor _contenedor_. Mapear al puerto 8080 del host
incus config device add _contenedor_ _nombre_regla_nat_ proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80

Gestión de contenedores

Listar contenedores y su estado
incus list

Ejecutar un comando en un contenedor
incus exec my_container command

Pushing a file to the container
incus file push src_path/filename my_container/dest_path/filename

Getting a file from the container. No admite wildcards, sólo --recursive
incus file pull my_container/path dest

Creating a snapshot
incus snapshot my_container o bien
incus snapshot my_container snapshot_name

Listing snapshots
incus info my_container

Restoring a snapshot
incus restore my_contanier snapshot_name

Creating a new container from a snapshot
incus copy src_container/snapshot_name dest_container

Copying a container
incus copy src_container dest_container

Consumo actual de recursos de un contenedor
incus info my_container

Set the priority of a container (0=minimum, 10=maximum):
incus config set my_container limits.cpu.priority <priority>

apply a straightforward memory limit run (kB, MB, GB, TB, PB and EB)
incus config set my_container limits.memory 256MB

Asignar cpu a una máquina virtual
incus config set my-vm limits.cpu 2

To set a disk limit (requires btrfs):
incus config device set my_container root size 20GB

Set the I/O priority for that container
incus config set my_container limits.disk.priority 10

Set set an overall network priority (0=minimum, 10=maximum)
incus config set my_container limits.network.priority 5

Cuanto espacio consume cada container
????

Gestión de imagenes

Listar imagenes públicas disponibles
incus image list images:
incus image list images: 'alpine'
incus image list images: 'opensuse'
incus image list images: fedora amd64

Información de una imagen
incus image info images:a95831652b88

Importar una imagen (si es necesario) y lanzar un container
Añadir --storage <target_pool_name> si es necesario.
incus launch images:[hash] [nombre contenedor]
incus launch images:debian/13

lanzar un container efímero (descargando imágen si es necesario)
incus launch images:[hash] --ephemeral
incus launch images:debian/13 --ephemeral

Crear una imagen para luego poder generar contenedores
incus publish [contenedor] --alias [nombre_imagen]

Gestión de máquinas virtuales INCUS

Analizar: https://ib.bsb.br/maximizing-vm-performance-with-incus-v1/#1-hardware-assessment

Listado de imagenes disponibles de maquinas virtuales
incus image list images: amd64 type=virtual-machine

Listado de imagenes disponibles de debian
incus image list images: debian amd64 type=virtual-machine

Última versión de debian y lanzamiento de una vm básica
links https://wiki.debian.org/Status/Stable
incus launch images:debian/14 nombre-vm --vm

Establecer la contraseña de root
incus exec nombre-vm -- passwd root

Entregar una vGPU al guest

Activar en BIOS (asus prime B250)
* Advanced > System Agent (SA) Configuration > VT-d: Enabled.

  • Graphics Configuration > Primary Display: iGPU (o Auto).
  • iGPU Multi-Monitor: Enabled.
  • DVMT Pre-Allocated: 512Mb (por ejemplo)

Confirmar GPU
sudo lspci -nn | grep VGA

Configurar GRUB para g4560
* en /etc/default/grub y GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt kvm.ignore_msrs=1 i915.enable_gvt=1"

  • ejecutar sudo update-grub && sudo reboot
  • en /etc/modules-load.d/gvt-g.conf:
    • kvmgt
    • expgt
    • vfio-mdev

Instancias disponibles de vGPU

for vgpu_type in /sys/class/drm/card0/device/mdev_supported_types/*; do
    echo "Perfil: $(basename $vgpu_type)"
    echo "  Descripción: $(cat $vgpu_type/description)"
    echo "  Disponibles ahora: $(cat $vgpu_type/available_instances)"
done

Asignar una vGPU
incus config device add $NUEVO_HOST nombre_gpu gpu gputype=mdev mdev=i915-GVTg_V5_4 id=0

Quitar la GPU básica
incus config device set nombre-vm video vga=false

Quitar asignación de vGPU
incus config device remove $NUEVO_HOST nombre_gpu

Entregar un dispositivo de red al guest

Listar dispositivos PCI
sudo lspci -nnk

Ver denominación de los diferentes interfaces
sudo lshw -class network -businfo

Entrega SRIOV: Asigna una VF automáticamente (no funciona en B250)
incus config device add nombre_contenedor eth0 nic nictype=sriov parent=enp1s0f0 hwaddr=a2:cc:a2:be:dc:91

Entrega macvlan: Asigna una VF automáticamente)
incus config device add nombre_contenedor eth0 nic nictype=macvlan parent=enp1s0f0 hwaddr=a2:cc:a2:be:dc:9

Entregar el dispositivo
incus config device add router4-openwrt eth-pci pci address=0000:03:00.0

# Dar privilegios a la VM para gestionar hardware
incus config set router4-openwrt security.privileged true

# Permitir que la VM acceda a todas las capacidades del kernel (necesario para drivers PCI)
incus config set router4-openwrt security.nesting true

# Forzar el modo de paso PCI (en algunos casos ayuda a la visibilidad)
incus config set router4-openwrt raw.qemu -- "-device vfio-pci,host=03:00.0,x-vga=on"

Crear VM a partir de un ISO

NUEVO_HOST=nombre-vm

incus init $NUEVO_HOST --empty --vm --device root,size=10GiB --config limits.cpu=1 --config limits.memory=2GiB

# importar ISO (preferiblemente UEFI)
# Los tipo IMG substituyen tal cual al fichero root que genera incus.
incus storage volume import vm_isos [ruta a fichero ISO] [nombre_del_iso_en_pool_reducido] --type=iso
incus config device add $NUEVO_HOST [nombre_del_iso_en_pool_reducido] disk pool=vm_isos source=[nombre_del_iso_en_pool_reducido] boot.priority=10

# Si la ISO no es UEFI
incus config set $NUEVO_HOST security.secureboot=false

# SI necesitamos añadir un disco físico....
incus config device add $NUEVO_HOST sd_120gb disk source=/dev/sdc

# Activamos cpu host-passtrough
incus config set $NUEVO_HOST raw.qemu -- "-cpu host"

# Añadimos, si procede asignación de iGPU y ethernet virtual

# Iniciamos la VM
incus start $NUEVO_HOST

# Activar autostart (si procede):
incus config set $NUEVO_HOST boot.autostart true

# Eliminar el iso de instalación
incus storage volume detach vm_isos [nombre_del_iso] $NUEVO_HOST

# Establecer la clave de root
incus exec $NUEVO_HOST -- passwd root

# Establecer idioma de teclado
incus exec $NUEVO_HOST -- dpkg-reconfigure keyboard-configuration
incus exec $NUEVO_HOST -- setupcon

# conectarse a la máquina virtual (windows/linux)
incus console $NUEVO_HOST --type=vga
 

Setup de container privilegiado para docker

Según: https://ubuntu.com/tutorials/how-to-run-docker-inside-lxd-containers#2-create-lxd-container

incus config set mi_contenedor security.nesting=true security.syscalls.intercept.mknod=true security.syscalls.intercept.setxattr=true

Setup de un nuevo container a la red lechuga

Se condiciona la ejecuión del paso al uso que se le deba hacer éste.

se ejecuta desde el servidor incus

#!/bin/bash
# Este script se ejecuta desde la máquina host
NUEVO_HOST=backups2

# Activar autostart (si procede):
incus config set $NUEVO_HOST boot.autostart true

# Ajuste del timezone (18.04):
incus exec $NUEVO_HOST -- timedatectl set-timezone Europe/Madrid

# Añadir el FQDN del guest
incus exec $NUEVO_HOST -- bash -c "echo $NUEVO_HOST.lechuga.eu > /etc/hostname"

# instalación wget
incus exec $NUEVO_HOST -- apt-get install wget -y

# Recuperación de hosts
incus exec $NUEVO_HOST -- wget https://192.168.1.154/git/git/hosts/raw/branch/master/hosts -O /etc/hosts --no-check-certificate

# Facilidades bash
incus file delete $NUEVO_HOST/root/.bashrc
incus file delete $NUEVO_HOST/etc/skel/.bashrc
incus exec $NUEVO_HOST -- wget https://192.168.1.154/git/git/bash-config/raw/branch/master/etc/bash.aliases -O /etc/bash.aliases --no-check-certificate
incus exec $NUEVO_HOST -- wget https://192.168.1.154/git/git/bash-config/raw/branch/master/etc/bash.bashrc -O /etc/bash.bashrc --no-check-certificate

# OPCIONAL -------------------------------------------

# instalar GIT (si necesario)
incus exec $NUEVO_HOST -- apt-get update
incus exec $NUEVO_HOST -- apt-get install git -y

# Usuario adminlechuga (si necesario)
incus exec $NUEVO_HOST -- useradd --create-home adminlechuga --uid 2008 --shell /bin/bash
incus exec $NUEVO_HOST -- passwd adminlechuga

# Actualización del rsyslog
incus exec $NUEVO_HOST -- wget -q https://192.168.1.154/git/git/rsyslog-config/raw/branch/master/etc/rsyslog.conf -O /etc/rsyslog.conf
 
Ejemplo de configuración de red en /etc/systemd/network/eth0.network

[Match]
Name=eth0

[Network]
Address=192.168.1.188/24
Gateway=192.168.1.1
DNS=192.168.1.154 192.168.1.1

  • Si es Debian, la configuración de red está en /etc/systemd/network/eth0.network
  • Activar el servicio sshd, copiar la configuración del GIT
  • Actualizar los names en los ssl que genera el host srv-internet
  • Configurar los NAT de los servicios en el router
  • Configurar las copias de seguridad según lo indicado en Brocoli.Backups

Actualizaciones automáticas

Ir a configuración de actualizaciones

Políticas de nuevos containers en Lechuga

A través de incus CONFIG DEVICE ADD se añaden los mínimos directorios al contenedor. A partir de ahí, hacer binds internos donde sea necesario.

Por ejemplo, en el host patio se hace un device add de /mnt/pool_(no)*crit, y de ahí salen las nubes, los homes, etc.