giu 112011
 

Bene, acquistare un servizio PaaS “non LAMP” non vi convince e volete realizzarvi il vostro sistema per ospitare il nuovo Twitter. Intanto in bocca al lupo! Vediamo quali sono gli elementi di una piattaforma destinata ad ospitare servizi “di un certo livello”, in modo che possiate ragionare su quali scelte dovrete affrontare.

1) Infrastruttura IaaS
Il livello più basso è quello relativo al servizio IaaS, cioè l’hardware virtuale che ospiterà la nostra piattaforma sulla quale creeremo l’applicazione. E’ possibile scegliere di utilizzare un fornitore come RackSpace, Amazon, ecc. oppure crearsi il proprio cloud privato/ibrido con sistemi come OpenNebula, OpenStack o Eucalyptus. Riguardo la scalabilità, dal punto di vista hardware tutti i fornitori di servizi IaaS hanno infrastrutture hardware in grado di scalare all’occorrenza, mentre nel caso di cloud privati dobbiamo anche preoccuparci di avere una base hardware adeguata e di monitorarne l’utilizzo per aggiungere nuovo hardware all’occorrenza.
Riguardo a come scalerà il nostro sistema, come dicevo nel precedente articolo, innanzi tutto dobbiamo programmare un sistema che prevede la possibilità di essere scalabile: avere una infrastruttura che ci permette di “accendere una nuova macchina” all’occorrenza, ma che poi rimane ferma perchè noi non abbiamo previsto tecnicamente la sua accensione, serve a poco.
Fatta questa ovvia precisazione, tutti i fornitori di servizi cloud IaaS prevedono la possibilità di interfacciarsi attraverso delle REST API in modo da poter accendere e spegnere le macchine virtuali all’occorrenza. Quindi scegliamo attentamente il sistema di cloud che ci permetterà, in caso, i minori problemi in caso di future migrazioni: le API più diffuse sono quelle di Amazon, ma stanno prendendo piede velocemente le API OCCI.
Se non ci si vuole affidare alla programmazione usando le API, è possibile usare sistemi meno sofisticati per raggiungere il medesimo obiettivo: affidarsi ad un sistema di monitoraggio esterno come Nagios per programmare l’accensione e lo spegnimento di istanze a VM al raggiungimento di determinati livelli di utilizzo.

2) Sistema Operativo
Ovvio, no? Si parte dal basso e in una infrastruttura IaaS bisogna scegliere anche questo elemento :-)
E’ inutile spendere troppe parole su questo: resta bene inteso che è necessario scegliere Microsoft Windows Server nel caso in cui si voglia programmare in .net ;-)
Se invece pensate di utilizzare altri linguaggi, utilizzate la distribuzione Linux che preferite.

3) Linguaggio di programmazione
Python, Rails o Java/Scala, quello che preferite, sono tutti adatti; se volete seguire il trend del momento scegliete Rails.

4) Framework e componenti aggiuntivi
Dipende dal linguaggio, ovviamente: Ruby nel caso di Rails, Django nel caso di Python, Lift in caso di Java/Scala. Se avete scelto Ruby on Rails, ricordatevi di installare su tutti i server che eseguiranno l’applicazione le gemme necessarie.
E’ importante prevedere un sistema di code per eseguire le operazioni più lunghe in background; se utilizzate Ruby on Rails, ci sono delle gemme già pronte allo scopo: resque, BackgroundJob e delayed_job. Se volete un gestore di code non legato a ruby valutate RabbitMQ; se volete un servizio esterno “bello e pronto” e avete deciso di essere ospitati su Amazon, potete utilizzare SQS.

Infine, se avete scelto di ospitare la vostra App su un cloud privato OpenNebula e avete scelto di programmare con Ruby on Rails, non fatevi sfuggire la gemma per utilizzare le OCCI API per comandare il cloud OpenNebula!

5) Frontend Web
Si tratta del “web server” che risponderà alle richieste e le rigirerà ai server ospitanti l’applicazioni in load balancing: nginx è la soluzione più utilizzata, anche se in passato ho avuto ottime esperienze con HAProxy. Infine potete valutare Rack o Mongrel nel caso in cui abbiate scelto Rails.
Se scegliete di usare nginx, una buona idea è di far servire i contenuti statici (ad es. immagini, file .js, file .css ecc) direttamente dal frontend web e di rigirare ai server con l’applicativo solo le richieste dirette verso i contenuti dinamici. In passato ho scritto un articolo su come proxare le richieste di file PHP con nginx, l’articolo può servire come base epr il setup di questo componente.

6) Proxy e database per i dati
In una applicazione “on-the-cloud” è vietatissimo salvare i dati sul disco locale: questi devono obbligatoriamente risedere all’interno di un database. Se così non fosse, si avrebbe un “disallineamento” tra i server che fanno girare l’applicazione, mentre avendo i dati salvati all’interno di un database gli stessi sono condivisi tra tutte le istanze delle VM che faranno girare l’applicazione e pronti per essere disponibili anche alle eventuali VM spente.
Pertanto risulta evidente che i servizi di “disco virtuale” dei servizi IaaS, non servono per contenere i dati, ma per contenere l’applicazione. Unico elemento “borderline” potrebbe essere un servizio di storage a blob come Amazon S3 o OpenStack Swift per memorizzare elementi statici come immagini, file js, ecc.
Inutile dire che i database relazionali più comuni sono PostgreSQL e MySQL e che probabilmente saranno sufficienti alla Vostra applicazione in quanto comunque possono entrambi scalare in lettura, bilanciando quindi il carico di lavoro delle query. Se però abbiamo necessità di scalare in maniera molto più elastica, stanno emergendo nuove basi dati come MongoDB o NoSQL.
Ultima possibilità, Amazon mette a disposizione il servizio Simple DB ed RDS.
Ovviamente l’utilizzo intensivo di un database è estremamente dispendioso per cui è praticamente obbligatorio installare un sistema di cache locale: il sistema più utilizzato è senza dubbio memcached.

Ora che abbiamo descritto cosa vi serve per programmare… happy coding!

apr 302011
 

Oggi facciamo una digressione dagli aspetti tecnici verso temi che propriamente non lo sono: parliamo di gestione del rischio tramite suddivisione in più unità.

Mi spiego con un esempio venuto con l’esperienza: avete una ditta, dovete anticipare delle fatture per cui vi serve un castelletto di 100.000,00 Euro. Il periodo è difficile, le banche prima di esporsi ci pensano 1.000 volte (belle stronze, visto che il casino l’hanno causato soprattutto loro con i mutui subprime e derivati vari), per cui è difficile che un istituto vi conceda un simile fido.

Come fare?

Come si è sempre fatto: vado in 10 banche e chiedo a ciascuna un affidamento di portafoglio di 10.000,00 Euro. E’ più difficile viaggiare per 10 banche diverse, ma grazie a 10 piccoli passi al posto di uno gigante, alla fine ho più probabilità di ottenere quello che mi serve. E non solo: se una delle banche mi crea problemi ne ho altre nove su cui contare e non su una sola che mi lascerebbe a piedi.

Lo stesso discorso si può applicare con i clienti: meglio un cliente che mi fa fatturare 100.000,00 Euro all’anno oppure 100 clienti da 1.000,00 Euro? Con un cliente solo “mi smazzo di meno”, ma quando ci sono i primi problemi (e prima o poi i problemi, anche temporanei, arrivano) si vede la differenza.

Come diceva la pubblicità: du is megl che uan!

Questo si chiama suddivisione del rischio e deve essere applicato in tutti i contesti con criticità… e non fraintendetemi, non sto dicendo di trovarvi 100 amanti per stare tranquilli se litigate con il cogniuge.

E’ per dirvi invece che la stessa filosofia deve essere applicata nell’ambito informatico per minimizzare i rischi causati da un disservizio: troppo spesso in questo blog abbiamo trattato argomenti legati al cloud, all’alta affidabilità, a più server in load balancing… ma se per caso prendono fuoco gli UPS ed il datacenter resta al buio?

Lungi da me criticare Amazon e Aruba che hanno avuto questo tipo di problemi proprio di recente, anzi, complimenti (soprattutto al secondo) per la rapidità con la quale sono tornati operativi: come si dice, la bravura non sta a non cadere mai da cavallo, ma a rialzarsi in fretta dopo una brutta caduta.

Critico però tutti coloro che concentrano tutti i servizi presso un’unica struttura, senza valutare il rischio che questa cosa può generare e, quando accade, piangono…

E, paradossalmente, per affrontare questo problema ci viene in aiuto proprio il cloud: forse non tutti sanno che i cloud di possono federare. Bella parola, ma cosa vuol dire questo? Che pressochè tutti i sistemi di cloud utilizzano le API EC2 di Amazon e quindi, per definizione, esiste un layer di compatibilità che permette di unire assieme più cloud per bilanciare il carico di lavoro (e quindi anche il rischio in caso di guasto).

Nella pratica, per il proprio web server, meglio avere un’unica grande VM su Amazon o 10 piccole VM su 10 differenti cloud in load balancing?
Ok, il vostro ISP (io) è strafigo, vi assicura continuità… ma le recenti vicissitudini indicano che nessuno è immune da problemi, per cui magari costerà di più ma è meglio avere 10 web server in load balancing piuttosto di concentrare il rischio in un’unica struttura, per quanto importante possa essere.

Quindi, nel momento in cui state per acquistare un servizio “on-the-cloud” quantomeno informatevi se il Vostro provider permette la federazione con altri cloud. Diffidate da chi non la prevede, potreste pentirvene amaramente un domani.

mar 242011
 

In questo articolo installeremo OpenStack Glance, il componente di OpenStack in grado di interfacciarsi con il pool di server Nova per fornire loro le immagini delle macchine virtuali.

Glance può utilizzare diversi datastore per registrare le immagini delle macchine virtuali, tra cui OpenStack Swift; in questo articolo, però, per semplicità, utilizzeremo semplicemente l’hard disk locale. In successivi articoli spiegheremo come far collaborare al meglio assieme i componenti di OpenStack.

Per l’installazione, e consigliabile utilizzare come distribuzione Ubuntu Linux Server 10.10. E’ possibile utilizzare un server separato e ridondarlo, assumiamo però di utilizzare lo stesso cloud controller dell’esempio precedente (172.16.0.1). E’ semper importante eseguire i comandi come utente root

Download ed installazione di Glance

Iniziamo con aggiungere la repository apt ed installare il pacchetto

add-apt-repository ppa:glance-core/trunk
apt-get update
apt-get install glance

Quindi creiamo la directory con il file di configurazione:

cd /etc
mkdir glance
cd glance

Configurazione dei servizi

Creiamo quindi il file glance.conf con la configurazione:

/etc/glance/glance.conf
[DEFAULT]
# Show more verbose log output (sets INFO log level output)
verbose = True

# Show debugging output in logs (sets DEBUG log level output)
debug = False

[app:glance-api]
paste.app_factory = glance.server:app_factory

# Directory that the Filesystem backend store
# writes image data to
filesystem_store_datadir=/var/lib/glance/images/

# Which backend store should Glance use by default is not specified
# in a request to add a new image to Glance? Default: 'file'
# Available choices are 'file', 'swift', and 's3'
default_store = file

# Address to bind the API server
bind_host = 0.0.0.0

# Port the bind the API server to
bind_port = 9292

# Address to find the registry server
registry_host = 0.0.0.0

# Port the registry server is listening on
registry_port = 9191

[app:glance-registry]
paste.app_factory = glance.registry.server:app_factory

# Address to bind the registry server
bind_host = 0.0.0.0

# Port the bind the registry server to
bind_port = 9191
# SQLAlchemy connection string for the reference implementation
# registry server. Any valid SQLAlchemy connection string is fine.
# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine
sql_connection = sqlite:///glance.sqlite

# Period in seconds after which SQLAlchemy should reestablish its connection
# to the database.
#
# MySQL uses a default `wait_timeout` of 8 hours, after which it will drop
# idle connections. This can result in 'MySQL Gone Away' exceptions. If you
# notice this, you can lower this value to ensure that SQLAlchemy reconnects
# before MySQL can drop the connection.
sql_idle_timeout = 3600

Ora aggiungiamo ad /etc/rc.local il seguente comando per avviare glance automaticamente:

/usr/bin/glance-control all start

Altra modifica da effettuare riguarda il file /etc/nova/nova.conf: bisogna levare i riferimenti a nova-objectsore che non sarà più utilizzato e aggiungere quelli relativi a glance:

/etc/nova/nova.conf

Levare:
--s3_host=172.16.0.1

Aggiungere:
--glance_host=172.16.0.1
--glance_port=9292
--image_service=nova.image.glance.GlanceImageService

Per non sprecare risorse inutili, consiglio di levare il servizio glance-objectstore dall’avvio automatico. A questo punto abbiamo finito con le configurazioni e possiamo procedere a riavviare il nostro server.

Utilizzo di Glance

Per utilizzare il servizio glance, è necessario pubblicare le immagini sul server con il comando glance-upload:

wget http://smoser.brickies.net/ubuntu/ttylinux-uec/ttylinux-uec-amd64-12.1_2.6.35-22_1.tar.gz
tar zxvf ttylinux-uec-amd64-12.1_2.6.35-22_1.tar.gz
glance-upload --disk-format=ari --container-format=ari --type=ramdisk ttylinux-uec-amd64-12.1_2.6.35-22_1-initrd ramdisk
glance-upload --disk-format=aki --container-format=aki --type=kernel ttylinux-uec-amd64-12.1_2.6.35-22_1-vmlinuz kernel
glance-upload --disk-format=ami --container-format=ami --type=machine --ramdisk=1 --kernel=2 ttylinux-uec-amd64-12.1_2.6.35-22_1.img

Per controllare le istanze, d’ora in poi utilizzaremo direttamente il comando nova. Ad esempio:

nova flavor-list
nova image-list
nova boot pippo --flavor 2 --image 3

It’s all folks, but stay tuned!

mar 132011
 

Negli “HowTo” di OpenStack Swift è dimostrato come creare un ambiente di test utilizzando un singolo server con più partizioni, oppure (situazione consigliata) con più server deidicati allo storage. Troppo semplice: in questo HowTo spieghiamo come realizzare un sistema composto da 2 server con 4 dischi, definendo come zona il disco, quindi una soluzione ibrida tra le due proposte sul sito ufficiale.

Server st01:
IP esterno: 10.1.22.1/16 su eth1
IP interno: 172.16.0.1/24 su eth0/2 in bonding
HD SATA 750 GB: /dev/sda1 da 100 GB in ext4 per la partizione /; /dev/sda2 da 8 GB per lo swap e /dev/sda3 da 500 GB in XFS per la zona 1
HD USB da 500 GB: /dev/sdb1 da 500 GB in XFS per la zona 2

Server st02:
IP esterno: 10.1.22.2/16 su eth1
IP interno: 172.16.0.2/24 eth0/2 in bonding
HD SATA 750 GB: /dev/sda1 da 100 GB in ext4 per la partizione /; /dev/sda2 da 8 GB per lo swap e /dev/sda3 da 500 GB in XFS per la zona 3
HD USB da 500 GB: /dev/sdb1 da 500 GB in XFS per la zona 4

Attacchiamo i cavi e facciamo partire l’installazione base di Ubuntu LTS 10.04 nella versione 64bit. Eseguire una installazione di base, scegliendo solo, per comodità, di installare openssh server.

Configurazione della rete
Sui server abbiamo 3 schede di rete a Gbit, per cui voglio che le schede 0 e 3 siano collegate in bonding tra loro.
Installiamo innanzi tutto il pacchetto ifenslave su entrambi i server:

apt-get install ifenslave

ora creiamo il file /etc/modprobe.d/bonding.conf con le configurazioni del bond (i pacchetti vengono spediti in manera sequenziale tra le interfacce)

alias bond0 bonding
options bonding mode=0 miimon=100 downdelay=300 updelay=300

Quindi andiamo ad editare il file /etc/network/interface su st01

auto eth1
iface eth1 inet static
address 10.1.22.1
gateway 10.1.1.1
netmask 255.255.0.0

auto bond0
iface bond0 inet static
address 172.16.0.1
netmask 255.255.255.0
pre-up modprobe bonding
up ifenslave bond0 eth0 eth2
pre-down ifenslave bond0 -d eth0 eth2
post-down rmmod bonding

e su st02:

auto eth1
iface eth1 inet static
address 10.1.22.2
gateway 10.1.1.1
netmask 255.255.0.0
auto bond0
iface bond0 inet static
address 172.16.0.2
netmask 255.255.255.0
pre-up modprobe bonding
up ifenslave bond0 eth0 eth2
pre-down ifenslave bond0 -d eth0 eth2
post-down rmmod bonding
mar 122011
 

OpenStack è un progetto OpenSource sviluppato da una collaborazione di aziende tra cui Rackspace, NASA, Dell, Citrix, Cisco e Canonical (Ubuntu) attraverso cui è possibile generare un sistema Cloud simile a quello di Amazon utilizzando “Commodity Computer”, cioè dei computer standard senza particolari caratteristiche.

A chi può servire OpenStack Swift
Come già detto tutto non va bene per fare tutto, ogni cosa è concepita con uno scopo preciso e, se si usa per ambiti differenti da ciò per la quale è stata concepita, è facile rimanere insoddisfatti.

Openstack Swift è concepito per:
- archiviare file multimediali (foto, video, musica, ecc.)
- archiviare file di videosorveglianza
- archiviare intercettazioni telefoniche
- archiviare file di log
- archiviare backup
- salvare e caricare file di VM
- achiviare file piccoli (<50K)
- archiviare grosse quantità di file (miliardi)
- gestire storage esremamente grandi (Petabytes – milioni di Gigabyte) che possono crescere dinamicamente
- gestire storage geograficamente separati

Openstack non è concepito per:
- archiviare file di dimensioni > 5 GB: in questi casi è necessario splittare il file in più parti
- essere usato come un filesystem: per accedere ai file ci sono le REST API, le funzionalità POSIX di Linux non sono supportate
- situazioni in cui è necessario controllare le quantità di dati memorizzate dall’utente
- situazioni in cui serve la gerarchia delle directory
- situazioni in cui è necessario modificare il singolo byte all’interno di un file – on Swift sovrascrive il file ad ogni modifica e ne crea una nuova versione
- nessun supporto in append (vedi sopra)
- nessun uso di ACL e di File Locking
- situazioni in cui è necessaria la consistenza dei file – nel casi di contemporaneità, la versione memorizzata sarà quella ad essere modificata per ultima
- nessun supporto del criptaggio dei dati memorizzati ma solo del traffico
- incompatibile con i Web Browser
- nessun supporto di database per la ricerca di file
- situazioni in cui è necessario modificare spesso file di grosse dimensioni – i file sono immutabili, ad ogni modifica si crea una nuova versione
- tentare di usare Swift come FileSystem attraveso applicazioni come FUSE

Se queste limitazioni sono incompatibili con ciò che volete fare, probabilmente vi potrà andar meglio OCFS2, NFS, GFS2, ecc.

Concetti di base:
Swift mette a disposizione un ambiente di storage in cui un cliente (account) ha accesso ad un’area si storage dove può creare distinte partizioni (container) e caricare file (object) all’interno di queste. Ogni account può avere associate più username/password.

Tecnicamente il sistema si compone di 3 entità che possono sia risiedere sullo stesso server, sia essere separate: l’Auth server è dove risiedono i dati di autenticazione degli utenti; gli storage server sono i server dove fisicamente risiedono i dati e il il proxy server è il server che ha il compito di girare i dati di autenticazione all’auth server e, successivamente, interagire con gli storage server per rendere disponibili i dati.

Bisogna ora introdurre due altri concetti: le zone e le repliche. Qui la cosa è leggermente più difficile.
Le zone sono le entità fisiche che devono essere gestite e sono formate da una o più aree di disco fisiche; vediamole come l’entità minima che si può guastare. Con OpenStack si ha la massima libertà nel scegliere qual è l’elemento minimo del sistema e quindi la zona: può essere una partizione fisica all’interno di un disco, un disco, un server o un intero datacenter. Più piccola è l’entità zona, maggiore è l’efficenza del sistema, ma peggiore è la tolleranza ai guasti. Ad esempio, se abbiamo 2 server con 2 HD ciascuno e definiamo come zona il singolo disco (ciò che faremo nell’HowTo), tollereremo il guasto del singolo disco, ma non tollereremo il guasto di un intero server. Analogamente se definiamo come zona un server e abbiamo i server in due diversi datacenter, tollereremo il guasto di un Server, ma potremmo avere problemi nel caso in cui un intero datacenter muoia.

Le repliche sono invece il numero di copie che si vogliono avere per ogni dato memorizzato nel sistema: normalmente è 3; il numero di zone minimo presenti nel cluster è pari al numero di repliche, in questo caso abbiamo un sistema “mirror”. Il numero minimo consigliato di zone per un sistema in produzione è 5.
Da sottolineare che OpenStack non fa il mirror a livello di file, bensì suddivide il filesystem delle zone in partizioni più piccole (normalmente 10 GB/partizione) e si occupa di migrarle dinamicamente tra le zone per mantenere il sistema bilanciato.

Ultimo concetto da introdurre in OpenStack sono gli anelli (ring): un anello è un insieme di zone, quindi rappresenta la distribuzione dei nostri dati all’interno del cluster. Devono essere configurati tre anelli: uno per gli account, uno per i container e uno per gli object.

Come fare ad accedere ad OpenStack Swift
Openstack Swift include delle API per tutti i più importanti linguaggi di programmazione (php, .net, python ecc.). Inoltre esistono numerosi prodotti che già possono interagire con OpenStack Swift: a parte OpenStack Nova, mi sembra giusto citare CyberDuck che, oltre ad essere un ottimo client FTP, permette di collegarsi direttamente a storage di nuova concezione come Amazon S3 e, appunto, Openstack Swift.

Quando lo storage deve crescere
E’ semplice: si aggiunge un nuovo elemento “zona” aggiungendolo al proxy e ribilanciando il sistema e lo si annuncia agli altri storage copiando i file di configurazione. Operazione totalmente trasparente, il sistema continua ad essere operativo fintanto che l’update viene completato.