Cloud e Grid computer: qual è la differenza?

Spesso i termini Grid Computer e Cloud Computer sono utilizzati per identificare la stessa cosa: in realtà stiamo parlando di cose simili ma tecnicamente diverse.
Come spiegato da Rich Wolski del progetto Eucalyptus, differenziamo innanzi tutto lo scopo delle due modalità di cluster: dato un numero X di server fisici, un Grid Computer contiene al suo interno un numero di istanze minore o uguale ad X (ad esempio se ho 100 server fisici, il numero di istanze sarà 10, 50, 100… ma non di più); al contrario, in un Cloud Computer, il numero di istanze sarà sempre maggiore rispetto ad X (tornando all’esempio di prima, se faccio girare sui miei 100 server 200, 500, 1000 istanze).
Facendo questa premessa risulta evidente anche la differenza in termini di ingegnerizzazione del sistema che sta alla base del cluster.
In un Grid Computer il controller si occuperà prevalentemente di gestire la schedulazione delle operazioni, parallelizzandole ove possibile: difatti, nel caso del Grid Computing avremo poche istanze che girano contemporaneamente, però queste normalmente saranno estremamente esose di risorse e, pertanto, potrebbero richedere l’utilizzo esclusivo dell’hardware del sistema costringendo le nuove istanze a rimanere in attesa.
In un Cloud Computer, al contrario, abbiamo un gran numero di piccole istanze che girano contemporaneamente all’interno del cloud in real time e quindi non è possibile concepire un meccanismo di schedulazione delle stesse. Facendo un esempio con il servizio Cloud più conosciuto (Amazon EC2), un utente ha di base la possibilità di istanziare 20 VM contemporanee all’interno del cloud che condividono le medesime risorse Hardware. Quindi un simile sistema necessita di meccanismi di sincronizzazione e condivisione delle risorse diversi (e ovviamente più sofisticati) rispetto a quelli necessari per realizzare un Grid Computer.

Portando questa differenza astratta nella pratica, ci si accorge subito di quali rischi si possono incontrare quando si offre il servizio di cloud computing: gli strumenti attualmente disponibili che ci permettono di creare facilmente ed in maniera economica un sistema di cloud computing partendo da una manciata di server, rendono le cose talmente semplici che spesso si perde il controllo di ciò che è il reale utilizzo della propria infrastruttura. E’ facile, purtroppo, lasciarsi “prendere la mano” e istanziare un elevato numero di VM che, in caso di intenso utilizzo, arrivano a saturare l’infrastruttura Cloud; è necessario quindi mantenere un controllo sistemistico dello stato dell’infrastruttura, coadiuvandosi magari con l’utilizzo di sistemi appositamente concepiti quali Nagios e Ganglia, in modo da essere proattivi e agire con l’aggiunta di nuove risorse hardware prima che il sistema arrivi a saturazione.

Configuriamo la rete di una istanza su OpenNebula

Per chi è abituato all’utilizzo di sistemi di virtualizzazione classica, si può trovare spiazzato quando affronta per la prima volta il setup di una istanza in un cloud.
Difatti, lavorando direttamente sull’hypervisor, è pratica comune utilizzare un disco virtuale per ogni macchina virtuale contenente tutte le configurazioni specifiche di quella macchina.
Usando sistemi di cloud la cosa non può essere così: difatti chi acquista una istanza in un cloud pretende un setup quasi immediato, cosa che non permetterebbe ai sistemisti di creare una installazione ad-hoc per tale macchina, pertanto si è costretti ad operare in maniera diversa: in un sistema cloud vengono creati uno o più dischi master per le VM (ad esempio un disco con l’istallazione di base di una distribuzione) che vengono “duplicati” alla creazione dell’istanza della VM.
Nella maggior parte dei casi, inoltre, si tende ad utilizzare filesystem evoluti che permettono di creare snapshot dell’immagine master senza dover duplicare fisicamente l’immagine, cosa che rende il processo di provisioning ancora più rapido e migliora l’utilizzo dello spazio all’interno dello storage.
Da una simile premessa, risulta evidente che l’immagine master non può contenere una configurazione specifica per ciascuna delle istanze che vengono create, bensì è necessario che l’immagine all’avvio si “autoconfiguri” in modo da settare automaticamente quelle opzioni univoche che sono necessarie per il corretto funzionamento.
L’esempio più evidente è il settaggio dell’indirizzo IP: non è corretto settare un unico indirizzo IP all’interno della immagine master, bensì è necessario configurare l’immagine master in modo che setti automaticamente un IP univoco all’avvio.
Tale operazione specifica potrebbe essere compiuta attraverso un server DHCP installato all’interno del bridge della rete con le VM; OpenNebula ha però un metodo interno per gestire tutti questi parametri.

Il metodo che andremo a descrivere ora permette di configurare automaticamente l’indirizzo IP della scheda di rete della VM in base a quanto settato nel file di configurazione della VM. L’indirizzo IP verrà estratto in base al MAC Address assegnato alla scheda di rete: questa associazione può essere presente sia all’interno della configurazione del network virtuale associato all’intanza (onevnet per intenderci) sia usando una configurazione statica nella configurazione della VM.
Per eseguire questo setup automatico, è necessario copiare all’interno della directory /etc/init.d dell’istanza alla VM lo script per la propria distribuzione scaricabile da qui.
Quindi, utilizzando il comando ln -s, o qualsiasi altro comando proprio della distribuzione, far partire il comando prima della configurazione della rete: all’avvio dell’istanza, lo script estrarrà l’indirizzo IP assegnato alla VM e creerà il file di configurazione per il setup statico della rete, pronto per essere utilizzato successivamente dallo script di configurazione.

Un nodo di calcolo Xen 3 per OpenNebula con MooseFS

In questo articolo descriverò la procedura necessaria per creare un nodo di calcolo Xen con CentOS 5.5 compatibile con OpenNebula e MooseFS.

In fase di installazione di CentOS 5.5, scegliamo di installare i tools per la virtualizzazione: così facendo verrà automaticamente installato XEN 3.1.2 e il kernel 2.6.18 con le estensioni per Xen.

A questo punto installiamo il pacchetto necessario per montare il filesystem MooseFS. In CentOS è piuttosto semplice in quanto è già presente nel repository RPMforge:

wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
rpm -ivh rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
yum install mfs-client ruby
mkdir -p /srv/vms

Per montare il filesystem ho scelto di creare il mountpoint in /etc/fstab con l’opzione noauto e di montarlo all’avvio tramite rc.local in modo di essere certo che il montaggio avvenga al termine del caricamento degli altri servizi.
Modificiamo il file /etc/fstab aggiungerndo:

mfsmount                /srv/vms                fuse    mfsmaster=172.16.0.200,mfsport=9421,noauto  0 0

Quindi modifichiamo il file /etc/rc.local aggiungendo:

mount /srv/vms

Ora creiamo l’utente per OpenNebula:

groupadd --gid 1002 cloud
useradd --uid 1002 -g cloud -d /srv/vms/one -s /bin/bash oneadmin

Ora bisogna editare il file /etc/sudoers aggiungendo:

%cloud    ALL=(ALL) NOPASSWD: /usr/sbin/xm *
%cloud    ALL=(ALL) NOPASSWD: /usr/sbin/xentop *

inoltre, sempre in questo file, bisogna commentare la riga:

#Defaults    requiretty

La configurazione di XEN deve essere modificata aggiornando il file /etc/xen/xend-config.sxp:

(xend-relocation-server yes)
(xend-relocation-port 8002)
(xend-relocation-address '')
(xend-relocation-hosts-allow '')

Infine, sul cloud controller, aggingiamo il nuovo server al pool:

onehost create compute-01 im_xen vmm_xen tm_moosefs

Creiamo un Cloud Controller OpenNebula con MooseFS

Recentemente Libersoft ha rilasciato un plugin nell’Ecosystem di OpenNebula per integrare are uno storage MooseFS: attraverso questo plugin sono sfruttate le potenzialità di snapshot di MooseFS per il deploy delle immagini, cosa che rende il sistema estremamente veloce. Inoltre, seguendo questa installazione, installeremo anche OpenNebula all’interno dello sotrage MooseFS in modo da renderlo

In questo howto faremo riferimento ai precedenti articoli per creare un cloud controller/storage controller: in pratica il nostro server fungerà sia da controller per OpenNebula, sia da controller per MooseFS.

Nel mio caso ho installato il sistema usando come distribuzione Ubuntu Linux 10.2 LTS, partendo da una installazione di base.

Installazione del controller MooseFS
In Ubuntu non è presente un pacchetto per MooseFS, per cui è necessario compilarlo manualmente. Innanzi tutto, quindi, installiamo i tools per la compilazione:

apt-get install gcc build-essential

Quindi installiamo le librerie FUSE, prerequisito per la compilazione i tools per montare il filesystem moosefs:

apt-get install libfuse-dev fuse-utils libfuse2

A questo punto possiamo procedere con la compilazione di MooseFS come spiegato in questo articolo
Per maggiore sicurezza consiglio di abilitare il metadata server anche sul controller così come spiegato in questo articolo.
In questo articolo non tratteremo l’installazione dei chunk server (i nodi di storage di MooseFS), diamo per buono che ce ne siano e siano collegato al controller.
A questo punto creiamo la directory con il mountpoint di moosefs e montiamo il filesystem:

mkdir -p /srv/vms
mfsmount /srv/vms -H 127.0.0.1 -P 9421

Ricordiamoci di aggiungere i comandi per avviare i tre demoni di MooseFS e per montare lo storage all’interno di /etc/rc.local per far si che avvenga tutto in automatico il filesystem all’avvio; attenzione che è necessario eseguire queste operazioni prima di lanciare il demone di OpenNebula.

Installazione di OpenNebula
A questo punto installiamo OpenNebula, anche in questo caso compilando i sorgenti i modalità utente come spiegato in questo articolo; l’unica cosa a cui dobbiamo prestare attenzione è la directory di installazione che dovrà essere /srv/vms/one.
Le uniche differenze quindi stanno nella creazione dell’utente:

groupadd cloud
useradd -d /srv/vms/one  -s /bin/bash -g cloud -m oneadmin
mkdir /srv/vms/one /srv/vms/deply /srv/vms/images
chown -R oneadmin:cloud /srv/vms/

nel file .profile

.profile
export ONE_AUTH='/srv/vms/one/.one/one_auth'
export ONE_LOCATION='/srv/vms/one'
export ONE_XMLRPC='http://localhost:2633/RPC2'
export PATH=$PATH':/srv/vms/one/bin'

E nella compliazione di OpenNebula

./install.sh -d /srv/vms/one

Installazione del plugin per MooseFS
Ultima cosa da fare è installare il plugin di MooseFS come spiegato nella pagina dedicata.
Eseguiamo il download:

https://github.com/libersoft/opennebula-tm-moosefs/tarball/master

estraiamo la directory tm_moosefs in /srv/vms/one/etc/ e la directory tm_commands/moosefs in /srv/vms/one/lib/tm_commands
A questo punto modifichiamo il file di configurazione di OpenNebula:

<strong>/srv/vms/one/etc/oned.conf</strong>
HOST_MONITORING_INTERVAL = 60
VM_POLLING_INTERVAL      = 60
VM_DIR=/srv/vms/deploy
IMAGE_REPOSITORY_PATH = /srv/vms/images
SCRIPTS_REMOTE_DIR=/tmp/one
DB = [ backend = "mysql",
       server  = "localhost",
       port    = 0,
       user    = "oneadmin",
       passwd  = "oneadmin",
       db_name = "opennebula" ]
VNC_BASE_PORT = 5000
DEBUG_LEVEL=3
NETWORK_SIZE = 254
MAC_PREFIX   = "00:03"
DEFAULT_IMAGE_TYPE    = "OS"
DEFAULT_DEVICE_PREFIX = "hd"
IM_MAD = [
    name       = "im_xen",
    executable = "one_im_ssh",
    arguments  = "xen" ]
VM_MAD = [
    name       = "vmm_xen",
    executable = "one_vmm_ssh",
    arguments  = "xen",
    default    = "vmm_ssh/vmm_ssh_xen.conf",
    type       = "xen" ]
TM_MAD = [
       name       = "tm_moosefs",
       executable = "one_tm",
       arguments  = "tm_moosefs/tm_moosefs.conf" ]
HM_MAD = [
    executable = "one_hm" ]
VM_HOOK = [
    name      = "image",
    on        = "DONE",
    command   = "image.rb",
    arguments = "$VMID"
HOST_HOOK = [
    name      = "error",
    on        = "ERROR",
    command   = "host_error.rb",
    arguments = "$HID -r n",
    remote    = "no" ]
VM_HOOK = [
   name      = "on_failure_resubmit",
   on        = "FAILED",
   command   = "/usr/bin/env onevm resubmit",
   arguments = "$VMID" ]

Ricordiamoci che per aggiungere i nodi host, bisogna usare il tm_moosefs:

onehost create host01 im_xen vmm_xen tm_moosefs

Comandiamo le VM in OpenNebula

Come già detto nel precedente articolo, OpenNebula include il comando onevm per gestire le istanza delle VM.
Sinceramente la documentazione ufficiale e il manuale del comando mi hanno un po’ tratto in inganno per cui inquesto articolo cercherò di fare un po’ di chiarezza.
Ovviamente i comandi lanciabili attraverso onevm possono tranquillamente essere lanciati anche attraverso l’interfaccia web sunstone.

create
Abbiamo già visto l’utilizzo di “create”: con questo comando si crea l’istanza di una nuova VM partendo da un file template oppure dai dati inseriti attraverso l’interfaccia web sunstone. Una volta lanciato il comando, l’immagine viene posta in stato “pending”, in attesa quindi che lo schedulatore interno di opennebula si faccia carico di eseguire tutte le operazioni necessarie per avviare l’istanza su un hypervisor.
Dopo qualche istante, quindi, l’immagine entrerà nello stato “boot” per poi passare in stato “running”.

shutdown
Qui arriva il mio primo misunderstanding: siamo in un cloud e non in un semplice hypervisor, quindi le istanze delle VM non sono altro che dei servizi. Ciò vuol dire che con shutdown non chiedo semplicemente lo spegnimento della VM, ma ne chiedo, sostanzialmente, la disattivazione!
Quindi, lanciando lo shutdown, la VM viene spenta e cancellata senza alcuna possibilità di essere riavviata a meno di non creare una nuova istanza! Tenetelo ben presente…
La voce relativa all’istanza rimane comunque memorizzata per motivi storici fintantochè non viene cancellata.

delete
Serve per cancellare una VM. Nel caso in cui la VM sia accessa, prima viene operato uno shutdown.

suspend e resume
Il comando suspend mette in pausa la macchina virtuale. Lo stato viene salvato in un’area temporanea all’interno del nodo di clacolo locale, pronto per essere riutilizzato quando si lancia il resume.

stop e resume
Il comando stop è simile al suspend ma la macchina virtuale viene salvata in un’area temporanea all’interno del controlle per essere riutilizzata quando si lancia il resume e funziona solo se l’immagine ha il flag “SAVE” attivo. La differenza tra stop e suspend sta proprio nella posizione ove viene salvato lo stato della VM: averla nel nodo locale (suspend) permette di rendere il resume più rapido, però è necessario che tutte le risorse necessarie per far funzionare la VM siano disponibili. Al contrario, con lo stop, i dati della VM vengono spostati all’interno del controller, per cui in fase di resume viene scelto l’host più adatto per ospitare la VM.

migrate e livemigrate
I comandi migrate e livemigrate permettono di spostare l’immagine della VM da un server Hypervisor all’altro. Nel caso di migrate, viene fermata la VM, salvato lo stato sul cloud controller e poi viene eseguito il resume sul secondo host; nel caso di livemigrate, si sfruttano le potenzialità offerte dall’hypervisor per migrare la VM senza soluzione di continuità.

restart
Altro comando che crea imbarazzo: non serve per riavviare una istanza attiva, ma per far ripartire una istanza in stato sconosciuto. Se una VM si blocca (o se spegnamo una VM attraverso il comando “halt” di linux) è possibile farla riprtire attraverso il comando reboot.

Riassumendo, quindi:

  • una macchina virtuale può essere messa in pausa con stop o suspend, ma non può essere spenta “alla VMWare” tramite hypervisor, ma solo attraverso shell locale

  • se una macchina virtuale si blocca, oppure se il controller viene riavviato, lo stato della VM diventa “UNKNOWN”: in questo caso è possibile riavviare l’istanza della VM attraverso “restart”

  • il “reboot” da linux è ininfluente per lo stato della VM in OpenNebula

  • per riavviare una VM che appare in “RUNNING” ma che in realtà è bloccata (ad es. se riempite il disco della VM ;-)) l’unica possibilità è quella di cancellare l’istanza e ricrearla