Postazioni diskless usando Gentoo Linux
1.Introduzione
Prefazione
Questo HOWTO intende illustrare la creazione di una rete formata da postazioni
diskless, basate su Gentoo Linux. Nella rete sono presenti svariate
guide che si occupano di questo argomento, purtroppo la maggior parte risultano
complicate. Invece questa guida intende essere il più semplice possibile, in
modo da aiutare anche le persone che sono alle prime armi con Linux.
Cosa è un PC diskless?
Una postazione diskless è un comune computer sprovvisto delle consuete
periferiche di avvio quali: dischi fissi, lettori floppy e lettori di cdrom. La
postazione diskless esegue la procedura d'avvio tramite la scheda di rete,
pertanto è richiesta la presenza di un server che le fornisca lo spazio fisico
su cui salvare i propri dati. D'ora in avanti ci riferiremo al server con il
termine di master, mentre con il termine slave si fa riferimento
alla postazione diskless. Come detto in precedenza lo slave esegue la procedura
d'avvio tramite la propria scheda di rete, per poterlo fare è necessario avere
una scheda di rete che supporti i protocolli PXE o Etherboot. Per sapere se la
propria scheda di rete sia tra quelle compatibili consultate la lista presente
sul sito Etherboot.org. La maggior
parte delle schede di rete (comprese quelle integrate sulle schede madri) di
recente produzione supporta PXE.
Prima di iniziare
Sul PC master dovrebbe essere installato Gentoo Linux e dovrebbe esserci
abbastanza spazio libero per contenere anche l'intero file system degli slave.
Inoltre è necessario controllare d'avere due schede di rete sul pc master,
una collegata ad internet e l'altra collegata alla rete locale.
2.Configurazione del master e degli slave
Cosa è il kernel
Nota:
Se si desidera utilizzare le proprie postazioni all'interno di un cluster
openMosix è necessario controllare di utilizzare un kernel con applicate le
patch necessarie ad openMosix. L'ebuild relativo si può trovare all'interno
del portage, nel percorso sys-kernel/openmosix-sources. Per
compilare un kernel funzionante con openMosix è consigliata la lettura
dell'openMosix HOWTO
|
Il kernel è il cuore del sistema operativo, è un programma che permette a
tutti i programmi presenti di interfacciarsi con l'hardware della propria
macchina. Quando un computer è avviato il BIOS legge delle istruzioni presenti
in un settore riservato del disco fisso; queste istruzioni non sono altro che
il boot loader, il quale si preoccupa di caricare il kernel. In seguito sarà
il kernel a gestire tutti i processi in esecuzione.
Per ulteriori informazioni sul kernel e su come configurarlo è consigliata
la lettura di
questa guida.
Configurazione del kernel della postazione master
Il kernel della postazione master non ha limiti di dimensione, sono solo
richieste alcune opzioni. Per attivarle occorre entrare nel menu di
configurazione del kernel tramite i seguenti comandi:
Esempio 1: Configurare il kernel del master |
# cd /usr/src/linux
# make menuconfig
|
A questo punto si presenta un'interfaccia grafica: si tratta di un'alternativa
più rapida rispetto alla modifica a mano del file
/usr/src/linux/.config. Se il proprio attuale kernel è
funzionante è consigliabile farne una copia da tenere al sicuro. Per farlo
digitare, all'uscita dell'interfaccia grafica, i seguenti comandi:
Esempio 2: Fare una copia della configurazione del kernel del master |
# cp .config .config_funzionante
|
Entrare nei seguenti sotto-menu e controllate che le opzioni elencate siano
impostate come compilate staticamente (e NON come dei moduli). Le
opzioni elencate di seguito sono relative ad un kernel della serie 2.6.10.
Nel caso si desideri utilizzare un kernel differente il listato seguente
potrebbe variare leggermente. Accertarsi d'avere selezionato le voci indicate
di seguito:
Esempio 3: Opzioni per il kernel del master |
Code maturity level options --->
[*] Prompt for development and/or incomplete code/drivers
Device Drivers --->
Networking options --->
<*> Packet socket
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: multicasting
[ ] Network packet filtering (replaces ipchains)
File systems --->
Network File Systems --->
<*> NFS server support
[*] Provide NFSv3 server support
[*] Network packet filtering (replaces ipchains)
IP: Netfilter Configuration --->
<*> Connection tracking (required for masq/NAT)
<*> IP tables support (required for filtering/masq/NAT)
|
Se si desidera utilizzare il packet filtering è possibile compilare le sue
sotto-opzioni modularmente. Per configurare correttamente il proprio firewall
è consigliata la lettura del capitolo numero 12 della
Guida Gentoo alla sicurezza.
Nota:
Queste opzioni del kernel sono da intendersi come un'aggiunta alle vostre
attuali opzioni, esse non intendono rimpiazzare completamente la propria
configurazione del kernel.
|
Dopo aver riconfigurato il kernel del master è necessario procedere alla sua
compilazione:
Esempio 4: Ricompilare il kernel del master ed i suoi moduli |
# make && make modules_install
# cp arch/i386/boot/bzImage /boot/bzImage-master
|
Infine aggiungere una nuova voce per il nuovo kernel all'interno di
lilo.conf o di grub.conf, a seconda del proprio
bootloader. Ora che il nuovo file bzImage è stato copiato nella directory
/boot è possibile riavviare il sistema per attivare le nuove
modifiche.
Configurare il kernel degli slave
E' consigliabile compilare il kernel degli slave senza moduli, dato che la
presenza dei moduli renderebbe la procedura d'avvio remoto difficoltosa.
Inoltre il kernel degli slave deve essere il più piccolo e compatto possibile,
in modo da essere efficiente al momento dell'avvio. Si compili il kernel degli
slave nello stesso percorso in cui abbiamo compilato quello del master.
Per evitare confusione e inutili sprechi di tempo è consigliabile fare una
copia della configurazione del kernel del master. Digitare semplicemente:
Esempio 5: Fare un bakup della configurazione del kernel del master |
# cp /usr/src/linux/.config /usr/src/linux/.config_master
|
Si procede ora alla configurazione del kernel degli slave nello stesso modo con
cui è stato configurato quello del master. Se si desidera lavorare su una
configurazione "pulita" (ovvero senza avere le opzioni selezionate
precedentemente per il master) è possibile recuperare il file
/usr/src/linux/.config iniziale digitando:
Esempio 6: Ripristinare il .config di default |
# cd /usr/src/linux
# cp .config_master .config
|
Ora è possibile lanciare nuovamente l'interfaccia grafica di configurazione
del kernel digitando:
Esempio 7: Configurare il kernel dello slave |
# cd /usr/src/linux
# make menuconfig
|
Accertarsi d'avere selezionato le seguenti voci come compilate staticamente
e NON come moduli:
Esempio 8: Opzioni obbligatorie del kernel dello slave |
Code maturity level options --->
[*] Prompt for development and/or incomplete code/drivers
Device Drivers --->
[*] Networking support
Networking options --->
<*> Packet socket
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: kernel level autoconfiguration
[*] IP: DHCP support (NEW)
File systems --->
Network File Systems --->
<*> file system support
[*] Provide NFSv3 client support
[*] Root file system on NFS
|
Nota:
Un'alternativa all'uso di un server dhcp è la creazione di un server BOOTP.
|
Importante:
E' importante che i driver della scheda di rete siano compilati staticamente
(e non come un modulo) all'interno del kernel degli slave. Ad ogni modo l'uso
dei moduli generalmente non dovrebbe rappresentare un problema.
|
Ora non resta altro che compilare il kernel dello slave. In questa fase è
opportuno prestare molta attenzione controllando che non siano sovrascritti
e/o eliminati i moduli compilati precedentemente per il master (sempre se
presenti).
Esempio 9: Compilare il kernel dello slave |
# cd /usr/src/linux
# make
|
Ora creare una directory sul master per contenere i file si sistema richiesti
dallo slave. E' possibile scegliere il percorso che si preferisce, ad esempio
questo: /diskless. Ora copiare il file bzImage dello slave
all'interno della directory /diskless:
Nota:
Nel caso in cui si stia lavorando con architetture differenti potrebbe essere
utile salvare ogni file di configurazione del kernel come
.config_arch. Fare la medesima cosa con le immagini del kernel:
salvarle all'interno di /diskless come bzImage_arch.
|
Esempio 10: Copiare il kernel dello slave |
# mkdir /diskless
# cp /usr/src/linux/arch/i386/boot/bzImage /diskless
|
Configurare il file system iniziale dello slave
Il file system del master e dello slave possono essere modificati a proprio
piacimento, al momento è interessante avere un file system iniziale con le
giuste configurazioni ed i punti di mount esatti. Per prima cosa è necessario
creare all'interno di /diskless una directory per la prima
postazione slave. Ogni slave ha bisogno della sua directory di root
(/) riservata, infatti la condivisione di alcuni file di sistema
potrebbe causare problemi con i permessi e soprattutto gravi crash. E'
possibile chiamare queste directory come si preferisce ma, per motivi pratici,
è consigliabile usare l'indirizzo ip dello slave (dato che essi sono unici e
non danno luogo a confusioni). Per esempio, nel caso in cui il primo slave
avesse il seguente ip 192.168.1.21:
Esempio 11: Creazione della directory remota di root per uno slave |
# mkdir /diskless/192.168.1.21
|
Molti file presenti in /etc devono essere modificati per potere
funzionare sullo slave. Copiare la directory /etc del master
all'interno della directory di root dello slave:
Esempio 12: Creazione di /etc per lo slave |
# cp -r /etc /diskless/192.168.1.21/etc
|
Il filesystem non è ancora pronto, ci sono ancora da creare diversi punti
di mount e directory. Per crearli digitare:
Esempio 13: Creazione dei punti di mount e delle directory dello slave |
# mkdir /diskless/192.168.1.21/home
# mkdir /diskless/192.168.1.21/dev
# mkdir /diskless/192.168.1.21/proc
# mkdir /diskless/192.168.1.21/tmp
# mkdir /diskless/192.168.1.21/mnt
# chmod a+w /diskless/192.168.1.21/tmp
# mkdir /diskless/192.168.1.21/mnt/.initd
# mkdir /diskless/192.168.1.21/root
# mkdir /diskless/192.168.1.21/var
# mkdir /diskless/192.168.1.21/var/empty
# mkdir /diskless/192.168.1.21/var/lock
# mkdir /diskless/192.168.1.21/var/log
# mkdir /diskless/192.168.1.21/var/run
# mkdir /diskless/192.168.1.21/var/spool
# mkdir /diskless/192.168.1.21/usr
# mkdir /diskless/192.168.1.21/opt
# mkdir /diskless/192.168.1.21/mfs
|
La maggior parte delle directory create precedentemente dovrebbero essere
familiari. Directory quali /dev o /proc vengono
popolate all'avvio dello slave, le restanti sono montate in seguito. E'
necessario anche editare il file
/diskless/192.168.1.21/etc/conf.d/hostname per riflettere
l'hostname dello slave. I file binario, le librerie ed i restanti file vengono
inseriti più avanti, prima dell'avvio dello slave.
Anche se la directory /dev sarà popolata successivamente da
udev, è comunque necessario creare il device console.
Altrimenti si avrà il messaggio d'errore: "unable to open initial console".
Esempio 14: Creazione del device console in /dev |
# mknod /diskless/192.168.1.21/dev/console c 5 1
|
3.Configurazione del server DHCP
A proposito del server DHCP
La sigla DHCP significa: Dynamic Host Configuration Protocol. Il server DHCP
è il primo computer con cui gli slave comunicano all'avvio. Lo scopo
principale del server DHCP è l'assegnazione degli indirizzi IP. Volendo, il
server DHCP può assegnare gli indirizzi IP in base all'indirizzo MAC della
scheda di rete dello slave. Non appena lo slave ottiene un indirizzo IP il
server DHCP gli fornisce le indicazioni su dove trovare il suo file system
iniziale ed il suo kernel.
Prima di iniziare
Prima di iniziare è meglio controllare il funzionamento di alcune cose.
Per prima cosa controlliamo la connessione di rete:
Esempio 15: Controllo della configurazione di rete |
# ifconfig eth0 multicast
# ifconfig -a
|
E' opportuno controllare che il dispositivo eth0 sia funzionante.
Dovrebbe apparire circa così:
Esempio 16: Un dispositivo eth0 funzionante |
eth0 Link encap:Ethernet HWaddr 00:E0:83:16:2F:D6
inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:26460491 errors:0 dropped:0 overruns:2 frame:0
TX packets:32903198 errors:0 dropped:0 overruns:0 carrier:1
collisions:0 txqueuelen:100
RX bytes:2483502568 (2368.4 Mb) TX bytes:1411984950 (1346.5 Mb)
Interrupt:18 Base address:0x1800
|
E' importante che appaia la voce MULTICAST, se non compare è necessario
ricompilare il proprio kernel attivando il supporto a multicast.
Installazione del server DHCP
Se la rete non ha ancora un server DHCP è necessario crearne uno:
Esempio 17: Installazione del server dhcp |
# emerge dhcp
|
Invece se la rete ha già un server DHCP non c'è da fare altro che
configurarlo in maniera da supportare il protocollo PXE.
Configurazione del server DHCP
Dovrete modificare solamente il file /etc/dhcp/dhcpd.conf prima
d'avviare il vostro server. Potete semplicemente copiare il file di
configurazione d'esempio, modificandolo in seguito:
Esempio 18: Modificare il file di configurazione del server dhcp |
# cp /etc/dhcp/dhcpd.conf.sample /etc/dhcp/dhcpd.conf
# nano -w /etc/dhcp/dhcpd.conf
|
Si tratta di un file indentato che dovrebbe apparire così:
Esempio 19: File dhcpd.conf d'esempio |
ddns-update-style none;
shared-network LOCAL-NET {
subnet 192.168.1.0 netmask 255.255.255.0 {
host slave{
}
group {
}
}
}
|
Il blocco d'opzioni di rete condivise è facoltativo e dovrebbe essere
usato per tutti gli IP che si desidera assegnare alla stessa tipologia di rete.
Si deve dichiarare almeno una subnet, mentre il blocco d'opzioni
relativo al gruppo è opzionale e consente di raggruppare le opzioni tra
i vari elementi. Un buon esempio per il file dhcpd.conf è questo:
Esempio 20: Esempio del file dhcpd.conf |
# DHCP configuration file for DHCP ISC 3.0
ddns-update-style none;
# Definizione delle opzioni relative a PXE
# Code 1: Indirizzo IP multicast del server di boot
# Code 2: Porta UDP che il client dovrebbe monitorare per le risposte MTFTP
# Code 3: Porta UDP su cui il server MTFTP è in attesa delle richieste MTFTP
# Code 4: Numero di secondi di inattività prima che il client inizi un nuovo trasferimento MTFTP
# Code 5: Numero di secondi di inattività prima che il client provi a riavviare un trasferimento MTFTP
option space PXE;
option PXE.mtftp-ip code 1 = ip-address;
option PXE.mtftp-cport code 2 = unsigned integer 16;
option PXE.mtftp-sport code 3 = unsigned integer 16;
option PXE.mtftp-tmout code 4 = unsigned integer 8;
option PXE.mtftp-delay code 5 = unsigned integer 8;
option PXE.discovery-control code 6 = unsigned integer 8;
option PXE.discovery-mcast-addr code 7 = ip-address;
subnet 192.168.1.0 netmask 255.255.255.0 {
class "pxeclients" {
match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
option vendor-class-identifier "PXEClient";
vendor-option-space PXE;
# Deve essere indicata almeno una delle opzioni PXE relative alla propria scheda di rete, solo così
# le schede dei client capiscono che c'è un server compatibile PXE. E' necessario mettere il
# valore 0.0.0.0 alla variabile MCAST IP, in questo modo i client capiscono che non c'è un
# server TFPT multicast (il valore 0.0.0.0 indica l'assenza dell'host).
option PXE.mtftp-ip 0.0.0.0;
# Questo è il nome del file che la scheda di rete del client deve scaricare.
filename "pxelinux.0";
# Questo è l'indirizzo del server presso il quale è possibile scaricare il file.
next-server 192.168.1.1;
}
class "etherboot" {
if substring (option vendor-class-identifier, 0, 9) = "Etherboot" {
filename "/diskless/vmlinuz";
}
}
pool {
max-lease-time 86400;
default-lease-time 86400;
deny unknown clients;
}
host slave21 {
hardware ethernet 00:40:63:C2:CA:C9;
fixed-address 192.168.1.21;
server-name "master";
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
option domain-name "mydomain.com";
option host-name "slave21";
option root-path "/diskless/192.168.1.21";
if substring (option vendor-class-identifier, 0, 9) = "Etherboot" {
filename "/vmlinuz_arch";
} else if substring (option vendor-class-identifier, 0,9) ="PXEClient" {
filename "/pxelinux.0";
}
}
}
|
Nota:
Nulla impedisce di utilizzare insieme l'avvio tramite PXE e quello tramite
Etherboot. Il codice illustrato precedentemente è soltanto un esempio.
Nel caso incontriate problemi è raccomandata la consultazione della
documentazione di DHCPd.
|
L'indirizzo IP in indicato dopo la voce next-server sarà richiesto nel
file indicato alla voce filename Questo indirizzo IP dovrebbe essere
quello del server tftp, che solitamente è in esecuzione sul master. Il nome
del file indicato nella vece filename ha come percorso relativo
/diskless (questo dipende dalle impostazioni relative al server
tftp, impostazioni che analizzeremo successivamente). All'interno del blocco
di opzioni della voce host alla voce hardware ethernet si
specifica un indirizzo MAC, alla voce fixed-address si indica un
indirizzo IP da assegnare staticamente all'indirizzo MAC indicato in
precedenza. E' consigliabile fare uso anche della voce host-name, la
quale non indica altro che l'hostname di un particolare slave. Per
ulteriori informazioni è consigliabile la lettura dell'ottima pagina man
di dhcpd.conf, ci sono infatti molte
altre opzioni che vanno oltre gli scopi di questa guida. E' possibile leggere
la pagina man digitando:
Esempio 21: Leggere la pagina man di dhcpd.conf |
# man dhcpd.conf
|
Avviare il server DHCP
Prima di lanciare lo script d'avvio del server dhcp modificare il file
/etc/conf.d/dhcp in maniera che assomigli a questo:
Esempio 22: Esempio del file /etc/conf.d/dhcp |
IFACE="eth0"
|
La variabile IFACE corrisponde al dispositivo di rete su cui il
server DHCP resta in ascolto, in questo caso eth0. Nel caso di complesse
tipologie di rete, con più dispositivi di rete, potrebbe essere necessario
aggiungere più valori alla variabile IFACE. Per avviare il server dhcp
digitare:
Esempio 23: Avviare il server dhcp sul master |
# /etc/init.d/dhcp start
|
Per avviare il server dhcp fin dall'avvio del master digitare:
Esempio 24: Avviare il server dhcp all'avvio del master |
# rc-update add dhcp default
|
Possibili problemi con il server DHCP
E' possibile verificare l'avvio di una postazione remota leggendo il file
/var/log/syslog.log. Se la postazione esegue con successo la
procedura di boot, verso la fine del file syslog.log si dovrebbe
avere delle linee come queste:
Esempio 25: Possibili linee create nel file di log dal server dhcp |
DHCPDISCOVER from 00:00:00:00:00:00 via eth0
DHCPOFFER on 192.168.1.21 to 00:00:00:00:00:00 via eth0
DHCPREQUEST for 192.168.1.21 from 00:00:00:00:00:00 via eth0
DHCPACK on 192.168.1.21 to 00:00:00:00:00:00 via eth0
|
Nota:
Da questo file di log è possibile anche scoprire gli indirizzi MAC degli
slave.
|
Nel caso in cui si ottenga il seguente messaggio esistono degli errori
all'interno del file di configurazione, ma il server continua comunque
a funzionare correttamente in broadcast.
Esempio 26: Possibile errore del server dhpc |
no free leases on subnet LOCAL-NET
|
Ogni volta che sono fatte delle modifiche alla configurazione è necessario
riavviare il server dhcp. Per riavviarlo digitare:
Esempio 27: Riavviare il server dhcp sul master |
# /etc/init.d/dhcpd restart
|
4.Configurare il server TFTP e l'avvio tramite PXE e/o Etherboot
A proposito del server TFTP
La sigla TFTP significa Trivial File Transfer Protocol.
Il server TFTP ha la funzione di fornire agli slave il loro kernel ed il loro
filesystem iniziale. Tutti i kernel ed i filesystem degli slave saranno
conservati sul server TFTP, è quindi una buona idea avviare il server TFTP sul
master.
Installare il server TFTP
E' consigliabile utilizzare l'ebuild tftp-hpa. Si tratta di
un'implementazione scritta dall'autore di SYSLINUX che funziona molto bene
con PXE. Per installarlo digitare:
Esempio 28: Installazione del server tfp |
# emerge tftp-hpa
|
Configurare il server TFTP
Modificare il file /etc/conf.d/in.tftpd. All'interno si deve
specificare, con la variabile INTFTPD_PATH, il percorso della directory
di root del server tftp e, nella variabile INTFTPD_OPTS, le opzioni con
cui avviare il server tftp. Il file dovrebbe essere simile a quello riportato
di seguito:
Esempio 29: Esempio del file /etc/conf.d/in.tftpd |
INTFTPD_PATH="/diskless"
INTFTPD_OPTS="-l -v -s ${INTFTPD_PATH}"
|
L'opzione -l indica che il server resta in ascolto senza richiedere
l'avvio di inetd. L'opzione -v indica che il server scrive nei file di
log molte informazioni in più rispetto al solito. L'opzione
-s /diskless specifica la directory di root del vostro server tftp.
Avviare il server TFTP
Per avviare il server tftp digitate:
Esempio 30: Avviare il server tftp sul master |
# /etc/init.d/in.tftpd start
|
In questo modo il server tftp viene avviato usando le opzioni specificate in
/etc/conf.d/in.tftpd. Se si desidera avviare il server tftp ad
ogni avvio del master digitate:
Esempio 31: Avviare automaticamente il server tftp all'avvio |
# rc-update add in.tftpd default
|
A proposito di PXELINUX
E' possibile saltare questa sezione se si ha intenzione di utilizzare solamente
Etherboot. PXELINUX è un bootloader di rete, equivalente a LILO o GRUB, che fa
uso di un server TFTP. Sostanzialmente è un insieme di istruzioni che spiegano
al pc dove reperire il proprio kernel ed il proprio filesystem. Come tutti i
bootloader anche PXELINUX permette il passaggio di parametri all'avvio del
kernel.
Prima di iniziare
E' necessario procurarsi il file pxelinux.0 che è contenuto nel
pacchetto SYSLINUX (il cui autore è H. Peter Anvin). E' possibile
installare questo pacchetto digitando:
Esempio 32: Installare syslinux |
# emerge syslinux
|
Configurare PXELINUX
Nota:
Non è richiesto Etherboot
|
Prima d'avviare il server tftp si deve
configurare pxelinux. Per prima cosa
copiare il binario di pxelinux all'interno della directory
/diskless:
Esempio 33: Configurare il bootloader remoto |
# cp /usr/lib/syslinux/pxelinux.0 /diskless
# mkdir /diskless/pxelinux.cfg
# touch /diskless/pxelinux.cfg/default
|
Questo crea una configurazione di default per il bootloader. L'eseguibile
pxelinux.0 andrà a cercare, all'interno della directory in cui è
contenuto il file pxelinux.cfg, un file il cui nome sia
l'equivalente in esadecimale dell'indirizzo IP del client. Nel caso in cui non
trovi il file allora ne cerca un altro il cui nome è identico al precedente,
senza però l'ultimo gruppo di numeri sulla destra (i numeri sono separati tra
di loro da un punto); continua a ripetere questa operazione fino a quando non
ci sono più punti all'interno del nome del file da cercare. A partire dalla
versione 2.05 syslinux per prima cosa cerca un file il cui nome deriva
dall'indirizzo mac. Se non è trovato nessun file allora è eseguita la
procedura di scoperta descritta precedentemente. Se non è trovato nessun file
allora è usato il file default.
Esempio 34: Sequenza di file cercati da PXE all'interno di pxelinux.cfg/ |
01-00-40-63-c2-ca-c9
C0A80115
C0A8011
C0A801
C0A80
C0A8
C0A
C0
C
default
|
Nota:
Tutti i caratteri sono minuscoli.
|
Si analizzi ora il file default:
Esempio 35: Esempio del file pxelinux.cfg/default |
DEFAULT /bzImage
APPEND ip=dhcp root=/dev/nfs nfsroot=192.168.1.1:/diskless/192.168.1.21
|
Alla variabile DEFAULT corrisponde il percorso completo dell'immagine
del kernel compilata precedentemente per lo slave. Nella variabile
APPEND sono specificati gli argomenti da passare al kernel al momento
del caricamento. Dato che è stato compilato il kernel dello slave con il
supporto a NFS_ROOT_SUPPORT, allora qui si specifica il percorso del
file system remoto. Il primo IP è quello del master, mentre il secondo è la
directory creata all'interno di /diskless per contenere il file
system iniziale dello slave.
A proposito di Etherboot
Nota:
E' possibile evitare l'uso di Etherboot se si ha intenzione di usare PXE.
|
Etherboot carica l'immagine del kernel da un server TFTP. Così come PXE,
anche Etherboot è equivalente a LILO o GRUB. Il programma mknbi
permette di creare varie immagini d'avvio.
Prima di iniziare
E' necessario installare il pacchetto mknbi, al suo interno si trova
tutto il necessario per creare immagini del kernel utili per il boot da remoto.
Questo programma crea un'immagine del kernel preconfigurata a partire dal
kernel originale.
Esempio 36: Installare mknbi |
# emerge mknbi
|
Configurare Etherboot
In questa sezione si crea una semplice immagine d'avvio di etherboot. Dato che
il server dhcp fornisce ai client il percorso della loro directory di root (è
stata specificata all'interno del dhcp.conf con l'opzione
option root-path) in questo momento non si deve indicarla. Per ulteriori
informazioni è consigliabile la lettura della man page di mknbi:
Esempio 37: Lettura della man page di mknbi |
# man mknbi
|
Si procede ora alla creazione delle immagini d'avvio. In questa fase si creano
delle immagini d'avvio in ELF in grado di fornire al kernel le informazioni
relative al dhcp ed al percorso del filesystem remoto; inoltre si forza il
kernel a cercare nella rete un server dhcp.
Esempio 38: Creazione delle immagini netboot |
# mkelf-linux -ip=dhcp /diskless/bzImage > /diskless/vmlinuz
|
Nota:
Per le immagini relative ad una determinata architettura è necessario
specificare bzImage_arch e vmlinuz_arch.
|
Problemi comuni con l'avvio tramite rete
Ci sono un paio di modi per individuare gli errori che si verificano durante
la fase d'avvio remoto. Per prima cosa è possibile utilizzare un programma
chiamato tcpdump. Per installarlo digitare:
Esempio 39: Installing tcpdump |
# emerge tcpdump
|
Ora è possibile controllare il traffico della vostra rete, accertandosi che le
iterazioni client/server funzionino a dovere. Se non si riesce a vedere il
traffico tra i due host dovete controllare un paio di cose. Per primo
verificare che i due host siano collegati fisicamente in maniera corretta, e
che il cavo di rete non sia danneggiato. Se il client/server non riceve le
richieste destinate ad una certa porta allora verificare la presenza di
eventuali firewall e la loro configurazione. Per leggere il traffico tra due
pc digitare:
Esempio 40: Monitorare il traffico tra il client ed il server usando tcpdump |
# tcpdump host and
|
E' possibile utilizzare tcpdump per visualizzare il traffico relativo ad
una particolare porta. Per ascoltare il traffico sulla porta di tftp digitare:
Esempio 41: Visualizzare il traffico diretto alla porta del server tftp |
# tcpdump port 69
|
Un errore molto comune è il seguente: "PXE-E32: TFTP open time-out".
Solitamente è dovuto alle regole di alcuni firewall. Se si sta usando
TCPwrappers vi consigliamo di controllare i file
/etc/hosts.allow e etc/hosts.deny controllando che
siano impostati correttamente. Ricordare che al client dove essere consentito
di connettersi al server.
5.Configurare il server NFS
A proposito del server NFS
NFS significa Network File System. Il server NFS viene utilizzato per fornire
lo spazio di lavoro agli slave. Il server NFS può essere configurato in vari
modi, ma questi esulano dagli intenti di questa guida.
A proposito di Portmapper
Molti servizi dei client e dei server non sono in ascolto su una determinata
porta, ma si affidano alle RPCs (Remote Procedure Calls). Quando il servizio è
inizializzato si mette in ascolto su una porta a caso e poi registra questa
porta tramite l'uso di Portmapper. NFS si affida alle RPCs e pertanto
Portmapper deve essere in esecuzione prima del suo avvio.
Prima di iniziare
Il server NFS richiede delle opzioni abilitate all'interno del kernel, nel caso
non siano selezionate è necessario ricompilare il kernel del master. Per
controllare rapidamente la selezione di queste opzioni digitare:
Esempio 42: Verificare il supporto di NFS all'interno del kernel del master |
# grep NFS /usr/src/linux/.config_master
|
Se il kernel è stato configurato correttamente si dovrebbe avere un risultato
simile al seguente:
Esempio 43: Kernel configurato con il supporto a NFS |
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETFILTER is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
|
Installare il server NFS
Per installare il pacchetto contenente i programmi di NFS digitare:
Esempio 44: Installare le nfs-utils |
# emerge nfs-utils
|
Questo pacchetto installa i programmi richiesti per un corretto funzionamento
di NFS, preoccupandosi di risolvere tutte le loro dipendenze.
Configurare il server NFS
I principali file da configurare sono:
Esempio 45: File di configurazione di Nfs |
/etc/exports
/diskless/192.168.1.21/etc/fstab
/etc/conf.d/nfs
|
All'interno del file /etc/exports sono specificate le directory da
condividere, come condividerle e a chi condividerle. Il file fstab dello slave
viene modificato in maniera tale da montare il filesystem che il master
condivide.
Una configurazione tipica del file /etc/exports del master
dovrebbe apparire così:
Esempio 46: Esempio del file /etc/exports del master |
/diskless/192.168.1.21 192.168.1.21(sync,rw,no_root_squash,no_all_squash)
/opt 192.168.1.0/24(sync,ro,no_root_squash,no_all_squash)
/usr 192.168.1.0/24(sync,ro,no_root_squash,no_all_squash)
/home 192.168.1.0/24(sync,rw,no_root_squash,no_all_squash)
/var/log 192.168.1.21(sync,rw,no_root_squash,no_all_squash)
|
Il primo campo indica la directory da esportare, quello successivo indica a
chi e come condividerla.. Il secondo campo può essere diviso in due parti:
nella prima si indica chi può accedere alla condivisione, nel secondo campo si
indicano i suoi permessi sulla directory. I permessi possono essere di sola
lettura(ro), lettura e scrittura (rw). Gli attributi
no_root_squash e no_all_squash sono importanti per le nostre
postazioni remote in quanto evitano crash e perdite di dati durante le
operazioni di lettura e scrittura. Il file
/diskless/192.168.1.21/etc/fstab dello slave dovrebbe essere
simile al seguente:
Esempio 47: Esempio del file fstab di uno slave |
master:/diskless/192.168.1.21 / nfs sync,hard,intr,rw,nolock,rsize=8192,wsize=8192 0 0
master:/opt /opt nfs sync,hard,intr,ro,nolock,rsize=8192,wsize=8192 0 0
master:/usr /usr nfs sync,hard,intr,ro,nolock,rsize=8192,wsize=8192 0 0
master:/home /home nfs sync,hard,intr,rw,nolock,rsize=8192,wsize=8192 0 0
none /proc proc defaults 0 0
master:/var/log /var/log nfs hard,intr,rw 0 0
none /mfs mfs dfsa=1 0 0
|
Nell'esempio la variabile master è semplicemente l'hostname del master,
oppure il suo indirizzo IP. Il primo campo indica la directory che deve essere
montata, il secondo campo indica il punto in cui montarla. Il terzo campo
indica il filesystem da utilizzare, questo deve essere NFS per ogni punto di
mount NFS. Il quarto campo indica varie opzioni che saranno usate durante il
mount (per approfondimenti consultare le pagine man di mount(1)). Molti utenti
hanno riscontrato difficoltà usando dei punti di mount soft, pertanto sono
stati usati solo punti di mount hard. Per ottimizzare il vostro sistema si
consiglia di leggere le varie opzioni applicabili a /etc/fstab.
L'ultimo file da modificare è /etc/conf.d/nfs. In questo file
sono specificate alcune opzioni che sono usate all'avvio di nfs. Dovrebbe
essere simile al seguente:
Esempio 48: Esempio del file /etc/conf.d/nfs presente sul master |
# Config file for /etc/init.d/nfs
# Number of servers to be started up by default
RPCNFSDCOUNT=8
# Options to pass to rpc.mountd
RPCMOUNTDOPTS=""
|
E' necessario cambiare il parametro RPCNFSDCOUNT inserendo il numero
di postazioni remote che sono presenti nella propria rete.
Avviare il server NFS
Per avviare il server nfs utilizzare lo script situato in
/etc/init.d. Basta digitare:
Esempio 49: Avviare il server nfs |
# /etc/init.d/nfs start
|
Per avviare il server nfs all'avvio del master digitare:
Esempio 50: Avviare il server nfs all'avvio del master |
# rc-update add nfs default
|
6.Completare il filesystem dello slave
Copiare i file mancanti
A questo punto è possibile sincronizzare il filesytem dello slave con quello
del master fornendo i binari necessari, ma mantendo i file propri dello slave.
Esempio 51: Creazione del filesystem dello slave |
# rsync -avz /bin /diskless/192.168.1.21
# rsync -avz /sbin /diskless/192.168.1.21
# rsync -avz /lib /diskless/192.168.1.21
|
Nota:
E' stato usato il comando rsync -avz al posto di cp per mantenere
i collegamenti simbolici ed i permessi dei file copiati.
|
Script di inizializzazione
Gli script di base cercano di lanciare checkroot, ciò ovviamente non
ha alcun senso per il slave. Per risolvere questo problema è possibile
modificare lo script di avvio /diskless/192.168.1.21/sbin/rc,
questa però è una soluzione pericolosa e molto difficile; inoltre dopo ogni
sincronizzazione del filesystem dello slave sarebbe necessario ripetere questa
operazione. Esiste però un trucco: avere un file /fastboot
all'avvio del proprio sistema. Questo file indica a checkroot di non
compiere alcun controllo all'avvio. Purtroppo checkroot cancella il file
/fastboot al termine della procedura d'avvio, si deve quindi
ricreare questo file prima dello spegnimento/riavvio dello slave. Basta
digitare i seguenti comandi:
Esempio 52: Evitare che gli script d'avvio compiano un controllo sul filesystem |
# touch /diskless/192.168.1.21/fastboot
# echo "touch /fastboot" >> /diskless/192.168.1.21/etc/conf.d/local.start
|
Dato che i filesystem remoti devono essere smontati il più tardi possibile
bisogna modificare il file /etc/init.d/netmount nel seguente modo:
Esempio 53: Modificare /etc/init.d/netmount |
depend() {
before *
|
Nota:
La versione 1.11.* e successive di baselayout non necessitano di questa
modifica.
|
Se si sta usando un file system live, non bisogna dimenticarsi di eseguire
depscan.sh per risolvere le dipendenze dei servizi. Si possono ignorare
tranquillamente gli eventuali messaggi d'avvertimento relativi alle collisioni
con /etc/init.d/checkroot. Questo è possibile perchè checkroot è disabilitato
dal file fastboot creato nel paragrafo precedente.
A questo punto si è liberi d'aggiungere tutti gli script d'avvio che si
desidera all'interno di /diskless/192.168.1.21/etc/runlevels;
aggiungere tutti quelli che si desidera che siano avviati sulla propria
postazione remota.
Attenzione:
NON utilizzare il comando rc-update per rimuovere o aggiungere
gli script dal runlevel dello slave mentre si è collegati sul master. Infatti
questo provocherebbe un cambiamento al runlevel del master e non dello slave.
Si deve creare i collegamenti a mano, oppure collegarsi allo slave fisicamente
(tramite tastiera e monitor) oppure da remoto (per esempio tramite ssh).
|
Esempio 54: Tipici runlevel di uno slave |
/diskless/192.168.1.21/etc/runlevels/:
total 16
drwxr-xr-x 2 root root 4096 2003-11-09 15:27 boot
drwxr-xr-x 2 root root 4096 2003-10-01 21:10 default
drwxr-xr-x 2 root root 4096 2003-03-13 19:05 nonetwork
drwxr-xr-x 2 root root 4096 2003-02-23 12:26 single
/diskless/192.168.1.21/etc/runlevels/boot:
total 0
lrwxrwxrwx 1 root root 20 2003-10-18 17:28 bootmisc -> /etc/init.d/bootmisc
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 checkfs -> /etc/init.d/checkfs
lrwxrwxrwx 1 root root 17 2003-10-18 17:28 clock -> /etc/init.d/clock
lrwxrwxrwx 1 root root 23 2003-10-18 17:28 consolefont -> /etc/init.d/consolefont
lrwxrwxrwx 1 root root 20 2003-10-18 17:28 hostname -> /etc/init.d/hostname
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 keymaps -> /etc/init.d/keymaps
lrwxrwxrwx 1 root root 22 2003-10-18 17:28 localmount -> /etc/init.d/localmount
lrwxrwxrwx 1 root root 18 2003-10-18 17:28 net.lo -> /etc/init.d/net.lo
lrwxrwxrwx 1 root root 20 2003-10-18 17:28 netmount -> /etc/init.d/netmount
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 portmap -> /etc/init.d/portmap
lrwxrwxrwx 1 root root 21 2003-10-18 17:28 rmnologin -> /etc/init.d/rmnologin
lrwxrwxrwx 1 root root 18 2003-10-18 17:28 serial -> /etc/init.d/serial
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 urandom -> /etc/init.d/urandom
/diskless/192.168.1.21/etc/runlevels/default:
total 0
lrwxrwxrwx 1 root root 17 2003-10-18 17:28 clock -> /etc/init.d/clock
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 distccd -> /etc/init.d/distccd
lrwxrwxrwx 1 root root 17 2003-10-18 17:28 local -> /etc/init.d/local
lrwxrwxrwx 1 root root 19 2003-10-18 17:28 metalog -> /etc/init.d/metalog
lrwxrwxrwx 1 root root 22 2003-10-18 17:28 ntp-client -> /etc/init.d/ntp-client
lrwxrwxrwx 1 root root 16 2003-10-18 17:28 ntpd -> /etc/init.d/ntpd
lrwxrwxrwx 1 root root 16 2003-10-18 17:28 sshd -> /etc/init.d/sshd
lrwxrwxrwx 1 root root 17 2003-10-18 17:28 vcron -> /etc/init.d/vcron
/diskless/192.168.1.21/etc/runlevels/nonetwork:
total 0
lrwxrwxrwx 1 root root 17 2003-10-18 17:28 local -> /etc/init.d/local
/diskless/192.168.1.21/etc/runlevels/single:
total 0
|
Questa è la fine, è ora di avviare il proprio slave.
In bocca al lupo!
|