Netwerk booten van een Raspberry Pi

Door synoniem op dinsdag 22 oktober 2019 23:41 - Reacties (7)
Categorie: Raspberry Pi, Views: 3.978

Inleiding
Zo in de loop van de tijd heb ik al aardig wat Raspberry Pi's draaien en daardoor ook te maken met de beperkte levensduur van SD-kaartjes. Vandaar dat ik op het idee kwam om te kijken of een Pi van het netwerk gestart kan worden. En dat kan! Voor de Pi 2B heb je dan nog steeds een SD-kaartje nodig maar daar staat maar één vfat partitie met één bestand op namelijk bootcode.bin. Staat dit bestand van ongeveer 52 K er op dan kan het SD-kaartje readonly gemaakt worden. Voor de Pi 3B, Pi 3B+ en Pi 4B heb je zelfs dat niet nodig. Overigens heb ik zelf nog geen Pi 4. maar volgens de documentatie die ik gevonden heb, werkt netbooten hetzelfde als bij de 3B+. De Pi 4 werkt niet hetzelfde, zie de link in de reactie van The Zep Man hier onder.

Wat heb je nodig: server
Om te beginnen heb je één of meer servers nodig die respectievelijk dhcp,tftp en nfs leveren. In mijn geval heb ik al een aparte dhcpserver en heb een sambaserver aanvullend geconfigureerd met tftp en nfs. In de dhcpserver heb ik option 66 next-server ingevuld met het ip-nummer van deze nieuwe server: 192.168.1.2. Daarnaast heb ik met dhcp static mappings voor vijf Pi's vaste ip-adressen ingesteld. Hiermee voorkom je een hoop problemen. Namelijk dat je Pi ineens twee ip-adressen krijgt of bij nfs startup crashed. De Pi geeft namelijk bij het booten vanaf het netwerk niet altijd een ACKnowledge naar de dhcpserver. Verderop na het laden van boot- en root-bestanden, bij het configureren van het network krijgt de Pi dan vrolijk een tweede ip-adres mee.

Voor de Pi's gebruik ik Raspbian 9 Lite en voor de samba/tftp/nfsserver Debian 9.
Wil je één server inclusief dhcp dan kan dat door het installeren en instellen van dnsmasq.

sudo apt install dnsmasq


Pas de inhoud van /etc/dnsmasq.conf aan naar:

port=0
dhcp-range=192.168.1.255,proxy
log-dhcp
enable-tftp
tftp-root=/srv/tftp
pxe-service=0,"Raspberry Pi Boot"


Voor het installeren van tftp en nfs:
sudo apt install tftpd-hpa nfs-kernel-server nfs-common

sudo mkdir /srv/tftp
sudo mkdir /srv/nfs


Controleer het tftpd-hpa configuratiebestand /etc/default/tftpd-hpa en pas het eventueel aan naar:

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"


Maak een nfs exportdirectory door /etc/exports aan te passen. In mijn thuisnetwerk heb ik dit verder niet uitgebreid beveiligd. In een bedrijfsnetwerk of niet vertrouwde omgeving is het raadzaam om de manualpage van nfs er op na te slaan om uitgebreide beveiliging in te stellen.

/srv/tftp/      192.168.1.0/24(ro,sync,no_subtree_check,no_root_squash)
/srv/nfs/      192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)


Met deze instellingen kan het hele subnet 192.168.1.0 de export benaderen. De tftp directory hoeft alleen gelezen te worden en heeft read-only als kenmerk meegekregen. De nfs-directory moet straks door de Pi's gelezen en geschreven kunnen worden, vandaar read-write access. Om het root account (of pi met sudo) te kunnen gebruiken op de Pi's stel je no_root_squash in.
Start de export met:

sudo exportfs -a -v


De server heeft als vast ip-adres 192.168.1.2 dit adres heb je straks nodig voor het instellen van de clients.

Nu wil ik voor elke Pi een eigen configuratie en filesysteem hebben. Dat kan vrij eenvoudig omdat bij het opstarten van bootcode.bin geprobeerd wordt om ./<serienummer>/start.elf in te lezen. Is de directory <serienummer> aanwezig dan zullen alle ander bootbestanden ook uit die directory gelezen worden. Om het serienummer van de Pi te achterhalen gebruik je:

pi@rpi-1:~ $ cat /proc/cpuinfo|grep Serial

Serial		: 00000000d46ad669


Het serienummer zijn de laatste acht tekens. De laatste zes tekens zijn ook de laatste zes tekens van het MAC adres.
Met dit gegeven kun je aparte directories per Pi aanmaken op je bootserver:

mkdir /srv/nfs/d46ad669
mkdir /srv/tftp/d46ad669


De eenvoudigste manier om je huidige Pi één op één als netwerkboot versie terug te krijgen, is door je bestaande SD-kaartje te kopieeren. Dit kan in theorie vanaf een werkende Pi met rsync maar mijn ervaring is dat je beter offline het SD-kaartje kan kopieeren. Daar zijn vele manieren voor, bijvoorbeeld door een kaartlezer op je server aan te sluiten en dan als root de boot en root partitie te kopieeren. Je kan met Windows en Win32 Disk Imager de SD-kaart naar een image bestand op de server kopieeren en dan op de server als image bestand mounten met losetup. Het eindresultaat moet zijn dat van de boot partitie bootcode.bin in /srv/tftp komt te staan en de rest in /srv/tftp/d46ad669. De inhoud van de rootpartitie moet (ook als root) naar /srv/nfs/d46ad669 gekopieerd worden.

Na het kopieeren moet /srv/tftp/d46ad669/etc/fstab aangepast worden zodat alleen de regel voor proc blijft staan:

proc            /proc           proc    defaults          0       0


En /srv/tftp/d46ad669/cmdline.txt met opstartparameter moet per Pi aangepast worden naar:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=192.168.1.2:/srv/nfs/d46ad669,tcp,v4 ip=192.168.1.10 rootfstype=nfs rw elevator=deadline rootwait


Gebruik je NFS versie 3 op de server dan wordt het v3 in plaats van v4. Het ip-adres 192.168.1.10 is het static mapped adres wat ik in de dhcpserver ingesteld heb staan voor deze Pi. In principe kan je ook de parameter ip=dhcp gebruiken in plaats van een ip-adres maar dat werkt dus niet altijd even betrouwbaar is mijn ervaring.

Als laatste, om het updaten van de boot bestanden mogelijk te houden, maken we een symbolic link naar de bootdirectory:

sudo ln -s /srv/tftp/d46ad669 /srv/nfs/d46ad669/boot


In principe kun je de bootdirectory ook als een nfsmount in /etc/fstab plaatsen. Maar omdat de tftp export bij mij read-only is, zou ik dan nog steeds niet de bootbestanden kunnen updaten.

Daarmee is de configuratie van de server klaar en wordt het tijd om de clients te configureren.


Wat heb je nodig: client
Het meest eenvoudig zijn de Pi 3B+ en de Pi 4B want daar hoeft niets aan te gebeuren. Netwerk aansluiten en ze kunnen booten.

De Pi 2B blijft een SD-kaartje nodig houden met een enkele vfat partitie en het bootcode.bin bestand. Vanaf daar boot hij verder op dezelfde manier als de andere modellen.

De Pi 3B vergt wat extra handelingen, namelijk het inschakelen van USB boot mode. Dit is een eenmalige actie waarbij je een stukje One Time Programmable geheugen overschrijft. Daarna kun je overigens desgewenst nog steeds van een SD-kaartje booten. Je kunt controleren of USB boot mode is ingeschakeld met het volgende commando:

$ sudo vcgencmd otp_dump | grep 17:


Is het resultaat 17:3020000a dan is het ingeschakeld.

Zo niet dan voeg je aan /boot/config.txt als laatste regel toe:

program_usb_boot_mode=1


en reboot je de Pi. Controleer of het vcgencmd commando nu wel het goede resultaat geeft en verwijder de laatste regel weer uit config.txt. Sluit de Pi af, verwijder de SD-kaart en laat hem netwerk booten!