En este artículo describo la instalación de un Host Hypervisor basado en KVM, una solución de virtualización basada en el Kernel de Linux para hardware x86 con extensiones Intel VT o AMD-V. Puedes usar cualquier distribución Linux para hacerlo y casi cualquier hardware, en mi caso he optado por el NUC5i5RYK con 16GB de RAM.

HyperKVM

Después de tener funcionando con éxito el Hypervisor ESXi he decidido aprender KVM y darle una oportunidad por varios motivos: garantía de soporte del Hardware casero, menor consumo de memoria (ESXi consume aprox 2GB) y que todas mis VM’s están basadas en Linux/FreeBSD por lo que previsiblemente sea más óptimo ejecutarlas en KVM.

 

Instalación del Host (Gentoo)

Aquí tienes los pasos necesarios para preparar un Host KVM con Gentoo Linux.

Crea un USB para instalar, haz boot con ella y una vez que aparezca el prompt de arranque pulsa TAB para ver las opciones disponibles, en nuestro caso escribimos “gentoo” y pulsamos Intro. Código de teclado usa “13” para Español.

Una de las ventajas del NUC NUC5i5RYK es que trae un Hardware muy bien soportado por linux, así que tras el primer boot el equipo activa la tarjeta Ethernet y recibe una dirección IP vía DHCP.

Te recomiendo que dejes de trabajar en la consola y pases a un puesto de trabajo remoto vía SSH, asigno una contraseña a root, verifico que tiene “PermitRootLogin yes” y arranco el daemon:

A partir de aquí sigo desde un equipo remoto:

Siempre recomiendo guardar toda la información posible sobre el equipo que vamos a instalar, en particular todo lo relacionado con el hardware, que será muy útil a la hora de configurar el kernel.

El ISO que hemos grabado en el USB contiene un kernel con cientos de módulos y hace una detección excelente del hardware de casi cualquier PC, así que ahora vamos a poder “ver” y apuntar qué ha detectado. Usa los comandos siguientes y guarda los resultados. Dejo aquí una copia como referencia sobre lo detectado durante el boot de este Intel NUC5i5RYK

 
Crear las particiones del disco

Antes de crear las particiones hay que identificar el nombre del dispositivo del disco SSD (y no confundirlo con el USB de arranque). Hay un par de maneras de averiguarlo: con dmesg o con fdisk.

Parted

Teniendo claro cual es el disco (/dev/sda) empiezo a preparar las particiones. Notar que voy a usar UEFI y GPT (en vez de MBR) en el disco SSD del equipo.

A continuación creo los file systems

Aunque todavía no podemos usar la versión gráfica “gparted”, una vez que terminé la instalación así es como se ve desde dicho programa:

particionar

Montamos root y boot

Ajustar la hora

Descarga de Stage 3

El “Stage 3” es un “paquete” que contiene un entorno Gentoo mínimo (ya compilado) que facilita el proceso de instalación. Te recomiendo consultar en paralelo el Gentoo Handbook que encontrarás en la Wiki de Gentoo.

Descargo el último “stage3”, el último “portage”:

chroot al nuevo entorno

A partir de ahora “/” (root) apuntará al disco SSD que hemos formateado y donde hemos descomprimido Stage 3 y Portage.

Antes de hacer el chroot debes copiar el /etc/resolv.conf para que la red siga funcionando (sobre todo la resolución de nombres :-))

Modificamos el fichero make.conf

Establezco el mirror y el rsync server

Leemos todas las “News”

Establecemos la Zona horaria

Preparo el /etc/fstab

Instalo herramientas

Instalo herramientas útiles a la hora de trabajar con Portage y con el sistema en general.

Instalo v86d

El uvesafb se apoya en módulos del kernel y en el daemon sys-apps/v86d para cambiar las resoluciones del display

Instalo DHCP Cliente

Para el futuro arranque tras el primer boot, mejor instalar ahora el paquete cliente de DHCP

Preparo portage

Preparo los ficheros de portage

Compilo el Kernel

Los fuentes quedan instalados en /usr/src/linux , a continuación tendrías que parametrizarlo con make menuconfig y luego compilarlo. Si tienes experiencia en parametrizar el kernel, adelante con ello. No olvides activar el soporte de iSCSI en el caso de querer configurar ese tipo de targets (consulta la sección iSCSI al final de este apunte). Si lo prefieres utiliza mi copia del fichero .config para Kernel 4.0.4 para NUC5i5RYK

 

Instalación de “systemd”

Selecciono el perfil adecuado.

Recompilo con el nuevo Profile systemd

Una vez que se selecciona un Profile distinto lo que ocurre es que cambias los valores USE de por defecto del sistema y esto significa que tenemos que “recompilarlo” por completo, así que lo siguiente que vamos a hacer es un emerge que actualice “world”:

Hostname

Con systemd se deja de usar /etc/conf.d/hostname, así que voy a editar a mano directamente los dos ficheros que emplea systemd. – Llamé a mi servidor “edaddepiedrix” (como siempre haciendo alusión a la aldea gala)

Contraseña de root

Antes de rearrancar es importante que cambies la contraseña de root.

Preparo el mtab

Es necesario realizar un link simbólico especial:

Instalo Grub 2 como boot loader

Modifico el fichero de configuración de Grub /etc/default/grub, las siguientes son las líneas importantes:

GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd quiet rootfstype=ext4"
GRUB_TERMINAL=console
GRUB_DISABLE_LINUX_UUID=true

Ah!, en el futuro, cuando te sientas confortable, cambia el timeout del menu que muestra Grub a “0”, de modo que ganarás 5 segundos en cada rearranque de tu servidor Gentoo 🙂

GRUB_TIMEOUT=0

Cada vez que se modifica el fichero /etc/default/grub hay que ejecutar el programa grub2-mkconfig -o /boot/grub/grub.cfg porque es él el que crea la versión correcta del fichero de configuración de Grub: /boot/grub/grub.cfg.

Nota, si en el futuro tienes que modificar el Kernel, no olvides ejecutar grub2-mkconfig tras la compilación (y posterior copiado a /boot) del kernel, tampoco te olvides de haber montado /boot (mount /boot) previamente.

Preparo la red

Uso “nombres de interfaces predecibles”, un servicio de udevd bien descrito upstream. Asigno un nombre específico a la interfaz principal (cambia la MAC a la de tu interfaz).

En la sección de KVM veremos la configuración completa de La Red. De momento creo un fichero bajo /etc/systemd/network, el nombre puede ser cualquiera pero debe terminar en .network. En este caso solo tengo una interfaz física:

A continuación debes habilitar el servicio para el próximo arranque con: systemctl enable systemd-networkd

Otras opciones:
* Arrancar manualmente: systemctl start systemd-networkd
* Re-arrancar (si cambias algo): systemctl restart systemd-networkd
* Verificar: networkctl

 

Reboot

Salgo del chroot, desmonto y rearranco el equipo…

 

Terminar la configuración

Tras el primer reboot nos faltan piezas importantes, vamos a arreglarlo empezando por lo básico.. el teclado 🙂

Teclado y Locale

Parametrizo con systemd el teclado y los locales ejecutando los tres comandos siguientes:

El primer comando modifica /etc/vconsole.conf

El siguiente modifica /etc/X11/xorg.conf.d/00-keyboard.conf

El siguiente modifica /etc/locale.conf

El ultimo simplemente para comprobar

Preparo el fichero locale.gen

Compilo los “locales”

Activo SSHD

Otro indispensable, habilito y arranco el daemon de SSH para poder conectar vía ssh. Si en el futuro quieres poder hacer forward de X11 recuerda poner X11Forwarding yes en el fichero /etc/ssh/sshd_config

Vixie-cron

Instalo, habilito y arranco el cron

Fecha y hora

Para configurar fecha/hora debe utilizarse “timedatectl”. No te pierdas este apunte sobre cómo montar además el servicio NTP.

 

Actualizo portage

Lo primero es hacer un “perl-cleaner” y luego un update completo.

Usuario y rearranque

Desde una shell añado un usuario normal y por último rearranco el equipo. Mira un ejemplo:

Instalo herramientas y paquetes adicionales

nfs-utils para montar volúmenes remotos desde mi NAS

Tienes dos opciones, utilizar /etc/fstab o automount.

Ejemplo con /etc/fstab para acceder a recursos remotos NFS.

Ejemplo usando automount

En mi caso prefiero el segundo método:

Por fin, rearranco de nuevo el equipo, deberías tener ya todos los servicios que hemos configurado.

 
 


 
kvm
 

Configurar la Virtualización con KVM

Ahora que tenemos el linux base (Host) preparado vamos a entrar a configurar KVM. Si estás empezando con esto de KVM verás muchas referencias cruzadas y confusas a KVM y a QEMU, mezclando los conceptos, así que antes de entrar en pista, vamos a ver cual es la diferencia entre KVM y QEmu. Como introducción, recordemos que mi objetivo es conseguir tener un Hypervisor (ahí es donde entra KVM) que se configura en el Kernel y además quiero ejecutar VM’s (máquinas virtuales) como invitados (guest) de dicho Hypervisor, y ahí es donde vamos a necesitar instalar QEmu para crear y manipular los guest, las máquinas virtuales, la monitorización, etc.

QEmu: es un software completo y autónomo que se utiliza para crear discos, VM’s y también para “emular máquinas”, es muy flexible y portátil. Además, es capaz de emular una máquina y transformar el código binario escrito para un procesador, por ejemplo permite ejecutar código MIPS en un MacOSX PPC, o ejecutar código ARM en un x86. Si además se quiere emular algo más que solo el procesador, pues incluye un montón de emuladores adicionales: disco, red, VGA, PCI, USB, puertos serie y paralelo, etc.

KQEmu: Si queremos emular un x86 en un x86 tenemos un módulo del Kernel que ayuda. El QEmu necesita seguir analizando el código en tiempo real para eliminar cualquier “instrucción privilegiada” y reemplazarlas con cambios de contexto, pero para que sea lo más eficiente posible en x86 hay un módulo del kernel llamado kqemu que se encarga de esto. Al ser un módulo del kernel es más óptimo, tiene que cambiar mucho menos código (ojo que aún así el rendimiento sufre algo).

KVM: Por último, KVM son un par de cosas: en primer lugar tenemos un módulo Hypervisor que se activa en el Kernel y que permite poner al equipo en diferentes estados “guest”. Dado que solo se trata de un nuevo estado del procesador, el código no hay que cambiarlo. Este módulo del Kernel además se encarga de los registros MMU (utilizados para manejar máquinas virtuales) y emula hardware PCI. En segundo lugar, KVM es un FORK de Qemu y ambos proyectos están muy sincronizados, mientras que QEmu se focaliza en emular Hardware y poder ejecutarlo en qualquier sitio, el equipo de KVM se focaliza exclusivamente en el módulo del Kernel (que por cierto, si QEmu lo detecta automáticamente lo utiliza).

Cuando trabajan de forma conjunta, KVM arbitra el acceso a la CPU y memoria y QEmu emula los recursos del hardware (disco duro, video, USB, etc.). Cuando trabaja solo, QEmu emula tanto la CPU como el Hardware.

Instalación de KVM y QEmu con todas las herramientas necesarias

Para KVM no hay que instalar nada, solo configurar el kernel y eso ya lo hice al instalar el Linux (tienes una copia de mi .config más arriba. Lo que sí hay que instalar son las herramientas de gestión de la virtualización (que utilizan QEmu por debajo).

Preparo los ficheros USE y ejecuto la instalación. Voy a pedir que se instale el programa virt-manager, en realidad es una forma simplificada de decir que se instale todo lo necesario: app-emulation/qemu y app-emulation/libvirt.

Ejecuto la instalación de QEMU, virt-manager, libvirt, ebtables (lo necesita libvirtd), creo grupo libvirt y añado mi usuario a los grupos apropiados.

Modifico la gestión de permisos de libvirt.

Automatizo el arranque del daemon libvirtd.

Es buen momento para hacer reboot y entrar de nuevo con el usuario normal.

virt-manager es un GUI para gestionar las máquinas virtuales de forma cómoda. Necesita XOrg y en mi caso quiero que funcione vía SSH y ver los gráficos en mi Mac con X11. Si no lo tienes ya instlado hazlo ahora: Instala xclock, xauth para así comprobar todo funciona antes de probar el virt-manager.

Compruebo la instalación KVM/QEmu:

 

La Red (Hypervisor)

Primero hay que tener claro el diseño físico de la red, qué NIC’s tenemos y qué NIC’s virtuales van a presentarse (desde KVM) a las VM’s. Voy a configurar las vNICs con nombres predecibles, con IPs estáticas (sin dhcp) y que no cambie nada al hacer reboot.

Conexiones físicas con KVM

Si empezamos por el diseño físico, es simple, mi Servidor casero, donde se ejecuta Linux Gentoo y el hypervisor KVM, tiene una única tarjeta de red, asi que conecto ese puerto al Switch externo por el cual se entregarán 4 x VLAN’s: 2 (iptv), 3 (voip), 6 (internet), 100 (intranet).

hyprevisor-kvm-fisico

Como voy a recibir 4 VLAN’s tengo que configurar 4 virtual switches, cada uno asociado a una VLAN y así poder ofrecérselos a las máquinas virtuales. Es posible hacerlo con Network Manager y de hecho no es demasiado complejo.

Configuración de varias VLAN’s y Bridge’s Virtuales

El Hypervisor (KVM) necesita usar el código del Kernel “Bridge”, que implementa el estándar ANSI/IEEE 802.1d (en realidad un subconjunto de dicho estándar). Permite crear uno o más bridges lógicos a los que conectaremos las interfaces físicas que deseemos y las lógicas de las máquinas virtuales. En mi caso voy a recibir múltiples VLAN’s por una única interfaz física, así que tan sencillo como crear un virtual Switch para cada VLAN y más adelante presentarle al menos una al propio equipo para poder gestionarlo y el resto a la las VM’s como desee.

kvmvlan

Veamos un ejemplo donde el Hypervisor recibe 4 VLAN’s:

  • WAN (Exterior)
    • vlan6 (datos) – MOVISTAR: PPPoE Internet. Aquí conecto una VM: “Firewall”
    • vlan2 (iptv) – MOVISTAR: Servicio IPTV. Aquí conecto una VM: “Firewall”
    • vlan3 (voip) – MOVISTAR: Servicio Voz. Aquí conecto una VM: “Firewall”
  • LAN (Interior)
    • vlan100 (intranet) – Aquí conecto a este equipo KVM para poder gestionarlo, la VM “Firewall” y otras VM’s de mi Intranet.

 

Estos son los ficheros de configuración:

  • ETH0

  • VLAN-2

  • VLAN-3

  • VLAN-6

  • VLAN-100

  • Dirección IP al Hypervisor KVM para gestionarlo

  • Nota: Para que todo esto funcione el Switch “Físico” al cual está conectado este equipo debe tener configurado que me envíe las VLAN’s 2,3,6,100

  • Rearranco el equipo y debería funcionarnos todo, aunque no está de más tener cerca virt-manager para acceder a la consola por si acaso :-).

 

Las Máquinas virtuales

Ya queda menos, el siguiente paso consiste en crear, modificar, borrar, etc. las máquinas virtuales. Podemos usar la línea de comandos o virt-manager.

Ten en cuenta que las interfaces que he configurado en el Host (Hypervisor) con soporte de VLAN’s se presentarán a las máquinas virtuales sin el tag VLAN y podrás conectar a cualquiera de ellas (o a todas) desde virt-manager

intfVirtuales

virt-manager

Con virt-manager las VM’s se crearán por defecto en el directorio /var/lib/libvirt/images. Recordemos que tendrán la extensión .qcow2. Veamos el ejemplo completo:

kvm-new-vm1

kvm-new-vm2

kvm-new-vm3

kvm-new-vm4

kvm-new-vm5

kvm-new-vm6

kvm-new-vm7

kvm-new-vm8-1

kvm-new-vm8-2

kvm-new-vm8-3

kvm-new-vm9

kvm-new-vm10

kvm-new-vm12

kvm-new-vm13

kvm-new-vm14

 

Comandos y trucos

Siempre tendremos la opción de manipular las máquinas virtuales usando la línea de comandos, veamos unos ejemplos:

  • Creación de una máquina virtual. Utilizo la herramienta virt-install, crearé un copia de Centos7 en el directorio /var/lib/libvirt/images.

La instalación será desatendida si el “ISO” es capaz de hacerlo (de hecho podríamos pasarle el argumento --graphics none, en caso contrario, una vez lanzado, podremos conectar desde otro terminal, ejecutar virt-manager, conectar con la máquina virtual, abrir su consola y repetir lo mismo que hicimos en la instalación gráfica.

  • Mostrar las máquinas virtuales

  • Editar el fichero XML de configuración de una máquina virtual

AVISO: Los ficheros de configuración residen en /etc/libvirt/qemu y deberías guardarte copias de seguridad.

kvmConfigs

  • Mostrar información sobre una máquina virtual