Gentoo Logo

Postazioni diskless usando Gentoo Linux

Indice:

1.  Introduzione

Prefazione

Questa guida 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 si riferirà 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 consultare 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

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:

Codice 2.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:

Codice 2.2: Fare una copia della configurazione del kernel del master

# cp .config .config_funzionante

Entrare nei seguenti sotto-menu e controllare 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:

Codice 2.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


Se si intende accedere a internet tramite il master e avere un firewall sicuro è consigliabile attivare il supporto a iptables.

  [*] 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 del Manuale sulla sicurezza per Gentoo .

Nota: Queste opzioni del kernel sono da intendersi come un'aggiunta alle proprie attuali opzioni, esse non intendono rimpiazzare completamente la propria configurazione del kernel.

Dopo aver riconfigurato il kernel del master è necessario procedere alla sua compilazione:

Codice 2.4: Ricompilare il kernel del master ed i suoi moduli

# make && make modules_install
(Accertarsi che /boot sia montata prima di copiarvi i file)
# 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. Compilare il kernel degli slave nello stesso percorso in cui è stato compilato quello del master.

Per evitare confusione e inutili sprechi di tempo è consigliabile fare una copia della configurazione del kernel del master. Digitare semplicemente:

Codice 2.5: Fare un copia di sicurezza della configurazione del kernel del master

# cp /usr/src/linux/.config /usr/src/linux/.config_master

Procedere 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:

Codice 2.6: Ripristinare il .config predefinito

# cd /usr/src/linux
# cp .config_master .config

Ora è possibile lanciare nuovamente l'interfaccia grafica di configurazione del kernel digitando:

Codice 2.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:

Codice 2.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).

Codice 2.9: Compilare il kernel dello slave

# cd /usr/src/linux
# make

Ora creare una directory sul master per contenere i file di 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.

Codice 2.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:

Codice 2.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:

Codice 2.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:

Codice 2.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/sys
# 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

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. È necessario anche modificare il file /diskless/192.168.1.21/etc/conf.d/hostname per riflettere l'hostname dello slave. I file binari, le librerie ed i restanti file verranno 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".

Codice 2.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 controllare la connessione di rete:

Codice 3.1: Controllo della configurazione di rete

# ifconfig eth0 multicast
# ifconfig -a

È opportuno controllare che il dispositivo eth0 sia funzionante. Dovrebbe apparire circa così:

Codice 3.2: 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:

Codice 3.3: 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

Bisognerà modificare solamente il file /etc/dhcp/dhcpd.conf prima d'avviare il proprio server. Si può semplicemente copiare il file di configurazione d'esempio, modificandolo in seguito:

Codice 3.4: 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ì:

Codice 3.5: File dhcpd.conf d'esempio

# opzioni globali
ddns-update-style none;
shared-network LOCAL-NET {
# opzioni di rete condivise
subnet 192.168.1.0 netmask 255.255.255.0 {
    # opzioni relative alle varie subnet
    host slave{
        # opzioni relative ad uno specifico host
    }
    group {
        # opzioni relative ad un determinato gruppo
    }
}
}

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:

Codice 3.6: Esempio del file dhcpd.conf

#
# Sample dhcpd.conf for diskless clients
#

# Disabilita il DNS dinamico
ddns-update-style none;

# Impostiamo un singolo gateway per il traffico IP
option routers 192.168.1.1;

# Forniamo ai client le informazioni relative ai server DNS
option domain-name-servers 192.168.1.1;
option domain-name "mydomain.com";

# Specifichiamo il server TFTP da utilizzare
next-server 192.168.1.1;

# 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;

# Impostiamo la sottorete in cui saranno collocati i nostri nodi diskless
subnet 192.168.1.0 netmask 255.255.255.0 {

  # Forniamo le adeguate impostazioni ai client PXE
  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";
  }

  # Forniamo le adeguate impostazioni ai client Etherboot
  class "etherboot" {
        match if substring(option vendor-class-identifier, 0, 9) = "Etherboot";
        filename "vmlinuz_arch";
    }

  # Aggiungiamo una dichiarazione di questo tipo per ogni nodo diskless
  host slave21 {
    hardware ethernet 00:02:A5:04:3B:66;
    fixed-address 192.168.1.21;
  }
}

Nota: Nulla impedisce di utilizzare insieme l'avvio tramite PXE e quello tramite Etherboot. Il codice illustrato precedentemente è soltanto un esempio. Nel caso si riscontrino 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 voce filename ha come percorso relativo /diskless (questo dipende dalle impostazioni relative al server tftp, impostazioni che verranno analizzate 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. 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:

Codice 3.7: 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:

Codice 3.8: Esempio del file /etc/conf.d/dhcp

IFACE="eth0"
# inserire altre eventuali opzioni

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:

Codice 3.9: Avviare il server dhcp sul master

# /etc/init.d/dhcp start

Per avviare il server dhcp fin dall'avvio del master digitare:

Codice 3.10: 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 messages si dovrebbero avere delle linee come queste:

Codice 3.11: 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.

Codice 3.12: 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:

Codice 3.13: 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:

Codice 4.1: 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:

Codice 4.2: 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 digitare:

Codice 4.3: 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 digitare:

Codice 4.4: 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:

Codice 4.5: 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:

Codice 4.6: Configurare il bootloader remoto

# cp /usr/share/syslinux/pxelinux.0 /diskless
# mkdir /diskless/pxelinux.cfg
# touch /diskless/pxelinux.cfg/default

Questo crea una configurazione predefinito 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.

Codice 4.7: Sequenza di file cercati da PXE all'interno di pxelinux.cfg/

(Lo 01 iniziale indica un'interfaccia Ethernet, i byte successivi coincidono con l'indirizzo MAC dello slave.
01-00-40-63-c2-ca-c9

(IP assegnati in esadecimale)
C0A80115
C0A8011
C0A801
C0A80
C0A8
C0A
C0
C

default

Nota: Tutti i caratteri sono in minuscolo.

Analizzare ora il file default:

Codice 4.8: 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.

Codice 4.9: 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 pagina man di mknbi:

Codice 4.10: Lettura della pagina man di mknbi

# man mknbi

Procedere 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.

Codice 4.11: 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:

Codice 4.12: Installare tcpdump

# emerge tcpdump

Ora è possibile controllare il traffico della propria rete, accertandosi che le iterazioni client/server funzionino a dovere. Se non si riesce a vedere il traffico tra i due host bisogna controllare un paio di cose. Il primo controllo è 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 ricevele 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:

Codice 4.13: Monitorare il traffico tra il client ed il server usando tcpdump

# tcpdump host client_ip and server_ip

E' possibile utilizzare tcpdump per visualizzare il traffico relativo ad una particolare porta. Per ascoltare il traffico sulla porta di tftp digitare:

Codice 4.14: 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 si consiglia 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 RPC (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 RPC 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:

Codice 5.1: 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:

Codice 5.2: 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:

Codice 5.3: 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:

Codice 5.4: 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ì:

Codice 5.5: Esempio del file /etc/exports del master

# aggiungere un linea come questa per ogni slave
/diskless/192.168.1.21   192.168.1.21(sync,rw,no_root_squash,no_all_squash)
# comune a tutti gli slave
/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)
# se si desidera avere dei log comuni
/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 proprie 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:

Codice 5.6: Esempio del file fstab di uno slave

# queste voci sono essenziali
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
# voci utili ma opzionali
master:/var/log                 /var/log  nfs     hard,intr,rw                                 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 proprio 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:

Codice 5.7: 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=""

È 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:

Codice 5.8: Avviare il server nfs

# /etc/init.d/nfs start

Per avviare il server nfs all'avvio del master digitare:

Codice 5.9: 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 mantenenndo i file propri dello slave.

Codice 6.1: 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.

Configurare le opzioni di rete delle postazioni diskless

Per evitare che gli script di rete eseguiti all'avvio saturino la connessione al server NFS, è necessario modificare opportunamente il file /etc/conf.d/net presente in ogni postazione diskless client.

Codice 6.2: Modifica da apportare a /etc/conf.d/net

(Modificare le opzioni relative alla interfaccia di rete
    della postazione diskless aggiungendo la seguente opzione)

config_eth0=( "noop" )

Nota: Per maggiori informazioni consultare il file /usr/share/doc/openrc-*/net.example.bz2.

Script di inizializzazione

Aggiungere tutti gli script d'avvio che si desidera all'interno di /diskless/192.168.1.21/etc/runlevels. Tutto dipende da ciò che gli slave dovranno svolgere.

Avvertenza: 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).

Codice 6.3: 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           22 2003-10-18 17:28 domainname -> /etc/init.d/domainname
lrwxrwxrwx    1 root     root           20 2003-10-18 17:28 hostname -> /etc/init.d/hostname
lrwxrwxrwx    1 root     root           22 2003-10-18 17:28 localmount -> /etc/init.d/localmount
lrwxrwxrwx    1 root     root           19 2003-10-18 17:28 modules -> /etc/init.d/modules
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           21 2003-10-18 17:28 rmnologin -> /etc/init.d/rmnologin
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           23 2003-10-18 17:28 consolefont -> /etc/init.d/consolefont
lrwxrwxrwx    1 root     root           19 2003-10-18 17:28 distccd -> /etc/init.d/distccd
lrwxrwxrwx    1 root     root           19 2003-10-18 17:28 keymaps -> /etc/init.d/keymaps
lrwxrwxrwx    1 root     root           17 2003-10-18 17:28 local -> /etc/init.d/local
lrwxrwxrwx    1 root     root           16 2003-10-18 17:28 sshd -> /etc/init.d/sshd
lrwxrwxrwx    1 root     root           21 2003-10-18 17:28 syslog-ng -> /etc/init.d/syslog-ng
lrwxrwxrwx    1 root     root           17 2003-10-18 17:28 vixie-cron -> /etc/init.d/vixie-cron

/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!



Stampa

Aggiornato il 30 ottobre 2011

La versione originale di questo documento non è più mantenuta

Oggetto: Questa guida illustra la realizzazione di una rete diskless tramite l'uso di Gentoo Linux.

Michael Andrews
Ricerca

Kristian Jerpetjoen
Redazione

Sven Vermeulen
Revisione

Xavier Neys
Revisione

Flavio Castelli
Traduzione

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.