News Ticker

OpenStack, appunti di viaggio: parte seconda, configurazione ambiente operativo

openstack Dopo l'introduzione alle componenti del primo articolo di questa serie dedicata agli appunti di viaggio di OpenStack questa seconda parte metterà in pratica le cose, al fine di creare un ambiente operativo completo. L'obiettivo finale sarà quello di avere uno o più sistemi minimali creati, attivati e pronti ad erogare servizi dall'ambiente OpenStack.


Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 47

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/docroots/mmul/miamammausalinux.org/wp-content/plugins/latex/latex.php on line 49

Presupposti e requisiti del progetto

Essenziale per orientarsi in questa lunga sequela di comandi è capire quali sono i presupposti del progetto descritto. La volontà è quella di creare un ambiente con due macchine:

  1. Una macchina (virtuale o fisica) che sarà il nodo Controller OpenStack, ossia la casa dei servizi database (MySQL), del sistema di gestione code e messagistica (RabbitMQ), del sistema di autenticazione (Keystone), del sistema di gestione delle immagini (Glance) e del sistema di controllo delle istanze (Nova);
  2. Una macchina fisica che sarà il nodo Compute OpenStack, ossia che il servizio hypervisor per le istanze erogate (Nova compute);

Il sistema operativo installato sulle macchine descritte è Ubuntu 12.04 LTS e tutta la procedura descritta fa riferimento alla documentazione ufficiale di OpenStack per la versione Havana, estremamente completa e di facile accesso, disponibile a questo indirizzo: http://docs.openstack.org/havana/install-guide/install/apt/content/ch_preface.html.
Buona parte di quanto scritto in questo articolo fa riferimento proprio alla documentazione ufficiale in maniera paritetica.

Configurazione del nodo Controller OpenStack

Ciascuna delle due macchine ha due schede di rete che fanno riferimento ad una rete locale (172.16.78.0/24) da cui le macchine fisiche saranno direttamente accessibili e ad una rete di erogazione (10.0.0.0/24) destinata al funzionamento delle istanze OpenStack.
La configurazione di rete della macchina controller sarà quindi:

root@controller:~# cat /etc/network/interfaces
...
auto eth0
iface eth0 inet static
	address 172.16.78.51
	netmask 255.255.255.0
	gateway 172.16.78.254
	dns-nameservers 172.16.78.254
 
 
# External Network
auto eth1
iface eth1 inet static
	address 10.0.0.51
	netmask 255.255.255.0

Onde evitare confusione nell'utilizzo delle macchine sarà necessario fissare gli indirizzi all'interno del DNS o alternativamente nel file /etc/hosts:

root@controller:~# cat /etc/hosts
...
172.16.78.51    controller
172.16.78.52    compute1
...

Generazione delle password

Ciascun servizio OpenStack prevede un'autenticazione e pertanto un'associazione nome utente - password che va stabilita in origine. L'elenco di tutte le password da generare è riassunto nel seguente listato:

DBPASS
RABBIT_PASS
KEYSTONE_DBPASS
ADMIN_PASS
GLANCE_DBPASS
GLANCE_PASS
NOVA_DBPASS
NOVA_PASS
DASH_DBPASS
CINDER_DBPASS
CINDER_PASS
NEUTRON_DBPASS
NEUTRON_PASS
HEAT_DBPASS
HEAT_PASS
CEILOMETER_DBPASS
CEILOMETER_PASS

Essendo l'elenco piuttosto corposo, per non far riferimento unicamente alla propria fantasia è possibile automatizzare la generazione delle password:

rasca@anomalia [~]> for i in `cat passwords`; do echo "$i `openssl rand -hex 10`"; done
DBPASS c1438b1424a276b8b74b
RABBIT_PASS 5b6ff315009c077c3bd1
KEYSTONE_DBPASS 41aea835640ed9f9a02f
ADMIN_PASS cf97189ffe5f0c958e5f
GLANCE_DBPASS 008dc6ca0eda4f1e039e
GLANCE_PASS 4160bbe3f16e1e81128a
NOVA_DBPASS 7ea03fd7348331912cdc
NOVA_PASS 123a703800d1c48ff61d
DASH_DBPASS 4bcdbe1d1b42f4635bc2
CINDER_DBPASS 1a960a312149753d70aa
CINDER_PASS e4c81dff5eb24d8030b8
NEUTRON_DBPASS 388e85cefa26a9f7e4f5
NEUTRON_PASS 70467655af08fac2a0f4
HEAT_DBPASS 4a0a80b187e1fdcd60b9
HEAT_PASS 7bb93f239c4180a66d39
CEILOMETER_DBPASS 3421f4d1550e2614bad4
CEILOMETER_PASS 94a9c162c4b271b8c86e

Tenendo quindi presente questo elenco sarà possibile proseguire con la configurazione degli specifici componenti.

Installazione MySQL

Il primo elemento da configurare sarà il database MySQL, di importanza critica e necessario per la registrazione di tutte le informazioni di autenticazione e funzionamento di OpenStack:

root@controller:~# apt-get install python-mysqldb mysql-server

Rispetto alle impostazioni base sarà necessario porre il servizio in ascolto su ogni interfaccia, mettendo in sicurezza l'installazione:

root@controller:~# grep bind-address /etc/mysql/my.cnf
bind-address		= 0.0.0.0
root@controller:~# service mysql restart
mysql stop/waiting
mysql start/running, process 4217
root@controller:~# mysql_secure_installation

Il comando mysql_secure_installation oltre ad impostare i criteri di sicurezza il database permetterà di modificare la password per l'utente root di MySQL (che chiaramente andrà impostata su quanto generato sopra).

Configurazione repository OpenStack ed aggiornamenti

Terminata l'installazione del database sarà necessario aggiungere i repository specifici per la release di OpenStack scelta (Havana) all'interno del sistema controller:

root@controller:~# apt-get install python-software-properties
root@controller:~# add-apt-repository cloud-archive:havana
root@controller:~# apt-get update && apt-get dist-upgrade

Terminato l'aggiornamento del sistema si potrà procedere con la configurazione delle specifiche componenti.

Installazione messaging server

Il sistema di messaging come stabilito sarà RabbitMQ:

root@controller:~# apt-get install rabbitmq-server
root@controller:~# rabbitmqctl change_password guest 5b6ff315009c077c3bd1

Il secondo comando lanciato imposta la password dell'utente per l'accesso al sistema da parte di tutte le componenti (per le password si farà sempre riferimento alla generazione avvenuta sopra).

Installazione di Identity (Keystone)

Il primo componente di OpenStack ad essere installato sarà il sistema di identificazione, Keystone, che racchiuderà le informazioni di autenticazione ai servizi OpenStack:

root@controller:~# apt-get install keystone
root@controller:~# egrep "admin_token|connection =" /etc/keystone/keystone.conf
admin_token = cf97189ffe5f0c958e5f
#connection = sqlite:////var/lib/keystone/keystone.db
connection = mysql://keystone:41aea835640ed9f9a02f@controller/keystone

La configurazione del servizio all'interno del file /etc/keystone/keystone.conf specifica un utente ed un database che ancora non esistono all'interno di MySQL. Questi andranno quindi creati:

root@controller:~# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.35-0ubuntu0.12.04.2 (Ubuntu)
 
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> CREATE DATABASE keystone;
Query OK, 1 row affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '41aea835640ed9f9a02f';
Query OK, 0 rows affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '41aea835640ed9f9a02f';
Query OK, 0 rows affected (0.00 sec)
 
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

A creazione avvenuta si potrà procedere all'inizializzazione del database:

root@controller:~# keystone-manage db_sync

Ed all'avvio del servizio:

root@controller:~# service keystone restart
keystone stop/waiting
keystone start/running, process 3790

Definizione degli utenti

Le prime entità da creare all'interno del servizio Keystone sarà quella relative ai Tenants, ossia i profili dei gestori di OpenStack. Ne vengono creati inizialmente due, uno relativo all'amministratore e l'altro relativo ai servizi:

root@controller:~# export OS_SERVICE_TOKEN=cf97189ffe5f0c958e5f
root@controller:~# export OS_SERVICE_ENDPOINT=http://controller:35357/v2.0
root@controller:~# keystone tenant-create --name=admin --description="Admin Tenant"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |           Admin Tenant           |
|   enabled   |               True               |
|      id     | 2a039dd0fd424036a9657c971f6d13bf |
|     name    |              admin               |
+-------------+----------------------------------+
root@controller:~# keystone tenant-create --name=service --description="Service Tenant"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |          Service Tenant          |
|   enabled   |               True               |
|      id     | 0978fe4f8a164e2c97bdd4d5fb114096 |
|     name    |             service              |
+-------------+----------------------------------+

Seguirà poi la creazione dell'utente amministratore, completo di ruolo ed associazione al tenant base:

root@controller:~# keystone user-create --name=admin --pass=cf97189ffe5f0c958e5f --email=root@controller
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |         root@controller          |
| enabled  |               True               |
|    id    | 7387de194bf64179bd65fb7e88f1b3f8 |
|   name   |              admin               |
+----------+----------------------------------+
root@controller:~# keystone role-create --name=admin
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|    id    | 6ff78e25102a41e1a802347689fc90c8 |
|   name   |              admin               |
+----------+----------------------------------+
root@controller:~# keystone user-role-add --user=admin --tenant=admin --role=admin

A questo punto le entry sono state create e non rimarrà che definire le modalità di accesso al servizio.

Definizione degli accessi alle API

Per consentire ad un determinato servizio di accedere alle informazioni di autenticazione sarà necessario definire la modalità di questo accesso all'interno di Keystone:

root@controller:~# keystone service-create --name=keystone --type=identity --description="Keystone Identity Service"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |    Keystone Identity Service     |
|      id     | e4b0869bfafc4df38fb2f74cca5a9fb7 |
|     name    |             keystone             |
|     type    |             identity             |
+-------------+----------------------------------+

Il servizio creato fornisce un id con cui sarà possibile creare il così detto end point, ossia la destinazione delle connessioni riferite al servizio:

root@controller:~# keystone endpoint-create --service-id=e4b0869bfafc4df38fb2f74cca5a9fb7 --publicurl=http://controller:5000/v2.0 --internalurl=http://controller:5000/v2.0 --adminurl=http://controller:35357/v2.0
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
|   adminurl  |   http://controller:35357/v2.0   |
|      id     | 9e87d693a7ce40c0a70aef52318b8df4 |
| internalurl |   http://controller:5000/v2.0    |
|  publicurl  |   http://controller:5000/v2.0    |
|    region   |            regionOne             |
|  service_id | e4b0869bfafc4df38fb2f74cca5a9fb7 |
+-------------+----------------------------------+

In questo modo l'accesso sarà consentito verso il servizio esposto dalla controller, cioè http://controller:5000/v2.0.

E' possibile effettuare un test di funzionamento della connettività, definendo un file, denominato keystonerc, contenente le informazioni di autenticazione così come sono state definite finora, attivabile mediante il comando source:

root@controller:~# cat keystonerc
export OS_USERNAME=admin
export OS_PASSWORD=cf97189ffe5f0c958e5f
export OS_TENANT_NAME=admin
export OS_AUTH_URL=http://controller:35357/v2.0
root@controller:~# source keystonerc 
root@controller:~# keystone token-get

Il comando keystone token-get restituirà un corposo output relativo al token, contenente l'ID del tenant specificato (ossia admin).
Un'ulteriore verifica si potrà effettuare interrogando la lista degli utenti:

root@controller:~# keystone user-list
+----------------------------------+-------+---------+-----------------+
|                id                |  name | enabled |      email      |
+----------------------------------+-------+---------+-----------------+
| 7387de194bf64179bd65fb7e88f1b3f8 | admin |   True  | root@controller |
+----------------------------------+-------+---------+-----------------+

A fronte dell'esito positivo di questi comandi, la configurazione iniziale del servizio Keystone può dirsi quindi completa.

Configurazione Image Service (Glance)

Il servizio Glance si occupa di rendere disponibili immagini, di fatto installazioni vergini preconfezionate, a cui vengono impostate dinamicamente le configurazione di rete gestite dal servizio Nova (che verrà configurato più avanti).
Per raggiungere l'obiettivo del progetto, verrà usato il backend file per la registrazione delle immagini, ossia il default, che prevede una directory locale per la registrazione delle immagini, in sostanza il path /var/lib/glance/images/

root@controller:~# apt-get install glance python-glanceclient

Le due componenti di Glance sono glance-api e glance-registry, entrambe con un file di configurazione associato. Questi andranno variati entrambi come segue:

root@controller:~# grep "sql_connection =" /etc/glance/glance-*.conf
/etc/glance/glance-api.conf:sql_connection = mysql://glance:008dc6ca0eda4f1e039e@controller/glance
/etc/glance/glance-registry.conf:sql_connection = mysql://glance:008dc6ca0eda4f1e039e@controller/glance

Al fine di predisporre l'accesso al database MySQL. Anche in questo caso andranno creati database e permessi:

root@controller:~# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 5.5.35-0ubuntu0.12.04.2 (Ubuntu)
 
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> CREATE DATABASE glance;
Query OK, 1 row affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY '008dc6ca0eda4f1e039e';
Query OK, 0 rows affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY '008dc6ca0eda4f1e039e';
Query OK, 0 rows affected (0.00 sec)

Ed anche per Glance andrà prevista la creazione del profilo in Keystone, quindi utente e ruolo:

root@controller:~# keystone user-create --name=glance --pass=4160bbe3f16e1e81128a --email=root@controller
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |         root@controller          |
| enabled  |               True               |
|    id    | ae6567bb7ed44b8cba978ee8e12852ae |
|   name   |              glance              |
+----------+----------------------------------+
root@controller:~# keystone user-role-add --user=glance --tenant=service --role=admin

All'interno dei file di configurazione menzionati poco fa, /etc/glance/glance-api.conf e /etc/glance/glance-registry.conf, precisamente nella sezione "[keystone_authtoken]", si trovano le sezioni da configurare per l'accesso a Keystone, che andranno configurate di conseguenza:

[keystone_authtoken]
auth_uri = http://controller:5000
auth_host = controller
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = glance
admin_password = 4160bbe3f16e1e81128a
 
[paste_deploy]
flavor=keystone

Gli stessi riferimenti per Keystone andranno aggiunti nella sezione [filter:authtoken] dei file /etc/glance/glance-api-paste.ini e /etc/glance/glance-registry-paste.ini:

[filter:authtoken]
paste.filter_factory=keystoneclient.middleware.auth_token:filter_factory
auth_host=controller
admin_user=glance
admin_tenant_name=service
admin_password=4160bbe3f16e1e81128a

E così come fatto in precedenza dovrà essere creato il servizio Glance in Keystone:

root@controller:~# keystone service-create --name=glance --type=image --description="Glance Image Service"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |       Glance Image Service       |
|      id     | 77e64e6608ba4282a50edf519c987020 |
|     name    |              glance              |
|     type    |              image               |
+-------------+----------------------------------+

Anche in questo caso, presa nota dell'id fornito nel precedente comando, si andrà a creare l'endpoint:

root@controller:~# keystone endpoint-create --service-id=77e64e6608ba4282a50edf519c987020 --publicurl=http://controller:9292 --internalurl=http://controller:9292 --adminurl=http://controller:9292
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
|   adminurl  |      http://controller:9292      |
|      id     | 643d0dc45e5d480b829a23e4ee24cb67 |
| internalurl |      http://controller:9292      |
|  publicurl  |      http://controller:9292      |
|    region   |            regionOne             |
|  service_id | 77e64e6608ba4282a50edf519c987020 |
+-------------+----------------------------------+

Infine i servizi Glance potranno quindi essere avviati:

root@controller:~# service glance-registry restart
glance-registry stop/waiting
glance-registry start/running, process 4800
root@controller:~# service glance-api restart
glance-api stop/waiting
glance-api start/running, process 4810

Caricamento delle immagini su Glance

Senza immagini caricate il servizio Glance risulta sostanzialmente inutile. Ma quali sono le immagini compatibili con OpenStack? In realtà OpenStack non è molto schizzinoso in termini di immagini pertanto una qualsiasi immagine Linux nel formato aspettato (http://docs.openstack.org/developer/glance/formats.html) dovrebbe risultare compatibile.
Ma va tenuto presente che all'interno dell'architettura OpenStack le performance di erogazione delle immagini saranno direttamente proporzionali alla leggerezza delle stesse (oltre che all'hardware, ma molte volte questo è indipendente dal sysadmin). Un'immagine di qualche giga sarà sicuramente completa, ma certamente poco performante in fase di deploy.
Pertanto l'ideale è personalizzare le immagini in modo che queste siano leggere e pensate specificamente ad uno scopo, piuttosto che general purpose. Esiste un'immagine Linux particolarmente adatta allo scopo dimostrativo di questo articolo, CirrOS:

root@controller:~# mkdir images
root@controller:~# cd images/
root@controller:~/images# wget http://cdn.download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-disk.img

Scaricata l'immagina localmente, questa potrà essere caricata in Glance:

root@controller:~/images# glance image-create --name=cirros --disk-format=qcow2 --container-format=bare --is-public=true < cirros-0.3.1-x86_64-disk.img
+------------------+--------------------------------------+
| Property         | Value                                |
+------------------+--------------------------------------+
| checksum         | d972013792949d0d3ba628fbe8685bce     |
| container_format | bare                                 |
| created_at       | 2014-02-13T12:03:51                  |
| deleted          | False                                |
| deleted_at       | None                                 |
| disk_format      | qcow2                                |
| id               | c5b27268-f703-4180-bf19-b24b0d662156 |
| is_public        | True                                 |
| min_disk         | 0                                    |
| min_ram          | 0                                    |
| name             | cirros                               |
| owner            | 2a039dd0fd424036a9657c971f6d13bf     |
| protected        | False                                |
| size             | 13147648                             |
| status           | active                               |
| updated_at       | 2014-02-13T12:03:51                  |
+------------------+--------------------------------------+

Per verificare il corretto caricamento fisico dell'immagine basterà controllarne l'esistenza nella cartella di destinazione di default /var/lib/glance/images/:

root@controller:~/images# ls -la /var/lib/glance/images/
totale 12848
drwxr-xr-x 2 glance glance     4096 feb 13 13:03 .
drwxr-xr-x 4 glance glance     4096 feb 13 12:39 ..
-rw-r----- 1 glance glance 13147648 feb 13 13:03 c5b27268-f703-4180-bf19-b24b0d662156

Oltre all'effettiva visibilità all'interno di Glance:

root@controller:~/images# glance image-list
+--------------------------------------+--------+-------------+------------------+----------+--------+
| ID                                   | Name   | Disk Format | Container Format | Size     | Status |
+--------------------------------------+--------+-------------+------------------+----------+--------+
| c5b27268-f703-4180-bf19-b24b0d662156 | cirros | qcow2       | bare             | 13147648 | active |
+--------------------------------------+--------+-------------+------------------+----------+--------+

In questo modo anche il componente Glance è completo.

Configurazione del Compute service (Nova)

Il servizio Nova riveste un'importanza essenziale nella gestione dell'operatività di OpenStack. Mediante Nova sarà possibile distribuire ed effettuare il deploy delle istanze sui nodi Compute (la cui configurazione sarà trattata poco più avanti).
Per prima cosa sarà necessario installare i pacchetti:

root@controller:~# apt-get install nova-novncproxy novnc nova-api nova-ajax-console-proxy nova-cert nova-conductor nova-consoleauth nova-doc nova-scheduler python-novaclient

E modificare il file di configurazione /etc/nova/nova.conf inserendo le informazioni definite in fase di creazione delle password:

...
rpc_backend = nova.rpc.impl_kombu
rabbit_host = controller
rabbit_password = 5b6ff315009c077c3bd1
 
[database]
connection = mysql://nova:7ea03fd7348331912cdc@controller/nova
 
[keystone_authtoken]
auth_host = controller
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = nova
admin_password = 123a703800d1c48ff61d

Anche per Nova andrà creato il database di riferimento con i relativi permessi:

root@controller:~/images# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 57
Server version: 5.5.35-0ubuntu0.12.04.2 (Ubuntu)
 
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> CREATE DATABASE nova;
Query OK, 1 row affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY '7ea03fd7348331912cdc';
Query OK, 0 rows affected (0.00 sec)
 
mysql> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY '7ea03fd7348331912cdc';
Query OK, 0 rows affected (0.00 sec)
 
mysql> 
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Il database Nova andrà inizializzato:

root@controller:~# nova-manage db sync
2014-02-13 13:36:37.330 7049 INFO migrate.versioning.api [-] 132 -> 133... 
...
...
2014-02-13 13:39:16.004 7049 INFO migrate.versioning.api [-] 215 -> 216... 
2014-02-13 13:39:16.104 7049 INFO migrate.versioning.api [-] done

E successivamente, così come fatto per i due servizi precedenti, anche per Nova andranno creati utente e ruolo:

root@controller:~/images# keystone user-create --name=nova --pass=123a703800d1c48ff61d --email=root@controller
+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |         root@controller          |
| enabled  |               True               |
|    id    | 16f8677a4fc543ed80936a87a66c8205 |
|   name   |               nova               |
+----------+----------------------------------+
root@controller:~/images# keystone user-role-add --user=nova --tenant=service --role=admin

infine all'interno /etc/nova/api-paste.ini verranno definite le modalità di accesso al servizio:

[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
auth_host = controller
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = nova
admin_password = 123a703800d1c48ff61d

E per concludere verrà registrato come di consueto il servizio in Keystone:

root@controller:~/images# keystone service-create --name=nova --type=compute --description="Nova Compute service"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |       Nova Compute service       |
|      id     | 32c01d242ee9416a825dedb66c517dd1 |
|     name    |               nova               |
|     type    |             compute              |
+-------------+----------------------------------+

Con associata la creazione dell'endpoint basato sull'id ricavato:

root@controller:~/images# keystone endpoint-create --service-id=32c01d242ee9416a825dedb66c517dd1 --publicurl=http://controller:8774/v2/%s --internalurl=http://controller:8774/v2/%s --adminurl=http://controller:8774/v2/%s
+-------------+-----------------------------------------+
|   Property  |                  Value                  |
+-------------+-----------------------------------------+
|   adminurl  | http://controller:8774/v2/%(tenant_id)s |
|      id     |     2cba958a098c49c5a72a51e1ba39ad1a    |
| internalurl | http://controller:8774/v2/%(tenant_id)s |
|  publicurl  | http://controller:8774/v2/%(tenant_id)s |
|    region   |                regionOne                |
|  service_id |     32c01d242ee9416a825dedb66c517dd1    |
+-------------+-----------------------------------------+

E' quindi giunto il momento di avviare i numerosi servizi di Nova:

root@controller:~/images# for service in nova-api nova-cert nova-consoleauth nova-scheduler nova-conductor nova-novncproxy; do service $service restart; done
nova-api stop/waiting
nova-api start/running, process 9882
nova-cert stop/waiting
nova-cert start/running, process 9892
nova-consoleauth stop/waiting
nova-consoleauth start/running, process 9902
nova-scheduler stop/waiting
nova-scheduler start/running, process 9912
nova-conductor stop/waiting
nova-conductor start/running, process 9930
nova-novncproxy stop/waiting
nova-novncproxy start/running, process 9940

A verifica del funzionamento di Nova sarà possibile interrogare la sezione immagini, all'interno della quale dovrebbe apparire quanto inserito in Glance:

root@controller:~/images# nova image-list
+--------------------------------------+--------+--------+--------+
| ID                                   | Name   | Status | Server |
+--------------------------------------+--------+--------+--------+
| c5b27268-f703-4180-bf19-b24b0d662156 | cirros | ACTIVE |        |
+--------------------------------------+--------+--------+--------+

Prima di procedere alla configurazione del nodo Compute rimane un'ultima cosa: predisporre la rete di erogazione delle istanze, in questo modo:

root@controller:~# nova network-create vmnet --fixed-range-v4=10.0.0.0/24 --bridge-interface=br100 --multi-host=T

Le istanze funzioneranno quindi nel segmento 10.0.0.0/24 utilizzando l'interfaccia br100. La configurazione del nodo Controller è per il momento completa.

Configurazione del nodo Compute (il nodo che eroga le istanze)

I nodi Compute dovrebbero essere pensati come componenti prive di configurazioni complesse, facilmente rimpiazzabili, in una parola: cannoni da fuoco, i cui proiettili saranno le istanze prodotte e guidate dal nodo Controller.
La rete del nodo Compute conterrà gli stessi elementi della Controller:

root@compute1:~# cat /etc/network/interfaces
...
auto eth0
iface eth0 inet static
	address 172.16.78.52
	netmask 255.255.255.0
	gateway 172.16.78.254
	dns-nameservers 172.16.78.254
 
# External Network
auto eth1
iface eth1 inet static
	address 10.0.0.52
	netmask 255.255.255.0

Anche per il nodo compute andranno aggiunti i repository:

root@compute1:~# apt-get install python-mysqldb
root@compute1:~# apt-get install python-software-properties
root@compute1:~# add-apt-repository cloud-archive:havana
root@compute1:~# apt-get update && apt-get dist-upgrade

E installati i soli pacchetti interessati alla comunicazione con OpenStack:

root@compute1:~# apt-get install nova-compute-kvm python-guestfsz nova-network

(Verrà posta una domanda inerente ad una componente supermin, una componente necessaria a generare un ambiente locale operativo per l'accesso alle immagini sul filesystem, la risposta dovrà essere sì).

La configurazione del servizio Nova sarà simile a quanto riportato poco fa per il nodo Controller e passerà anch'essa dal file /etc/nova/nova.conf:

auth_strategy=keystone
 
rpc_backend = nova.rpc.impl_kombu
rabbit_host = controller
rabbit_password = 5b6ff315009c077c3bd1
 
my_ip=172.16.78.51
vnc_enabled=True
vncserver_listen=0.0.0.0
vncserver_proxyclient_address=172.16.78.51
novncproxy_base_url=http://controller:6080/vnc_auto.html
 
glance_host=controller
 
# Network
network_manager=nova.network.manager.FlatDHCPManager
firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver
network_size=254
allow_same_net_traffic=False
multi_host=True
send_arp_for_ha=True
share_dhcp_address=True
force_dhcp_release=True
flat_network_bridge=br100
flat_interface=eth1
public_interface=eth1
 
[database]
# The SQLAlchemy connection string used to connect to the database
connection = mysql://nova:7ea03fd7348331912cdc@controller/nova

Da notare la sezione "# Network" il cui scopo è quello di gestire il bridge br100 per l'accesso delle istanze alla rete mediante l'interfaccia reale eth1.
Anche per il nodo Compute sarà necessario configurare la sezione di autenticazione al servizio nova presente sulla macchina Controller, mediante il file /etc/nova/api-paste.ini:

[filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
auth_host = controller
auth_port = 35357
auth_protocol = http
admin_tenant_name = service
admin_user = nova
admin_password = 123a703800d1c48ff61d

Infine i servizi Nova potranno essere avviati:

root@compute1:~# service nova-compute restart
nova-compute stop/waiting
nova-compute start/running, process 19187
root@compute1:~# service nova-network restart
nova-network stop/waiting
nova-network start/running, process 19949

Verificando l'esistenza del citato bridge:

root@compute1:~# ip addr show dev br100
5: br100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 54:04:a6:81:95:a6 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 brd 10.0.0.255 scope global br100
       valid_lft forever preferred_lft forever
    inet 10.0.0.52/24 brd 10.0.0.255 scope global secondary br100
       valid_lft forever preferred_lft forever
    inet6 fe80::70c2:e9ff:fe38:9eaa/64 scope link 
       valid_lft forever preferred_lft forever

Tutto è quindi completo. Non rimane che lanciare la prima istanza.

Primo lancio di un'istanza

Prima di effettuare il deploy vero e proprio dell'istanza è necessario capire come si potrà accedere a questa. Andranno cioè definite delle regole di accesso che consentiranno di utilizzare specifici protocolli e servizi. Nel caso in oggetto andranno create le regole per l'accesso ssh e ping (icmp):

root@controller:~/.ssh# nova secgroup-add-rule default tcp 22 22 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range  | Source Group |
+-------------+-----------+---------+-----------+--------------+
| tcp         | 22        | 22      | 0.0.0.0/0 |              |
+-------------+-----------+---------+-----------+--------------+
root@controller:~/.ssh# nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range  | Source Group |
+-------------+-----------+---------+-----------+--------------+
| icmp        | -1        | -1      | 0.0.0.0/0 |              |
+-------------+-----------+---------+-----------+--------------+

A questo punto si potrà procedere con il lancio effettivo dell'istanza. Per farlo è necessario capire il concetto di Flavor. Questo sapore rappresenta la caratteristica base dell'immagine che si va a creare. Esistono dei flavor predefiniti, visibili mediante il seguente comando:

root@controller:~# nova flavor-list
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+

E' facile quindi capirne il senso: quanto disco, quante cpu e via dicendo. Partendo quindi dalle immagini disponibili:

root@controller:~# nova image-list
+--------------------------------------+--------+--------+--------+
| ID                                   | Name   | Status | Server |
+--------------------------------------+--------+--------+--------+
| c5b27268-f703-4180-bf19-b24b0d662156 | cirros | ACTIVE |        |
+--------------------------------------+--------+--------+--------+

Sarà possibile strutturare il comando di creazione dell'istanza, utilizzando il comando nova boot:

root@controller:~# nova boot --flavor 1 --key_name rasca --image c5b27268-f703-4180-bf19-b24b0d662156 --security_group default cirrOS
+--------------------------------------+--------------------------------------+
| Property                             | Value                                |
+--------------------------------------+--------------------------------------+
| OS-EXT-STS:task_state                | scheduling                           |
| image                                | cirros                               |
| OS-EXT-STS:vm_state                  | building                             |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000001                    |
| OS-SRV-USG:launched_at               | None                                 |
| flavor                               | m1.tiny                              |
| id                                   | b884e7fa-31ee-498b-aa14-f797b0bd796c |
| security_groups                      | [{u'name': u'default'}]              |
| user_id                              | 7387de194bf64179bd65fb7e88f1b3f8     |
| OS-DCF:diskConfig                    | MANUAL                               |
| accessIPv4                           |                                      |
| accessIPv6                           |                                      |
| progress                             | 0                                    |
| OS-EXT-STS:power_state               | 0                                    |
| OS-EXT-AZ:availability_zone          | nova                                 |
| config_drive                         |                                      |
| status                               | BUILD                                |
| updated                              | 2014-02-13T14:55:26Z                 |
| hostId                               |                                      |
| OS-EXT-SRV-ATTR:host                 | None                                 |
| OS-SRV-USG:terminated_at             | None                                 |
| key_name                             | rasca                                |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | None                                 |
| name                                 | cirrOS                               |
| adminPass                            | H3xsNsUXbHw5                         |
| tenant_id                            | 2a039dd0fd424036a9657c971f6d13bf     |
| created                              | 2014-02-13T14:55:25Z                 |
| os-extended-volumes:volumes_attached | []                                   |
| metadata                             | {}                                   |
+--------------------------------------+--------------------------------------+

Seguendo poi le fasi di creazione dell'istanza, si noterà come inizialmente l'istanza sarà nel task "spawning" (con uno stato "NOSTATE"), ossia la fase di copia dell'immagine sull'host di destinazione, mentre è già definito quello che sarà l'indirizzo ip dell'istanza: 10.0.0.2:

root@controller:~# nova list
+--------------------------------------+--------+--------+------------+-------------+----------------+
| ID                                   | Name   | Status | Task State | Power State | Networks       |
+--------------------------------------+--------+--------+------------+-------------+----------------+
| 53838f2b-d92d-4401-9ff9-92b9a59afe5e | cirrOS | BUILD  | spawning   | NOSTATE     | vmnet=10.0.0.2 |
+--------------------------------------+--------+--------+------------+-------------+----------------+

L'operazione sarà completa quando l'istanza risulterà in uno stato "Running":

root@controller:~# nova list
+--------------------------------------+--------+--------+------------+-------------+----------------+
| ID                                   | Name   | Status | Task State | Power State | Networks       |
+--------------------------------------+--------+--------+------------+-------------+----------------+
| 53838f2b-d92d-4401-9ff9-92b9a59afe5e | cirrOS | ACTIVE | None       | Running     | vmnet=10.0.0.2 |
+--------------------------------------+--------+--------+------------+-------------+----------------+

Se tutto avrà funzionato a dovere, l'istanza sarà disponibile all'indirizzo indicato, mediante ssh:

root@controller:~# ssh cirros@10.0.0.2
The authenticity of host '10.0.0.2 (10.0.0.2)' can't be established.
RSA key fingerprint is f7:dd:3d:a2:6f:5d:63:2c:70:a4:fd:55:f8:87:ab:c5.
Are you sure you want to continue connecting (yes/no)?

Lo username di default è cirros mentre la password è cubswin:)

Conclusioni

Sebbene ad un'analisi superficiale questa puntata della serie appaia come una lunghissima sequela di comandi, andando a fondo si scopre come ciascuna delle configurazioni descritte aiuti a comprendere le dinamiche che stanno alla base delle componenti di OpenStack.
La complessità è evidente, così come però sono evidenti le enormi potenzialità di questo fantastico progetto.
Nella prossima puntata verrà introdotta la dashboard, analizzati gli errori comunemente riscontrati in fase di configurazione di un ambiente e verrà infine creata un'istanza minimale che agisca da webserver in modo da effettuare deploy dinamici ed in serie.

La serie

Ecco tutti gli articoli della serie "OpenStack, appunti di viaggio":

  • Luigi Tessitore

    Complimenti per l'ottimo lavoro!

    Una domanda: quando dici che "I nodi Compute dovrebbero essere pensati come
    componenti prive di configurazioni complesse, facilmente rimpiazzabili,
    in una parola: cannoni da fuoco, i cui proiettili saranno le istanze
    prodotte e guidate dal nodo Controller." stai affermando che le istanze delle VM girano sull'hw di queste macchine?

  • Raoul Scarazzini

    Esattamente. E' proprio lì che si gioca la netta differenza filosofica tra una soluzione cloud come OpenStack e una soluzione di virtualizzazione classica come RHEV o VMWare.
    Il "deploy" che ho menzionato consiste proprio nella copia dell'immagine sul nodo compute. Considerata la volatilità dell'istanza non è necessario che il nodo compute la conservi, il che, per proprietà transitiva, rende il nodo compute non essenziale, facilmente rimpiazzabile. Un cannone "e basta", appunto 🙂

  • Fabrizio

    Bello ma appunto nova network è deprecato...

  • Raoul Scarazzini

    È vero, ma Nova network è perfettamente funzionale allo scopo illustrativo dell'articolo.
    A voler essere precisi anche Havana è una release in end of life.
    Tuttavia il proof of concept non perde di valore.