Gentoo Linux OpenMosix Tutorial

Contenuti:

1.Introduzione

OpenMosix cos'è 

OpenMosix è uno dei sistemi di clustering più avanzati per gli ambienti di calcolo scientifico. Si contraddistingue per la facilità d'uso e per le alte prestazioni. OpenMosix è in grado di implementare il concetto di Single System Image, cioè un insieme di nodi individuali che danno all'utente e agli applicativi la visione di un unico grande computer. L'utente quindi non sa se un processo sta andando su un nodo che non è il suo. Attraverso algoritmi di bilanciamento, un processo in esecuzione su un nodo può 'migrare' in modo trasparente su di un altro nodo dove può attingere maggiori risorse. Infatti gli algoritmi di bilanciamento di OpenMosix fanno sì che i programmi abbiano sempre a disposizione le risorse necessarie. Fino a quando le risorse necessarie sono disponibili localmente, il processo rimarrà sul nodo sul quale è stato lanciato. Quando invece le risorse richieste superano quelle locali, il processo 'migra' in tempo reale verso un altro nodo che in quel momento ha un minor carico di lavoro. OpenMosix è in sostanza una patch da applicare al kernel standard di Linux e riguarda esclusivamente il cluster vero e proprio. Per la sua gestione, configurazione e monitoraggio, ci sono delle utility che girano nello user-space.

2.Installazione

Note sull'installazione 

Il processo di installazione e configurazione di un cluster OpenMosix è attualmente abbastanza semplice. Prima di tutto dovremo installare un kernel Linux con OpenMosix abilitato su ogni macchina che diventerà un nodo del cluster. Quindi installeremo le utility OpenMosix userland tools su ogni sistema. Alla fine dovremo configurare un paio di files in /etc e, se non esiste, creare uno script di startup.

Installazione di OpenMosix 

Per installare il software sul nostro nodo Gentoo dobbiamo avvalerci del mitico emerge:

Esempio 1

# emerge sys-apps/openmosix-user

Il comando precedente dovrebbe installare un OpenMosix kernel insieme alle utility OpenMosix. Questo tutorial è stato scritto per il kernel 2.4.22 che al momento è quello installato di default e per la versione 0.3.4 di openmosix-user.

Creazione di un kernel OpenMosix 

La prima cosa da fare è andare nella directory dei sorgenti del kernel ;-)) e inizializzare la procedura:

Esempio 2: Inizializzare la compilazione del kernel

# cd /usr/src/linux
# make mrproper

Fatto questo possiamo proseguire con la configurazione, compilazione e installazione del kernel. Tutto ciò di cui abbiamo bisogno è di abilitare gli appropriati set sotto la nuova sezione openMosix:

Esempio 3: Opzioni da attivare nel kernel

# make menuconfig
[*] openMOSIX process migration support
[*] Stricter security on openMOSIX ports
[*] Direct File-System Access
[*] openMOSIX File-System
[*] Poll/Select exceptions on pipes

Il resto della fase di configurazione, compilazione e installazione del kernel dovrebbe proseguire normalmente. Una volta che tutti i nodi hanno un kernel openMosix installato, è il momento di installare le utility userland su ogni nodo.

Nota: Un suggerimento. Installate anche un vanilla-kernel nel caso qualcosa non vada a buon fine col kernel openMosix. Usando gentoo 1.4 col kernel openMosix 2.4.22, ci potrebbe essere un problema al riavvio del PC. Il kernel si blocca senza errori apparenti prima di montare il devfs. Sembra che il problema sia l'ottimizzazione troppo aggressiva che viene attivata di default durante l'installazione di gentoo. Se in /etc/make.conf troviamo -O3, proviamo a porla uguale a -O2 e ricompilare il kernel, ricordandosi di dare un bel make mrproper prima di partire.

Configurazione delle utility userland 

Gli OpenMosix userland tools sono facili da configurare. Prima di tutto dobbiamo creare il file /etc/openmosix.map. Questo file ha la seguente sintassi:

Esempio 4: Sintassi di /etc/openmosix.map

numero_nodo   indirizzo_IP  range

"numero_nodo" dovrebbe essere il numero ufficiale di ogni nodo partendo da 1 con incremento di 1 per ogni linea successiva. Segue l'"indirizzo_IP" di ogni nodo e 1 per "range". Per esempio un openmosix.map che consiste in due nodi con IP 192.168.1.1 e 192.168.1.9 dovrebbe apparire nel seguente modo:

Esempio 5: Esempio di /etc/openmosix.map


1   192.168.1.1     1
2   192.168.1.9     1

Se invece avete ad esempio 10 nodi con IP consecutivi che partono dal 192.168.1.1 al 192.168.1.10 potete trarre vantaggio dal "range", infatti l' openmosix.map conterrà solo una riga come segue:

Esempio 6

1   192.168.1.1     10

Senza l'argomento "range" avreste dovuto creare un openmosix.map di 10 righe, una per ogni nodo.

Attenzione: Notate che il file openmosix.map NON DEVE contenere righe di commento. Altrimenti alla partenza di openMosix avrete un errore del tipo "tabella non ben formattata" ("table is not well-formatted").

Dobbiamo ora creare il punto di montaggio per l'oMFS (l'openMosix File System) e configurare appropriatamente il file /etc/fstab affinché il mounting avvenga automaticamente ad ogni riavvio del nodo:

Esempio 7: Configurazione per l'oMFS

# mkdir /mfs
# vi /etc/fstab
oMFS        /mfs        mfs     dfsa=1      0   0

Non ci resta che testare il nodo:

Esempio 8: Start del cluster

# /etc/init.d/openmosix start

Se il comando ha successo, proviamo ad eseguire il seguente comando (il numero indica il nodo, possiamo sostituirlo col numero del nodo da testare):

Esempio 9

# mosctl status 1
Up.

Se il risultato è "Up" siamo a cavallo!!! Il nodo è correttamente configurato e funzionante. Non resta che aggiungere al sistema di startup lo script openmosix per farlo partire ad ogni riavvio:

Esempio 10: Aggiungere openmosix al runlevel di default

# rc-update add openmosix default

3.Testiamo il cluster

Una volta che abbiamo più di un nodo installato e funzionante, possiamo testare veramente il cluster. Possiamo creare un piccolo script con le seguenti righe:

Esempio 11: Script di test

# vi test
for x in 1 2 3 4
do
    awk 'BEGIN{for(i=0;i<10000;i++)for(j=0;j<10000;j++); 
done

Ne mandiamo in esecuzione un paio in background e controlliamo con l'utility mosmon cosa succede:

Esempio 12

# ./test &
# ./test &
# mosmon

mosmon mostra in modalità testuale un grafico dell'attività di ogni singolo nodo. Dovremmo quindi vedere un paio di nodi la cui attività è notevole.


Figura 1: openMosix monitor

Fig. 1: openMosix monitor

Se vogliamo proprio stressare il nostro cluster possimo installare l'openmosixtest, una serie di tools che testano il cluster in vari modi, generando alla fine un report su file molto dettagliato dei risultati ottenuti. Per installare openmosixtest e iniziare il test:

Esempio 13

# emerge app-admin/openmosixtest
# cd /opt/omtest
# ./compile_tests.sh
# ./start_openMosix_test.sh

Potete ora andare a mangiare una pizza, a farvi una partita a scacchi o a leggervi "Il Signore degli anelli", perché il test durerà abbastanza.

4.L'oMFS (openMosix File System)

Nel paragrafo sull'installazione e configurazione abbiamo visto come abilitare nel kernel il supporto per l'oMFS e come montare l'openMosix File System al ravvio del nodo, ma in pratica cos'è l'oMFS e a cosa serve?

L'oMFS è un file system che dà una visione globale di tutti i file system locali di ogni nodo, da ogni nodo. Sembra un'affermazione astratta e forse lo è. Il suo creatore Moshe Bar lo definisce "uno strato astratto che mi permette questa visione unificata globale, ma non è un file system che scrive dati su un proprio disco. Per lo storage, oMFS si basa su qualsiasi file system supportato da Linux" (L&C - Anno 4 Numero 24).

In pratica una volta che l'oMFS è montato in /mfs su ogni nodo, ogni file systems di ogni nodo (escluso /proc), è accessibile attraverso /mfs/[openMOSIX_ID]/directory, e questo da ogni nodo. Se andiamo dentro /mfs e facciamo un ls...:

Esempio 14: Test di oMFS

# cd /mfs
# ls -l
total 16
drwxr-xr-x 20 root root 4096 Mar  8 22:13 1
drwxr-xr-x 20 root root 4096 Mar  8 1996  2
drwxr-xr-x 21 root root 4096 Mar  8 23:25 3
drwxr-xr-x 20 root root 4096 Mar  8 22:59 4
lr-xr-xr-x  1 root root    1 Dec 31  1969 here -> 1
lr-xr-xr-x  1 root root    1 Dec 31  1969 home -> 1
lr-xr-xr-x  1 root root    1 Dec 31  1969 lastexec -> 1
lr-xr-xr-x  1 root root    1 Dec 31  1969 magic -> 1
lr-xr-xr-x  1 root root    1 Dec 31  1969 selected -> 1
# ls 3
bin dev home lib mfs mnt proc sbin usr work
boot etc initrd lost+found misc opt root tmp var

È possibile quindi copiare file tra i vari nodi o accedere a file residenti su nodi diversi, direttamente attraverso /mfs. Questo permette ad un processo migrato su un nodo remoto di poter eseguire chiamate di sistema (lettura, scrittura, apertura, creazione, chiusura, etc.) senza dover tornare al nodo di origine. Con l'aiuto di link simbolici, tutti i nodi del cluster possono accedere agli stessi dati, p.e. /home_n01 sul nodo1:

Esempio 15

sul nodo2: # ln -s /mfs/1/home_n01 /home_n01
sul nodo3: # ln -s /mfs/1/home_n01 /home_n01
...
...

5.E se ho tanti nodi da montare?

Ecco un suggerimento per utenti più smaliziati e smanettoni che si trovano a installare un certo numero di nodi su macchine con le stesse caratteristiche hardware. In questi giorni mi sono trovato a dover installare un 'piccolo' cluster di 12 nodi. Le macchine sono tutte nuove e hanno tutte le stesse caratteristiche hardware. Installare Gentoo e configurare tutti i files per arrivare ad avere un nodo funzionante richiede tempo e concentrazione per questo ho pensato ad un modo 'rapido' per 'clonare' i nodi. I passi che ho seguito sono semplici (altri suggerimenti sono veramente apprezzati). Ho installato Gentoo su un nodo, facendo molta attenzione ad installare tutto il necessario per il suo funzionamento. Quando tutto funzionava perfettamente ho stoppato il sistema. Quindi ho tolto il disco di sistema da un secondo nodo, ho cambiato il jumper per renderlo slave, e l'ho messo in cascata al master del nodo precedentemente installato. Ho fatto ripartire il nodo che a questo punto ha due dischi. Dopo il login come root:

Esempio 16

# fdisk /dev/hdb

Ho naturalmente creato le stesse partizioni del nodo funzionante, settato il bootable flag su /dev/hdb1, salvato la tabella e creato lo swap e i filesystem ext3:

Esempio 17

# mkswap /dev/hdbX
# mke2fs -j /dev/hdbX
Dove X è la partizione da creare.

A questo punto col buon vecchio dd ho 'clonato' le partizioni:

Esempio 18

# dd if=/dev/hdaX of=/dev/hdbX
Anche in questo caso sostituire a X il numero della partizione.

Al termine della clonazione, ho montato la partizione / del secondo disco in /mnt per cambiare alcuni settaggi del nuovo nodo:

Esempio 19

# mount /dev/hdbX /mnt
# vi /mnt/etc/hostname
Cambio l'hostname.
# vi /mnt/etc/conf.d/net
Cambio l'IP del nuovo nodo.

Smontiamo quindi /mnt e stoppiamo il nodo:

Esempio 20

# umount /mnt
# halt

Rimontiamo fisicamente il disco sul nuovo nodo (ricordando di rimettere a posto il jumper per renderlo nuovamente master), lo ricolleghiamo al sistema e accendiamo il nuovo nodo. Se tutto va come dovrebbe abbiamo un nodo funzionante con una fatica minima.

6.DSH, Distributed Shell

Introduzione 

Ci sono dei momenti che dobbiamo lanciare dei comandi su ciascuno dei nodi del nostro cluster. Collegarsi a ciascun nodo non è una soluzione valida. Usare ssh o rsh richiede comunque la ridigitazione del comando col cambio dell'IP o del nome del nodo.

Per farlo in modo più semplice ci viene in aiuto dsh una shell distribuita. Ho scritto personalmente l'ebuild per l'installazione sia della dsh che delle libdshconfig dalle quali è dipendente. dsh usa rsh o ssh per l'esecuzione finale dei comandi.

Installazione 

Per installare dsh usiamo il solito comando emerge:

Esempio 21

# emerge app-shells/dsh

Essendo dsh dipendente in fase di compilazione dalle libdshconfig, il precedente comando dovrebbe installare anche queste ultime.

Configurazione 

La configurazione è altrettanto semplice. Occorre creare il file mosix (il nome del file può essere anche cambiato) dentro $HOME/.dsh/group/ con al suo interno la lista degli ip dei nodi che fanno parte del cluster.

Esempio 22: Configurazione di DSH

# mkdir $HOME/.dsh
# mkdir $HOME/.dsh/group
# vi $HOME/.dsh/group/mosix
192.168.1.1
192.168.1.2
192.168.1.3
...
...

Uso 

Vediamo come usare dsh per eseguire ls su tutti i nodi. Useremo il flag -g per specificare il gruppo (in questo modo possiamo avere più gruppi con differenti configurazioni).

Esempio 23

# dsh -r ssh -g mosix ls
192.168.1.1:    anaconda-ks.cfg
192.168.1.1:    install.log
192.168.1.1:    install.log.syslog
192.168.1.2:    anaconda-ks.cfg
192.168.1.2:    install.log
192.168.1.2:    install.log.syslog
192.168.1.3:    anaconda-ks.cfg
192.168.1.3:    install.log
192.168.1.3:    install.log.syslog
...
...

Notate che nessuna delle macchine richiede la password. Questo perchè ho configurato l'autenticazione rsa tra i vari nodi. Se volete eseguire comandi con dei parametri devete racchiudere il comando tra virgolette:

Esempio 24

# dsh -r ssh -g mosix "uname -c"

o usare l'opzione -c:

Esempio 25

# dsh -r ssh -g mosix -c -- uname -a

7.Configurare SSH senza password

Il primo passo è generare un paio di chiavi per SSH sul nodo master con ssh-keygen:

Esempio 26: Generazione della chiave rsa

# ssh-keygen -t rsa
verrà richiesto l'inserimento e la conferma della passphrase

Questo comando creerà due file dentro $HOME/.ssh, id_rsa (che è la chiave privata e non va data a nessuno) e id_rsa.pub (che è la chiave pubblica). Copiamo la chiave pubblica in un file chiamato authorized_keys:

Esempio 27

# cp $HOME/.ssh/id_rsa.pub $HOME/.ssh/authorized_keys

Il file $HOME/.ssh/authorized_keys va copiato sui nodi sempre in $HOME/.ssh.

Esempio 28

# scp -p $HOME/.ssh/authorized_keys nodeX:$HOME/.ssh/authorized_keys

Se proviamo ad aprire una connessione SSH con un nodo ci verrà richiesto l'inserimento della passphrase. Una volta immessa dovremmo essere loginati. Ma qual è il vantaggio? La passphrase di solito è più lunga di una normale password.

Ebbene, il vantaggio risiede nel fatto che possiamo usare ssh-agent che amministra la passphrase durante un login ssh. Facciamo una prova:

Esempio 29: Uso di ssh-agent

# ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XXYqbMRe/agent.1065; export SSH_AUTH_SOCK;
SSH_AGENT_PID=1066; export SSH_AGENT_PID;
echo Agent pid 1066;

L'esecuzione di ssh-agent produce la visualizzazione di due variabili ambiente con tanto di valore che dovrebbero essere settate se già non lo sono. Proviamo:

Esempio 30

# echo $SSH_AUTH_SOCK
# echo $SSH_AGENT_PID

Se non otteniamo risultati:

Esempio 31

Per la bash shell:
# export SSH_AUTH_SOCK=/tmp/ssh-XXYqbMRe/agent.1065
# export SSH_AGENT_PID=1066
Per la csh/tcsh shell:
# setenv SSH_AUTH_SOCK=/tmp/ssh-XXYqbMRe/agent.1065
# setenv SSH_AGENT_PID=1066

Con queste variabili il daemon sshd sull'host remoto può connettersi al nostro ssh-agent locale usando il socket-file in /tmp (nel nostro esempio /tmp/ssh-XXYqbMRe/agent.1065). ssh-agent può ora passare la passphrase al nodo remoto usando questo socket (naturalmente in modo cryptato).

Dobbiamo ora aggiungere la nostra chiave pubblica all'ssh-agent usando ssh-add:

Esempio 32

# ssh-add

Dovremmo ora essere in grado di eseguire un login via ssh su un nodo remoto senza la richiesta della passphrase.

Per evitare di eseguire tutte le operazioni che abbiamo visto in modo manuale ad ogni login, possiamo inserire i seguenti comandi all'interno del nostro login-profile (.bash_profile o .cshrc):

Esempio 33

# vi $HOME/.bash_profile
eval `ssh-agent`
ssh-add

Al prossimo login ci verra' richiesto l'inserimento della passphrase, e potremmo per tutta la sessione di lavoro loginarci su un nodo remoto o usare dsh senza che ci venga richiesto l'inserimento di alcuna password.

8.Script di partenza

Se per qualche motivo non fosse stato installato lo script di partenza, potete ricopiarvi il seguente:

Esempio 34

# vi /etc/init.d/openmosix

#!/sbin/runscript

depend() {
    need net
}

stop() {
    ebegin "Stopping openMosix"
    setpe -off
    rm -f /var/lock/subsys/mosix
    eend
}

start() {
    ebegin "Starting openMosix"
    if [ -s /etc/overheads -a -f /proc/mosix/admin/overheads ]
    then
        egrep -v '^#' /etc/overheads > /proc/mosix/admin/overheads
    fi
    if [ -s /etc/mfcosts -a -f /proc/mosix/admin/mfcosts ]
    then
        egrep -v '^#' /etc/mfcosts > /proc/mosix/admin/mfcosts
    fi
    local a1
    local a2

    a1=
    [ -s /etc/mospe ] && a1=" -p `cat /etc/mospe`"
    s2=
    [ -s /etc/mosgates ] && a2=" -g `cat /etc/mosgates`"
    setpe -W $a1 $a2 -f /etc/mosix.map
    touch /var/lock/subsys/mosix
    eend
}


Ultimo aggiorn.:
11 Novembre 2003
Enrico Morelli
Scrittore

Sommario:  Questo tutorial mostra come installare un cluster di PC Gentoo Linux basato su OpenMosix. Copre anche aspetti quali l'oMFS, DSH e SSH.
- 2002 Gentoo.it - Domande, commenti e/o correzioni? Email gentoo-dev@gentoo.it.