Kernel Based Virtual Machine (KVM)
Contents
- Kernel Based Virtual Machine (KVM)
- Introducción
- Instalación
- Máquinas virtuales del usuario y del sistema
- Crear una nueva invitada
- Configurando una red puente
- Gestionar VMs desde la línea de comandos (CLI)
- Gestionar VMs invitadas con una GUI
- Gestión automática de las VMs al inicio y paro del anfitrión
- Afinación de desempeño
- Migrar invitadas a un albergue Debian
- Solución de problemas
- Véase también
- Enlaces externos
Introducción
KVM es una solución de virtualización completa para Linux en hardware x86 (incluyendo hardware de 64-bits) que contienen las extensiones de virtualización Intel VT o AMD-V. Se compone de un módulo del kernel que puede ser cargado, kvm.ko, que provee la infraestructura de virtualización base, y un módulo específico para el tipo de procesador, kvm-intel.ko o kvm-amd.ko.
En Debian, ?Xen es la alternativa a KVM. (?VirtualBox no está en Debian main (Buster) y tampoco en Buster-Backports, 794466).
Instalación
Se puede hacer una instalación mínima con solo QEMU y KVM, pero la mayoría de los usuarios querrán también libvirt para configurar y gestionar convenientemente las máquinas virtuales (libvirt-daemon-system - libvirt, virt-manager - una GUI para libvirt). Normalmente se debe instalar:
# apt-get install qemu-system libvirt-clients libvirt-daemon-system
Al instalar en un servidor, se puede agregar la opción no-install-recommends para prevenir la instalación de paquetes gráficos innecesarios.
# apt-get install --no-install-recommends qemu-system libvirt-clients libvirt-daemon-system
El demonio libvirt-bin se iniciará automáticamente en la partida y cargará los módulos KVM apropiados, kvm-amd o kvm-intel, incluidos en distribución base de Linux de Debian. Si pretendes crear VMs desde línea de comandos (CLI), instala virtinst.
Para poder gestionar máquinas virtuales como usuario normal, ese usuario necesita ser añadido a grupo libvirt:
# adduser <elUsuario> libvirt
Debería ser capaz de listar tus dominios, es decir las maquinas virtuales administradas por libvirt
# virsh list --all
Máquinas virtuales del usuario y del sistema
Por defecto, si virsh se ejecuta como un usuario normal, se conectará a libvirt usando qemu:///<cadena URI de sesión>. Esta URI permite a virsh gestionar solamente el conjunto de VMs que pertenezcan a ese usuario. Para gestionar el conjunto de VMs del sistema (p. ej: VMs que pertenezcan al root) virsh debe ejecutarse como root o con la URI qemu:///system :
$ virsh --connect qemu:///system list --all
Para que no sea necesario especificar la opción --connect en cada comando, se puede establecer en la variable de entorno LIBVIRT_DEFAULT_URI:
$ export LIBVIRT_DEFAULT_URI='qemu:///system'
Crear una nueva invitada
El modo más fácil de crear y gestionar VMs invitadas es usando una aplicación gráfica (GUI) como
AQEMU aqemu.
Virtual Machine Manager virt-manager.
Como alternativa, puedes crear una VM invitada en la linea de comandos. Abajo hay un ejemplo de la creación de un invitado basado en Buster con el nombre buster-amd64:
virt-install --virt-type kvm --name buster-amd64 \ --cdrom ~/iso/Debian/debian-10.0.0-amd64-netinst.iso \ --os-variant debian10 \ --disk-size=10 --memory 1000
Puesto que la invitada aun no tiene conexión de red, necesitarás utilizar la GUI de virt-viewer para completar la instalación.
Puedes evitar bajar la ISO usando la opción de ubicación --location.
virt-install --virt-type kvm --name buster-amd64 \ --location http://deb.debian.org/debian/dists/buster/main/installer-amd64/ \ --os-variant debian10 \ --disk-size=10 --memory 1000
Para instalar utilizando una consola de texto en vez de la gráfica se debe usar una puerta serial en virt-install
virt-install --virt-type kvm --name buster-amd64 \ --location http://deb.debian.org/debian/dists/buster/main/installer-amd64/ \ --os-variant debian10 \ --disk size=10 --memory 1000 \ --graphics none \ --console pty,target_type=serial \ --extra-args "console=ttyS0"
Para una instalación completamente automática debes considerar preseed o debootstrap.
Configurando una red puente
Entre VMs invitadas
Por defecto, QEMU usa macvtap en modo VEPA para proveer acceso a red con NAT o acceso puenteado con otra invitada. Esta configuración permitirá a las invitadas acceder a Internet (si es que hay alguna conexión a internet en la maquina anfitriona), pero no permitirá a la anfitriona ni a otras máquinas en la misma LAN ver o acceder a las invitadas.
Entre anfitrión e invitadas
Red por defecto libvirt
Si utilizas libvirt para gestionar tus VMs, libvirt proporciona una red puenteada NAT llamada "default" que permite al anfitrión comunicarse con las invitadas. Esta red está disponible solamente para los dominios de sistema (Esto es, las VMs creadas por root o que usen la URI de conexión qemu:///system ). Las VMs que usan esta red obtienen una IP en el rango 192.168.122.1/24 y se les proporciona DHCP vía dnsmasq. Esta red no se inicia automáticamente. Para arrancarla usa:
virsh --connect=qemu:///system net-start default
Para hacer que la red por defecto arranque automáticamente usa:
virsh --connect=qemu:///system net-autostart default
Para que las cosas funcionen de este modo necesitas tener instalados estos paquetes recomendados dnsmasq-base, bridge-utils and iptables.
Acceder a los invitados por su nombre
Una vez que la red por defecto está instalada, se puede configurar el servidor dnsmasq de libvirt, de tal manera de acceder a las invitadas por su nombre. Esto es útil cuando se tienen múltiples visitas y se quiere acceder a ellas por su nombre en vez de su IP.
Primero, configure la red por defecto de libvirt. Ejecute virsh --connect=qemu:///system net-edit default y añada a la configuración la siguiente linea (por ejemplo, después de la linea mac)
<domain name='libvirt' localOnly='yes'/>
libvirt es el nombre del dominio para las visitas. Puede ser otro nombre, pero evite usar local pues puede estar siendo usado por mDNS. Es importante agragar hlocalOnly='yes' para asegurar que las consultas por el dominio no son transferidas mas arriba.
La configuración de red debería ser algo como:
<network connections='1'> <name>default</name> <uuid>66b33e64-713f-4323-b406-bc636c054af5</uuid> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <bridge name='virbr0' stp='on' delay='0'/> <mac address='52:54:00:af:9f:2a'/> <domain name='libvirt' localOnly='yes'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254'/> </dhcp> </ip> </network>
hora se debe configurar las máquinas visita con sus nombres. Por ejemplo, si se quiere una visita con el nombre 'vm1', entre en la máquina y corra:
sudo hostnamectl set-hostname vm1.libvirt
Luego se debe configurar el NetworkManager de la visita, de manera que utilice el servidor DNS del anfitrión. Primero, el anfitrión debe correr su propia versión de dnsmasq. Esto se consigue creando el archivo /etc/NetworkManager/conf.d/libvirt_dns.conf con el siguiente contenido:
[main] dns=dnsmasq
Segundo, informar a las visitas que cualquier consulta respecto al dominio libvirt debe ser enviada al dnsmasq del anfitrion. Esto se hace instalando el archivo /etc/NetworkManager/dnsmasq.d/libvirt_dns.conf con el contenido:
server=/libvirt/192.168.122.1
libvirt es el dominio here definido en la configuración de la red del anfitrion. La dirección IP debe corresponder con la definida en la red por defecto de libvirt. Esta es la dirección que aparece en la linea <ip address='xxx.xxx.xxx.xxx.' netmask='255.255.255.0'> de la configfuración mas arriba.
Relanzar el NetworkManager en cada visita
sudo systemctl restart NetworkManager
De ahora en adelante, las visitas pueden ser accedidas utilizando su nombres, por ejemplo, ssh vm1.libvirt.
Puenteo manual
Para permitir comunicaciones entre el anfitrión y las invitadas, puedes establecer un puente macvlan sobre una interfaz simple (dummy). Después de la configuración, puedes establecer usando la interfaz dummy0 (macvtap) en modo puente como la configuración de la red en la configuración de VMs invitadas.
modprobe dummy ip link add dummy0 type dummy ip link add link dummy0 macvlan0 type macvlan mode bridge ifconfig dummy0 up ifconfig macvlan0 192.168.1.2 broadcast 192.168.1.255 netmask 255.255.255.0 up
Entre anfitrion, VMs invitadas y el mundo
Para permitir comunicaciones entre el anfitrion, invitadas y el mundo exterior, puedes ?configurar un puente y como se describe en la página de QEMU.
Por ejemplo, puedes modificar el fichero de la configuración de la red /etc/network/interfaces para establecer una interfaz de ethernet eth0 para una interfaz de puente br0 similar a la de abajo. Tras la configuración, puedes utilizar la interfaz br0 como la configuración de conexión de red en VMs invitadas.
auto lo0 iface lo inet loopback # La interfaz de red primaria auto eth0 # Asegúrate de que no recibimos direcciones en nuestro dispositivo inicial iface eth0 inet manual iface eth0 inet6 manual #Establece el puente y dale una ip estática auto br0 iface br0 inet static address 192.168.1.2 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 bridge_ports eth0 bridge_stp off bridge_fd 0 bridge_maxwait 0 dns-nameservers 8.8.8.8 #permite autoconfiguración para ipv6 iface br0 inet6 auto accept_ra 1
Una vez correctamente configurada, deberías ser capaz de usar el puente en nuevas máquinas virtuales con:
virt-install --network bridge=br0 [...]
Gestionar VMs desde la línea de comandos (CLI)
Puedes usar el comando virsh(1) para iniciar y parar máquinas virtuales. Las VMs se pueden generar usando virtinst. Para mayor detalle mira la página de libvirt. Las VMs se pueden controlar usando el comando kvm de modo similar a ?QEMU. Algunos de los comandos mas frecuentemente usadas:
Arrancar una VM invitada configurada "VMGUEST":
# virsh start VMGUEST
Notificar a la VM invitada "VMGUEST" que se apague grácilmente:
# virsh shutdown VMGUEST
Forzar a la VM invitada "VMGUEST" a que se apague como sea, en caso de que esté colgada, p.ej: el apagado grácil no funciona:
# virsh destroy VMGUEST
Gestionar VMs invitadas con una GUI
Por otro lado, si quieres usar una interfaz gráfica de usuario GUI para gestionar las VMs, puedes usar alguno de:
AQEMU aqemu.
Virtual Machine Manager virt-manager.
Gestión automática de las VMs al inicio y paro del anfitrión
El comportamiento de las invitadas al iniciarse o apagarse la albergue se configura en el fichero /etc/default/libvirt-guests.
Este fichero especifica si las invitadas deberían apagarse o suspenderse, si deberían ser reiniciadas al arrancar la albergue, etc.
El primer parámetro define donde encontrar las invitadas en funcionamiento. Por ejemplo:
# URIs para comprobar invitadas en ejecución # ejemplo: URIS='default xen:/// vbox+tcp://host/system lxc:///' URIS=qemu:///system
Afinación de desempeño
Abajo hay opciones que pueden mejorar el desempeño de las VMs invitadas.
CPU
Asignar núcleos de CPU virtuales a núcleos CPU físicos dedicados
Edita la configuración de VMs invitadas, asume que el nombre de la VM invitada es "VMGUEST" teniendo 4 núcleos CPU virtuales
# virsh edit VMGUEST
añade los códigos de abajo tras la línea "<vcpu ..."
<cputune> <vcpupin vcpu='0' cpuset='0'/> <vcpupin vcpu='1' cpuset='4'/> <vcpupin vcpu='2' cpuset='1'/> <vcpupin vcpu='3' cpuset='5'/> </cputune>
donde vcpu son las identificaciones de núcleos CPU virtuales; cpuset son las identificaciones de los núcleos de CPU físicos reservados. Ajusta el número de líneas de vcpupin para reflejar el número de vcpu y cpuset para reflejar la reserva real de núcleos físicos de CPU. En general, la mitad superior de los núcleos físicos de CPU son los núcleos de hyperthreading, por lo cual no pueden tener una dedicación completa, en cambio tienen la ventaja de incrementar la tasa de acierto de memoria cache. Una simple regla general para establecer cpuset es:
- Para la primera vcpu, asigna un número de la parte media baja en cpuset. Por ejemplo, si el sistema tiene 4 núcleos y 8 hilos, el valor válido de cpuset está entre 0 y 7, la mitad inferior está por tanto entre 0 y 3.
- Para la segunda y cada segunda vcpu, asigna su parte media superior de número cpuset. Por ejemplo, si asignaste la primera cpuset a 0, entonces la segunda cpuset debería establecerse a 4.
Para la tercera vcpu y superiores, puede que necesites determinar cuál CPU física comparte la cache de memoria más con la primera vcpu como se describe aquí y asignarla al número cpuset para incrementar la tasa de acierto de memoria cache.
E/S de disco
La E/S de disco es normalmente el cuello de botella debido a sus características. A diferencia de la CPU y la RAM, el albergue puede que no reservar almacenamiento dedicado para una VM. Peor aún, el disco es el componente mas lento de todos. Hay dos tipos de cuellos de botella: rendimiento y tiempo de acceso. Un disco rotatorio moderno puede proveer 100MB/s, lo el cual es suficiente para la mayoría de los sistemas, mientras que solo provee unas 60 transacciones por segundo (tps).
Un modo de mejorar la latencia de E/S es usar un pequeño pero rápido dispositivo de estado solido (SSD) como cache para los discos rotatorios tradicionales. La pagina del manual de LVM lvmcache(7) describe como configurarlo.
Para la máquina que provee el albergue, puedes comprobar diferentes parámetros de E/S de disco para obtener los mejores tps para tu disco. Abajo hay un ejemplo de afinación de disco y benchmarking usando fio:
# echo deadline > /sys/block/sda/queue/scheduler # echo 32 > /sys/block/sda/queue/iosched/quantum # echo 0 > /sys/block/sda/queue/iosched/slice_idle # echo 1 > /proc/sys/vm/dirty_background_ratio # echo 50 > /proc/sys/vm/dirty_ratio # echo 500 > /proc/sys/vm/dirty_expire_centisecs # /sbin/blockdev --setra 256 /dev/sda # fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=/opt/fio.tmp --bs=4k --iodepth=64 --size=8G --readwrite=randrw --rwmixread=75 --runtime=60
para VMs invitadas tipo Windows, puede que desees cambiar el controlador IDE incluido por Windows (lento pero multi-plataforma) por el rápido controlador KVM pero específico VirtIO driver. Como resultado, el método de instalación para VMs invitadas tipo windows a continuación es un poco mas complicado pues proporciona un modo de instalar ambos controladores y usar uno de acuerdo a tus necesidades. Bajo virt-manager:
- Controlador nativo para VMs invitadas de Windows
- Crea una nueva VM invitada con la configuración de abajo:
Almacenamiento IDE para un contenedor de SO Windows, asignarle, por ejemplo, el nombre WINDOWS.qcow2
- IDE CDROM, vincula la ISO de SO Windows al CDROM
- Arranca la VM invitada e instala Windows como siempre
- Apaga la VM invitada
- Reconfigura la VM invitada con la configuración de abajo:
- Añade un almacenamiento simple (dummy) de VirtIO / VirtIO SCSI con tamaño de 100MB, p.ej: DUMMY.qcow2
Vincula el controlador VirtIO de CD ISO con el CDROM
- Reinicia la VM invitada
- Instala el controlador de VirtIO desde el IDE CDROM cuando Windows pregunte por el controlador del nuevo hardware
- Para VMs invitadas de Windows 10 y posteriores
- ejecuta "cmd" como administrador y ejecuta la orden de abajo
> bcdedit /set {current} safeboot minimal
- ejecuta "cmd" como administrador y ejecuta la orden de abajo
- Apaga la VM invitada
- Reconfigura la VM invitada con la configuración de abajo:
Elimina el almacenamiento IDE para SO de Windows, NO elimines WINDOWS.qcow2
Elimina el almacenamiento VirtIO para el almacenamiento dummy, puedes eliminar DUMMY.qcow2
- Elimina el almacenamiento IDE para el CD ROM
Añade un nuevo almacenamiento VirtIO / VirtIO SCSI y vincula a WINDOWS.qcow2
- Reinicia la VM invitada
- Para las VMs invitadas de Windows 10 y posteriores
- Entra en modo seguro de Windows 10 de la VM invitada y ejecuta la orden de abajo
> bcdedit /deletevalue {current} safeboot
- Reinicia la VM invitada
- Entra en modo seguro de Windows 10 de la VM invitada y ejecuta la orden de abajo
- Crea una nueva VM invitada con la configuración de abajo:
- Controlador nativo para VMs invitadas de Linux
- Selecciona almacenamiento VirtIO / VirtIO SCSI para los contenedores
- Reinicia la VM invitada
- Alamacenamiento VirtIO / VirtIO SCSI
- El Almacenamiento VirtIO SCSI proporciona características más enriquecidas que el almacenamiento VirtIO cuando la VM invitada tiene almacenamiento múltiple. Los desempeños son idénticos si la VM invitada tiene un simple almacenamiento.
- Cache de disco
- Selecciona "None" para el modo de cache de disco, "Native" para modo E/S, "Unmap" para el modo de descarte
- Hilos de E/S dedicados
- El especificar los hilos de E/S puede reducir los bloqueos significativamente. Un (1) hilo de E/S es suficiente en la mayoría de los casos. Edite la configuración de la VM. Supongamos que el nombre de la máquina es "VMGUEST"
virsh edit VMGUEST
despues de la primera linea "<domain ...>", añada
<iothreads>1</iothreads>
despues de la linea para el controlodaor de disco, por ejemplo "<controller type='scsi' ...>" si se esta utilizando el controlador Virtio-SCSI
<driver iothread='1'/>
- El especificar los hilos de E/S puede reducir los bloqueos significativamente. Un (1) hilo de E/S es suficiente en la mayoría de los casos. Edite la configuración de la VM. Supongamos que el nombre de la máquina es "VMGUEST"
E/S de red
Usando virt-manager:
- Controlador nativo para VMs invitadas de Windows
- Selecciona VirtIO para el adaptador de red
Adjunta el controlador VirtIO de CD ISO para el IDE CDROM
- Reinicia la VM invitada, Windows encontró un nuevo hardware adaptador de red, instala el controlador VirtIO desde el IDE CDROM
- Controlador nativo para VMs invitadas de linux
- Selecciona VirtIO para adaptador de red
- Reinicia la máquina invitada
Memoria
- Soporte de Memoria de páginas enormes (Huge Page Memory)
- Calcula el número de paginas enormes necesarias. Cada página enorme tiene de tamaño 2MB, como resultado podemos usar la formula de abajo para el cálculo.
Número de Paginas Enormes = Memoria Total de VM invitada en MB / 2
p.ej: 4 VMs invitadas, cada cual usando 1024MB, entonces el Número de paginas enormes = 4 x 1024 / 2 = 2048. Nota que el sistema puede colgarse si la memoria adquirida es mayor a la disponible por el sistema. - Configura soporte de Paginas Enormes de memoria usando el siguiente comando. Puede que la Memoria Enorme no se reserve si está demasiado fragmentada, por lo que es mejor añadir el código a /etc/rc.local
echo 2048 > /proc/sys/vm/nr_hugepages mkdir -p /mnt/hugetlbfs mount -t hugetlbfs hugetlbfs /mnt/hugetlbfs mkdir -p /mnt/hugetlbfs/libvirt/bin systemctl restart libvirtd
- Reinicia el sistema para permitir el soporte de páginas enormes de memoria. Verifica el correcto funcionamiento con el comando de abajo.
# cat /proc/meminfo | grep HugePages_ HugePages_Total: 2048 HugePages_Free: 2048 HugePages_Rsvd: 0 HugePages_Surp: 0
- Edita la configuración de la VM invitada, asume que el nombre de la VM invitada es "VMGUEST"
# virsh edit VMGUEST
Añade los codigos de abajo tras la línea "<currentMemory ..."
<memoryBacking> <hugepages/> </memoryBacking>
- Arranca la VM invitada "VMGUEST" y verifica si está usando paginas gigantes de memoria con el comando de abajo.
# virsh start VMGUEST # cat /proc/meminfo | grep HugePages_ HugePages_Total: 2048 HugePages_Free: 1536 HugePages_Rsvd: 0 HugePages_Surp: 0
Huge Page Counts = Total VM Guest Memory In MB / 2
- Calcula el número de paginas enormes necesarias. Cada página enorme tiene de tamaño 2MB, como resultado podemos usar la formula de abajo para el cálculo.
Migrar invitadas a un albergue Debian
Migrar invitadas desde RHEL/CentOS 5.x
Hay unos detalles menores en los ficheros XML de configuración de invitadas (/etc/libvirt/qemu/*.xml que necesitas modificar:
La variable Machine en la sección <os> debería decir pc, no rhel5.4.0 o similar
La entrada Emulator debería apuntar a /usr/bin/kvm, no a /usr/libexec/qemu-kvm
En otras palabras, las secciones relevantes deberían parecerse a esto:
<os> <type arch='x86_64' machine='pc'>hvm</type> --- recortado --- <devices> <emulator>/usr/bin/kvm</emulator>
Si tenías configurada una red puenteada en el albergue CentOS, por favor mira el ?artículo wiki sobre cómo hacer que funcione en Debian.
Solución de problemas
No hay puente de red disponible
virt-manager usa una red virtual para sus invitadas, por defecto esta encaminada a 192.168.122.0/24 y tu deberías ver esto al escribir ip route como root.
Si esta ruta no esta presente en la tabla de enrutamiento del kernel entonces las invitadas fallaran al conectar y no sera posible completar la creación de invitadas.
Arreglarlo es sencillo, abre virt-manager y ve a editar "Edit" -> detalles de invitada "Host details" -> pestaña de redes virtuales "Virtual networks". Desde ahí puedes crear una red virtual propia o puedes intentar arreglar la que hay por defecto. Normalmente el problema consiste en que no se ha iniciado la red por defecto.
no se puede crear un puente 'virbr0': Existe el fichero:
Para resolver este problema puedes eliminar la virbr0 ejecutando esto:
brctl delbr virbr0
Abre virt-manager y vea a editar "Edit" -> detalles del Albergue "Host details" -> redes virtuales "Virtual networks" arranca la red por defecto.
Puedes comprobar tu estado de red
virsh net-list --all
Opcionalmente puedes usar una red puente BridgeNetworkConnections
La invitada Windows se cuelga frecuentemente o hace BSOD
Algunos invitadas Windows usando ciertas CPU ultimo modelo de N-hilos pueden colgarse con asiduidad o dar BSOD, eso es un fallo conocido de kernel mientras no se arregle en Jessie (TBC en Stretch). La solución que verás abajo se puede aplicar añadiendo una sección <hyperv>...</hyperv> en la configuración de la invitada vía la orden virsh edit GUESTNAME:
<domain ...> ... <features> ... <hyperv> <relaxed state='on'/> </hyperv> </features> ...
Véase también
Puedes encontrar un ejemplo para probar. No puedes hacerlo remotamente.
Enlaces externos
Por favor, añadid enlaces a documentaciones externas. Esto no es un lugar para enlaces a productos no libres comerciales.
https://www.linux-kvm.org/ - Kernel Based Virtual Machine homepage;
https://www.linux-kvm.org/page/HOWTO - Howto's
https://web.archive.org/web/20080103004709/http://kvm.qumranet.com/kvmwiki/Debian - KVM on Debian Sid (old KVM wiki)
https://web.archive.org/web/20190827041509/http://www.makeinstall.es/2011/04/virtualizar-con-la-maquina-virtual-del.html - [Tutorial] Virtualizar con la Máquina Virtual del Kernel (KVM)
| CategoryVirtualization | CategorySoftware | CategorySystemAdministration