Automatizar migración en vivo con libvirt/KVM & Bash Script

ESCENARIO:

Introducción

Vamos a crear dos máquinas virtuales mediante virt-manager, donde el disco duro de MV1 será formato qcow2 y utilizando una imagen base. Y el disco adicional de 1 GiB es un volumen lógico formateado con XFS, al igual que el disco duro de MV2 es un volumen lógico creado previamente en el sistema.

Las máquinas estarán conectadas a un bridge interno de la máquina anfitriona, por lo cual tendremos que añadir reglas iptables para que sean accesible desde la red de nuestra máquina.

Instalaremos un servidor web cuyo datos estarán almacenados en el volumen adicional.

Finalmente configuraremos el sistema, para automatizar en caso de:

  • La máquina virtual MV1 consuma toda su RAM, migraremos la aplicación web a MV2, redimensionando el tamaño del volumen adicional
  • La máquina virtual MV2 consuma toda su RAM, aumente la RAM de MV2 en vivo a 2 GiB ( Configurando apropiadamente los valores de “Max memory” y “Used memory” )

Preparación

Primero nos aseguraremos que tenemos instalado el paquete “qemu-utils”:

Creamos un nuevo directorio para almacenar los ficheros .qcow2 (por organización):

Creamos con la utilidad, un fichero de imagen que tendrá un tamaño máximo de
10 GiB y que contendrá el disco duro de la máquina principal, donde instalamos
el sistema desde cero:

Ahora partimos de que hemos descargo la “ISO de Stretch netinst“:

  1. Crear una máquina nueva
  2. Medio de instalación local (Imagen ISO)
  3. Utilizar imagen disco
  4. 512 RAM 1 Core
  5. Seleccionar el almacenaje -> /home/charlie/QCOWS/stretch.qcow2
  6. Finalizar

Procedemos hacer la instalación de manera gráfica del sistema operativo sobre
el disco “qcow2” (En esta entrada vamos a omitir los pasos para instalar Stretch)

Una vez tenemos ya el sistema operativo instalado sobre el disco duro “stretch.qcow2

Eliminamos la máquina virtual creada, ¡pero no el disco!

Ahora hacemos uso de la funcionalidad que tienen las imágenes qcow2 denominada “aprovisionamiento ligero” para utilizar la imagen anterior como imagen base y crear una nueva máquina virtual sin tener que instalar el sistema de cero:

Antes de proceder a la creación de la MV1, vamos a crear una red nueva en la máquina
anfitriona con libvirt:

Editamos el fichero .xml con el siguiente contenido:

Definimos la red con libvirt:

Iniciar la red y habilitarla para el “autostart”:

Podemos comprobar que la red se refleja como la hemos definido con el comando virsh net-list:

Posteriormente creamos los dos nuevos volumenes lógicos con las siguientes características:

  • 1 GiB formateado con el sistema de ficheros XFS
  • 10 GiB

Ahora formatemos con XFS el volumen lógico “additional”:

Después vamos a crear un fichero xml donde definimos el pool de almacenamiento necesario para hacer uso de los volumenes lógicos en las máquinas virtuales:

Fichero: /etc/libvirt/storage/lvm-group.xml

Ahora creamos el pool con libvirt:

Le activamos el auto arranque y lo iniciamos:

Si quisieramos ver los pools de almacenamiento:

Ejemplo de salida:

Creación MV1 desde el entorno gráfico

Por último añadimos el volumen adicional de 1 GiB:

Creación MV2 desde el entorno gráfico

 

Montar el disco adicional sobre el directorio que almacenara la página web

Montamos el disco adicional sobre ese directorio:

O preferiblemente agregamos la linea en el fichero /etc/fstab para que se monte automáticamente en el arranque del sistema:

Instalar Apache en MV1 y MV2

Instalar Apache2:

Editamos algo del contenido de la página web /var/www/html/index.html

Para el directorio mysql en un principio no tenemos problema ya que la información la tenemos almacenada en el disco adicional, que será desasociada de MV1 y asociada a MV2 en la migración.

Hacer accesible la página web desde la red externa

Si accedemos a la direccion IP interna de la maquina MV1  funciona ya que el bridge interno conectado a nuestra máquina anfitriona con la direccion IP ( 10.0.0.1 ).

Pero que ocurre si queremos que una máquina que este en la misma red que nuestra máquina anfitriona, por ejemplo 172.22.0.0/16 , tendremos que añadir una regla iptable para reenviar las peticiones que vayan al puerto 80 como destino a la máquina virtual MV1:

Será necesario que nuestra máquina anfitriona haga de “router”, entonces primero debemos habilitar esto por software, editando el siguiente fichero en nuestra máquina:

Descomentar en el fichero /etc/sysctl.conf:

Y para hacer que el cambio tome efecto sin necesidad de reiniciar la máquina, ejecutamos:

Y ejecutar estas reglas: ( estas instrucciones no son persistentes, en un reinicio se perderían )

Instalar memtester en ambas máquinas

Para simular el uso excesivo de memoria ram en las máquinas haremos uso del paquete memtester, lo instalamos:

Uso: memtester + cantidad en megabytes de ram que queremos consumir + número de ciclos que queremos que haga para la comprobación.

Nota: parece ser que si no indicamos una unidad de medida por defecto usa megabytes

Copiar clave publica de la anfitriona a las máquinas virtuales

Antes de poder automatizar los 2 casos prácticos que vamos a ver, necesitamos de alguna forma que en el script en bash que vamos a escribir sea innecesario introducir la contraseña del root, si no hacemos uso de una contraseña en texto plano mejor y si evitamos que el script no sea interactivo es otro plus más 😉

Para ello se hace uso de una clave pública que generaremos nueva y sera copiada a ambas máquinas para poder ejecutar de manera remota comandos en ellas sin introducir la contraseña:

Tendremos que editar el fichero /etc/ssh/sshd_config de ambas máquinas y modificar el valor del siguiente parámetro:

Y reiniciar el servicio de ssh una vez modificado lo anterior:

Ahora en nuestra máquina anfitriona generamos una nueva clave pública:

Ahora con el comando ssh-copy-id copiamos la clave de manera remota a las dos máquinas virtuales:

 

CASO PRACTICO

Ahora con la herramienta memtester vamos a subir el uso de la RAM de MV1, para hacerlo algo mas real, la otra máquina estará apagada y tendremos que levantarla para asociarle el volumen adicional a ella, ya que en dicho volumen es donde reside la información que usa el servidor apache.

Pero antes de asociar el volumen a MV2, vamos a aumentarle algo su tamaño simulando que esta corto de espacio en el volumen.

En el otro caso de que el consumo de memoria RAM de la máquina MV2 suba casi al máximo se le aumentará en vivo a 2 GiB de RAM.

En todo momento los usuarios de la red donde se encuentra la máquina anfitriona serán capaces de acceder a la página web servida desde la dirección IP del host.

Todo esto lo vamos a plantear y llevar a cabo con un script escrito en bash que usará libvirt para manejar las máquinas, que será ejecutado cada X tiempo desde una tarea de Crontab:

Script:

Después tendremos que darle permiso de ejecución al script:

Configurar el script en crontab

Ahora necesitamos indicarle al sistema que ejecute este script cada minuto por ejemplo:

Añadir la siguiente linea:

Con esto ya estaría ejecutándose el script cada minuto comprobando si el consumo de RAM de la máquina MV1 o de la máquina MV2 ha llegado casi al límite.

Si vemos el log del sistema:

Y vemos una linea parecida a esta:

Quiere decir que necesitamos tener un servidor de correo instalado en la máquina, para que CRON nos notifique la salida de la tarea en este caso las salidas del script anterior, para ello:

Instalar un servidor de correo, por ejemplo:

Elegimos simplemente la opción de servidor local 

Subir el uso de memoria RAM de MV1

Como root en la máquina MV1, ejecutamos:

Afinaremos el primer valor para ajustar la memoria a utilizar visualizando con el siguiente comando, que queden menos de 30000 kB:

Entonces en cualquier momento de comprobación en intervalor de 1 minuto, el script se habrá ejecutado y entrado en el IF que tenemos indicado en el script, para realizar la migración automática a la maquina MV2.

Ahora si vemos la bandeja de entrada para el usuario root, nos llegaran los mensaje provenientes de la tarea crontab:

Salida:

Si volvemos a visitar desde el navegador se tendrá que seguir visualizando el contenido de la página web 😉

Subir el uso de memoria RAM de MV2

Realizaremos exactamente el proceso anterior ejecutar memtester en este caso le pondremos más tamaño de MB ya que tiene 1 GiB de RAM:

Si hacemos un:

Salida:

Y si comprobamos desde la consola de comandos en MV2, verificamos que así haya sido:

¿ Volver a empezar ?

Si queremos volver al estado iniciar, con este pequeño script podemos eliminar las reglas iptables asignadas para la máquina MV2 y empezar de cero:

Nota: para que funcione ese script tendrá que seguir la máquina MV2 arrancada.

Y si queremos volver a iniciar MV1 y que ofrezca el servicio apache2 con la redirección al puerto de la máquina:

O también valdría con reiniciar la máquina anfitriona 😛

ERRORES

Si no redirecciona bien la página web hacia la otra máquina, revisar con:

Que no exista ya una regla previa en la tabla PREROUTING, para eliminarla ejecutar:

Si nos aparece el siguiente mensaje de error:

Quiere decir que no podemos asignarle más memoria ram de la que le hayamos definido como memoria máxima anteriormente, para cambiar este valor tendremos que ejecutar la siguiente instrucción y esto no tomará efectividad hasta el próximo reinicio de la máquina:

Autor entrada: CharlieJ

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *