Questo HOWTO intende illustrare la creazione di una rete formata da postazioni
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
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.
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
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:
# 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
# cp .config .config_funzionante
Entrare nei seguenti sotto-menu e controllate che le opzioni elencate siano impostate come compilate staticamente (e
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 supportSe 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 della
Dopo aver riconfigurato il kernel del master è necessario procedere alla sua compilazione:
# 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
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:
# 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
# cd /usr/src/linux # cp .config_master .config
Ora è possibile lanciare nuovamente l'interfaccia grafica di configurazione del kernel digitando:
# cd /usr/src/linux # make menuconfig
Accertarsi d'avere selezionato le seguenti voci come compilate staticamente e
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
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).
# 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:
# mkdir /diskless # cp /usr/src/linux/arch/i386/boot/bzImage /diskless
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
# mkdir /diskless/192.168.1.21
Molti file presenti in
# 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:
# 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(solo per openMosix) # mkdir /diskless/192.168.1.21/mfs
La maggior parte delle directory create precedentemente dovrebbero essere familiari. Directory quali
Anche se la directory
# mknod /diskless/192.168.1.21/dev/console c 5 1
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 è meglio controllare il funzionamento di alcune cose. Per prima cosa controlliamo la connessione di rete:
# ifconfig eth0 multicast # ifconfig -a
E' opportuno controllare che il dispositivo
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
Se la rete non ha ancora un server DHCP è necessario crearne uno:
# 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.
Dovrete modificare solamente il file
# 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ì:
# 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'
# 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.# Utilizzare l'indirizzo IP del master next-server 192.168.1.1; }# Se si sta utilizzando etherboot senza una specifica immagine class "etherboot" { if substring (option vendor-class-identifier, 0, 9) = "Etherboot" { filename "/diskless/vmlinuz"; } } pool { max-lease-time 86400; default-lease-time 86400;# Questa opzione evita che dei pc non autorizzati ottengano un IP deny unknown clients; } host slave21 {# Utilizzare l'indirizzo MAC dello slave hardware ethernet 00:40:63:C2:CA:C9;# Fornire allo slave un indirizzo IP statico fixed-address 192.168.1.21; server-name "master";# Se necessario indicare l'indirizzo IP del vostro gateway option routers 192.168.1.1;# Se necessario indicare l'indirizzo IP del vostro server DNS option domain-name-servers 192.168.1.1; option domain-name "mydomain.com";# Utilizzare l'hostname dello slave option host-name "slave21";# Etherboot e pxe eseguono l'avvio con una specifica immagine 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"; } } }
L'indirizzo IP in indicato dopo la voce
# man dhcpd.conf
Prima di lanciare lo script d'avvio del server dhcp modificare il file
IFACE="eth0"# inserire altre eventuali opzioni
La variabile
# /etc/init.d/dhcp start
Per avviare il server dhcp fin dall'avvio del master digitare:
# rc-update add dhcp default
E' possibile verificare l'avvio di una postazione remota leggendo il file
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
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.
no free leases on subnet LOCAL-NET
Ogni volta che sono fatte delle modifiche alla configurazione è necessario riavviare il server dhcp. Per riavviarlo digitare:
# /etc/init.d/dhcpd restart
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.
E' consigliabile utilizzare l'ebuild
# emerge tftp-hpa
Modificare il file
INTFTPD_PATH="/diskless" INTFTPD_OPTS="-l -v -s ${INTFTPD_PATH}"
L'opzione
Per avviare il server tftp digitate:
# /etc/init.d/in.tftpd start
In questo modo il server tftp viene avviato usando le opzioni specificate in
# rc-update add in.tftpd default
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.
E' necessario procurarsi il file
# emerge syslinux
Prima d'avviare il server tftp si deve configurare pxelinux. Per prima cosa copiare il binario di pxelinux
all'interno della directory
# 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
(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
Si analizzi ora il file
DEFAULT /bzImage APPEND ip=dhcp root=/dev/nfs nfsroot=192.168.1.1:/diskless/192.168.1.21
Alla variabile
Etherboot carica l'immagine del kernel da un server TFTP. Così come PXE, anche Etherboot è equivalente a LILO o
GRUB. Il programma
E' necessario installare il pacchetto
# emerge mknbi
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
# 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.
# mkelf-linux -ip=dhcp /diskless/bzImage > /diskless/vmlinuz
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
# 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:
# tcpdump hostclient_ip andserver_ip
E' possibile utilizzare
# 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
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.
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.
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:
# grep NFS /usr/src/linux/.config_master
Se il kernel è stato configurato correttamente si dovrebbe avere un risultato simile al seguente:
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
Per installare il pacchetto contenente i programmi di NFS digitare:
# emerge nfs-utils
Questo pacchetto installa i programmi richiesti per un corretto funzionamento di NFS, preoccupandosi di risolvere tutte le loro dipendenze.
I principali file da configurare sono:
/etc/exports /diskless/192.168.1.21/etc/fstab /etc/conf.d/nfs
All'interno del file
Una configurazione tipica del file
# aggiungete 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(
# 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(solo se si sta configurando un cluster openMosix) none /mfs mfs dfsa=1 0 0
Nell'esempio la variabile
L'ultimo file da modificare è
# 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
Per avviare il server nfs utilizzare lo script situato in
# /etc/init.d/nfs start
Per avviare il server nfs all'avvio del master digitare:
# rc-update add nfs default
A questo punto è possibile sincronizzare il filesytem dello slave con quello del master fornendo i binari necessari, ma mantendo i file propri 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
Gli script di base cercano di lanciare
(Si crea il file /fastboot per il prossimo avvio) # touch /diskless/192.168.1.21/fastboot(Si crea il file /fastboot ad ogni avvio) # 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
depend() { before *
Se si sta usando un file system live, non bisogna dimenticarsi di eseguire
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/: 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!