Jugando con OpenNebula

3
15732

En este tutorial aprenderemos qué es OpenNebula y para qué se usa. Daremos detalles de uso básico por terminal y un ejemplo en Java. Además, mostraremos un ejemplo de qué se puede llegar a hacer.

Índice de contenidos

1. Introducción

OpenNebula es una aplicación de cloud computing que permite la organización, manejo y despliegue de tu propia nube. Es apto tanto para entornos empresariales como para entornos más sencillos debido a sus posibilidades de personalización.
Además, es un proyecto relativamente nuevo ya que comenzó en 2005, precisamente por un equipo de españoles como trabajo de investigación.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: 3.3 Ghz Intel Core I7, 16GB DDR3
  • Sistema Operativo anfitrión: Windows 8.1 (es indiferente, usamos VMs)
  • Entorno de ejecución:
    • VMWare Workstation 11.1
    • Sistema Operativo: Ubuntu 14.04 LTS Server
    • Número de máquinas virtuales: 3 (servidor, nodo y datastore)
    • OpenNebula: 4.12

3. Instalación

En este tutorial no hablaremos de la instalación para poder centrarnos más en explicar el uso básico de OpenNebula, y qué utilidades puede tener.

Para un comienzo rápido es recomendable seguir la guía para ubuntu y KVM. En esa guía se crea un entorno en el que existirán tres roles: servidor, nodo y datastore. Cada rol puede ser adoptado por una máquina distinta, aunque una misma máquina podría ejecutar todos los roles. Esto último no es recomendable puesto que en el mundo real no se va a tener una máquina para todo.

Se puede seguir la guía de instalación aquí:

[opción rápida]
[opción general]

4. Sunstone, la interfaz web de OpenNebula

La forma más sencilla de empaparse del funcionamiento de OpenNebula es mediante su interfaz web. Proporciona una visión global de lo que se puede hacer, además de un marketplace con un catálogo de imágenes para máquinas virtuales listas para ser usadas, ya sea de Sistemas Operativos completos o de imágenes ligeras destinadas únicamente a hacer pruebas.

Arriba vemos cómo sería Sunstone con máquinas funcionando. Todo lo que explicaremos durante el resto del tutorial puede ser también reproducido a través de esta interfaz web.

5. Almacenamiento

El almacenamiento en OpenNebula se produce en los datastores. Estos datastores sirven para almacenar las imágenes de las máquinas virtuales. Pueden ser de tres clases: de imágenes, de sistema y de archivos.

  • Imágenes: albergan el repositorio de imágenes de disco, es decir, las imágenes que podemos usar para crear nuevas máquinas virtuales. Desde este datastore se copian o mueven las imagenes cuando se crea una máquina.

  • De sistema: en este tipo se encuentran las máquinas virtuales en ejecución.

  • Archivos: un datastore especial que no alberga imágenes. Puede albergar cualquier otro tipo de archivo para ser usado posteriormente, como por ejemplo un archivo de contexto para pasarlo a una máquina virtual. Luego veremos para qué pueden servir estos archivos de contexto.

Por defecto OpenNebula se instala con tres datastores, uno de cada tipo de los mencionados: default, system y files, siguiendo el orden en el que los hemos descrito.

Lo normal es instalar datastores en servidores NAS que, en función de la tecnología que tengan por debajo, la transferencia de imágenes a un nodo puede ocurrir de distintas formas, según compatibilidad y drivers. OpenNebula es compatible con varios, incluyendo la opción de un directorio compartido (NFS) o copiado de las imágenes a través de ssh. También existen drivers más específicos como qcow2 o vmfs, de qemu y VMware respectivamente, etc.
Para más información sobre el almacenamiento consultar el siguiente enlace: http://docs.opennebula.org/4.12/administration/storage/index.html

6. Gestión típica. Operaciones básicas

Nota: Todas las órdenes que se usen a continuación se tienen que ejecutar como usuario «oneadmin».

6.1. Imágenes

El primer paso para usar OpenNebula es crear o instalar una imagen en el servicio, que será normalmente un sistema operativo listo para arrancarse. Recordamos que existe la posibilidad también de instalar una imagen a través del marketplace disponible a través de la interfaz web de OpenNebula. Nosotros vamos a usar el comando oneimage para instalar nuestra propia imagen. Podemos hacerlo a través de una plantilla o a través de línea de órdenes.

Al crear una imagen hay dos elementos indispensables: el nombre de la imagen a crear y la ubicación del archivo (la imagen de disco). Se pueden especificar otros elementos como el datastore específico en el que guardar la imagen, si va a ser persistente o no (esto permitirá arrancar la máquina virtual casi al instante en lugar de tener que hacer una copia de la imagen), el driver que se va a usar (qcow2, raw, etc.), etc.

$> oneimage create –-name “imagen ubuntu” –-driver qcow2 \
--path “/home/local/imagenes/ubuntu_14.04_desktop.qcow2” \
--type OS –-datastore default

A través de esta orden podemos también eliminar cualquier imagen existente e incluso clonarlas, entre otras cosas.

6.2. Redes virtuales

El segundo paso es crear una red virtual que asignar a nuestras máquinas virtuales (aunque es posible desplegar máquinas virtuales sin red). Estas redes mapean una o varias redes el nodo en el que se despliega la máquina virtual, por tanto, dependen de la configuración de red en el nodo. Para las redes hay varios elementos que configurar:

  • Atributos clave, como el nombre de la red, dispositivo bridge, si se activa VLAN, etc.

  • Espacio de direcciones disponible (Address Range, AR): tipo de red (IP4, IP6, Ethernet), tamaño de la red, rango de direcciones, etc.

  • Parámetros de contextualización, como puerta de enlace, servidor DNS, máscara de red, etc.

Es recomendable crear las redes a partir de plantillas debido al gran número de atributos que es necesario definir. Por tanto, creamos la plantilla y la instalamos con el comando onevnet. Se puede comprobar con el siguiente ejemplo cómo quedaría una red sencilla.

NAME = “red”
BRIDGE = br0

#Parámetros de context
NETWORK_ADDRESS = "192.168.1.0"
NETWORK_MASK    = "255.255.255.0"
DNS             = "8.8.8.8"
GATEWAY         = "192.168.1.1"

#Rango de direcciones
AR=[
	TYPE = “IP4”,
	IP   = "192.168.1.100",
	SIZE = "10”
]

Es recomendable consultar la documentación para así comprobar la multitud de posibilidades de configuración que existen.

6.3. Plantillas para máquinas virtuales

Para poder usar una imagen de nuestro repositorio y, en definitiva, crear una nueva máquina virtual es necesario especificar una plantilla del a misma. Esto se consigue a través de la orden onetemplate.

Las plantillas para máquinas virtuales necesitan varios elementos para ser instanciadas:

  • Asignación de recursos de la máquina virtual, como por ejemplo la cantidad de memoria RAM o el número de CPUs de los que va a disponer.

  • La imagen que va a usar, de las que hemos creado con anterioridad.

  • Pertenencia a alguna red virtual, como la creada en el apartado anterior. Aunque es opcional suele estar muy presente: interesa que nuestras máquinas virtuales.

Sumándose a éstos hay otros atributos muy interesantes que, aunque opcionales, pueden ser de gran utilidad:

  • Opciones de contextualización. Abren la puerta a todo tipo de personalizaciones para nuestra máquina.

  • Posibilidad de añadir un servidor VNC a la máquina para después conectarnos remotamente.

Un ejemplo de creación de una imagen usando la red de ejemplo y la imagen de ejemplo creadas en los apartados anteriores sería así en línea de órdenes, usando el comando onetemplate:

$> onetemplate create --name “Ubuntu template” --cpu 1 --vcpu 1 --arch x68_64 \
--memory 2048 --disk “imagen ubuntu” --vnc --nic “red” --ssh

Como podemos observar el número de argumentos es demasiado grande. Del mismo modo que antes con la red, se puede crear la plantilla en texto plano y luego agregarla al sistema mediante la orden anterior. Por supuesto es posible actualizar o eliminar también las plantillas usando la misma orden.

6.4. Máquinas virtuales, al fin

Llegamos por fin a lo que pretendíamos desde el principio: crear máquinas virtuales. Afortunadamente esta fase es muy sencilla, únicamente hay que instanciar una de las plantillas de máquinas virtuales que hemos creado y listo. Se pueden listar las plantillas que tenemos antes, e instanciar nuestra máquina por medio del nombre o el ID.

$> onetemplate list
	ID USER     GROUP    NAME                         REGTIME
	 6 oneadmin oneadmin Ubuntu template            09/28 17:20:07

$> onetemplate instantiate “Ubuntu template”
$> onetemplate instantiate 6

Una vez hecho esto, el planificador de OpenNebula será el encargado de asignar a un nodo que satisfaga los requisitos de la plantilla el despliegue de la máquina virtual. Podremos ver el estado de las máquinas virtuales con onevm list.

$> onevm list
	ID USER      GROUP    NAME		STAT	CPU		MEM		HOSTNAME	TIME
	 0 oneadmin  oneadmin my_vm		pend	0		0K					00 00:00:03

6.5. Contextualizar

Contextualizar una máquina virtual significa, en otras palabras, personalizarla a nuestra medida. Se trata ya de temas más avanzados. La imagen que hayamos creado tiene que estar preparada para interactuar con OpenNebula, debe tener instalado el paquete opennebula-context .

Entre las cosas que podemos hacer con ello, destacamos las siguientes:

  • Cambiar la configuración de red de la máquina, así adaptarla a la red en la que se encuentre el host, en función de los parámetros de red que hayamos configurado y las redes que le hayamos configurado.

  • Introducir los parámetros deseados a la máquina virtual, como por ejemplo la clave SSH del nodo, de forma que no necesitemos contraseña a la hora de hacer SSH a la máquina virtual.

  • Introducir cualquier fichero deseado a la máquina. Esto da la opción de introducir cualquier script o archivo externo. Las posibilidades son infinitas.

Aprovechando la opción del script externo se puede usar una misma imagen para varias cosas, de forma que dependiendo del script inicial que ejecutemos la máquina virtual se prepare de una forma u otra, con el consiguiente ahorro de espacio. La alternativa a esto sería tener varias imágenes específicas, aunque el espacio consumido en el datastore aumentaría considerablemente.

La contextualización se define a través de las plantillas. Esto creará una imagen de contextualización (que funciona como un CD para la máquina virtual, como se puede apreciar en la imagen) mediante el parámetro CONTEXT en las plantillas.

contextualization

Del parámetro CONTEXT colgarán diversos valores, como NETWORK, que indicará si se quiere o no contextualizar la red, SSH para la clave pública ssh o cualquier tipo de variable personalizada. Finalmente el valor que acompañe al atributo FILES serán los archivos (las rutas a ellos) que queremos pasar a las máquinas. Los scripts de los que hablábamos antes.

6.6. Varios

Destacar que existen muchas más órdenes además de las comentadas, ya sean de mantenimiento y control o de configuración de nuestro entorno. Por ejemplo podemos gestionar los datastores con el comando onedatastore, los nodos mediante onehost, usuarios con oneuser, etc.

Otra forma de monitorización son los logs, que se encuentran en /var/log/one/.

7. API Java

Terminaremos el tutorial con lo más interesante: hay API. OpenNebula proporciona una API mediante la que podemos gestionar las máquinas de forma muy sencilla con los conceptos que hemos visto a lo largo del tutorial.

OpenNebula funciona a través de llamadas XML-RPC, el API de java no es más que un wrapper que proporciona por debajo esa misma funcionalidad.

Veremos el código que expone OpenNebula de ejemplo en su documentación para hacernos una idea de lo podemos hacer.

// Lo primero que necesitamos hacer es crear un objeto Client, que nos permitirá conectarnos a
// OpenNebula.
Client oneClient;

try
{
    oneClient = new Client();

    // Ahora crearemos una máquina virtual a través de una plantilla, que es un simple String

    String vmTemplate =
          "NAME     = maquinaVirtual    CPU = 1    MEMORY = 1024\n"
        + "DISK     = [\n"
        + "\tsource   = \"/home/user/vmachines/Ubuntu14.04.qcow2\",\n"
        + "\ttarget   = \"hda\",\n"
        + "\treadonly = \"no\" ]\n"
        + "FEATURES = [ acpi=\"no\" ]";

    // Intentamos asignar la máquina virtual
    OneResponse rc = VirtualMachine.allocate(oneClient, vmTemplate);

    if( rc.isError() )
    {
        System.err.println( "falló.");
        throw new Exception( rc.getErrorMessage() );
    }

    // El mensaje de respuesta es el ID que se le ha asignado a la nueva VM
    int newVMID = Integer.parseInt(rc.getMessage());
    System.out.println("ok, ID " + newVMID + ".");

    // Podemos crear una representación de la nueva máquina virtual,
    // para así poder acceder a sus datos posteriormente.
    VirtualMachine vm = new VirtualMachine(newVMID, oneClient);

    // Retenemos la máquina virtual para que el planificador de OpenNebula no
    // la intente desplegar en ningún nodo
    rc = vm.hold();

    if(rc.isError())
    {
        System.err.println("falló!");
        throw new Exception( rc.getErrorMessage() );
    }

    // Solicitamos a OpenNebula la información relativa a la VM
   rc = vm.info();

    if(rc.isError())
        throw new Exception( rc.getErrorMessage() );

    System.out.println(
            "Esta es la información que guarda OpenNebula relativa a la nueva VM:");
    System.out.println(rc.getMessage() + "\n");

    // La clase VirtualMachine nos proporciona métodos útiles para acceder
    // a esos datos, aunque hay que recordar cargar esos datos antes a través
    // del método info
    System.out.println("La nueva VM " +
            vm.getName() + " está en estado: " + vm.status());

    // Incluso podemos usar XPATH para adentrarnos aún más, navegando
    // entre  en las propiedades en XML de la VM.
    System.out.println("El path del disco es");
    System.out.println( "\t" + vm.xpath("template/disk/source") );

    // La API también proporciona métodos muy útiles y directos para el
// manejo de la VM, como un método para borrarla.
    rc = vm.finalizeVM();
    System.out.println("\nIntentando eliminar la VM " +
                        vm.getId() + "...");

}
catch (Exception e)
{
    System.err.println(e.getMessage());
}

8. ¿Qué se puede llegar a hacer?

Gracias a la API podemos implementar sin mucho esfuerzo, por ejemplo, una plataforma web que proporcione ordenadores bajo demanda accesibles a través del navegador por VNC.

(Capturas tomadas desde el navegador)

Panel de control de la aplicación web

Conexión VNC desde la aplicación web

9. Referencias

3 COMENTARIOS

  1. ¿has probado lanzar una instancia (texto o con entorno gráfico) y ver si funciona la distribución de teclado español? A mí no me funciona…

  2. Hola
    Podrías orientarme sobre una solución que permita administrar (crear vlan, poner un puerto en port mirroring, apagar un puerto, etc) un centro de datos con diferentes plataformas: cisco, juniper, mikrotik, huawei (switch/routers). Si esto es posible o debo ir hacia una marca con una solución propietaria.
    Respecto a la opennebula, ¿me resolvería la administración y monitoreo de las máquinas virtuales (vmware, proxmox)?
    Estamos en proceso de implementar un centro de datos y muchas dudas respecto de la administración y el monitoreo del mismo.
    Aguardo tus comentarios.
    Saludos cordiales.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad