Netwerk booten van een Raspberry Pi

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

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!

Volgende: Pi Zero als smart USB-stick 1 12-11 Pi Zero als smart USB-stick 1

Reacties


Door Tweakers user The Zep Man, woensdag 23 oktober 2019 09:48

Raspberry Pi 4 maakt geen gebruik van bootcode.bin, maar van een EEPROM die voorzien moet worden van een nieuwe versie omdat anders de Pi 4 geen netwerk boot ondersteunt.

[Reactie gewijzigd op woensdag 23 oktober 2019 10:13]


Door Tweakers user i-chat, woensdag 23 oktober 2019 11:35

The Zep Man schreef op woensdag 23 oktober 2019 @ 09:48:
Raspberry Pi 4 maakt geen gebruik van bootcode.bin, maar van een EEPROM die voorzien moet worden van een nieuwe versie omdat anders de Pi 4 geen netwerk boot ondersteunt.
bovendien moet je dan dat bin bestand aanpassen, door bepaalde bestanden te extracten, die aan te passen met je netwerk config en ze daarna weer te mergen. daarna moet jej e aangebaste bin file flashen.

Dat maakt het niet onmogelijk maar wel een stuk minder mainstream.

persoonlijk had ik liever een manier gezien waarop er een klein beetje opslag op de pi werd gesoldeerd waarin je een /boot partition kunt opslaan, voor de rest zou je dan kunnen volstaan met 1 of meerdere usbsticks.

Het zelfde zou kunnen werken met een heel simpel SD kaartje, ware het niet dat zo'n pakket als Noobs hier geen out-of-the-box ondersteuning voor biedt. en je dus met tal van txt-files moet gaan .......

Door Tweakers user synoniem, woensdag 23 oktober 2019 12:56

The Zep Man schreef op woensdag 23 oktober 2019 @ 09:48:
Raspberry Pi 4 maakt geen gebruik van bootcode.bin, maar van een EEPROM die voorzien moet worden van een nieuwe versie omdat anders de Pi 4 geen netwerk boot ondersteunt.
Bedankt voor de aanvulling, dat is informatie die ik nog niet had toen ik hier mee begon. Ik pas het aan en ga z.s.m. als ik de Pi 4 heb het uitproberen en uiteraard hier weer een verhaal over schrijven.

Door Aardig, zaterdag 26 oktober 2019 12:41

Aardig idee, sinds ik Pi's gebruik al nooit geloofd in die SD kaartjes.. daar zijn ze niet voor bedoeld. Externe SSD erop is uiterst stabiel en snel.

Door Tweakers user codebeat, maandag 28 oktober 2019 14:17

Ik heb een externe USB schijf gekoppeld in DietPi en daar alle gegevens laten opslaan. Werkt prima.

Door Tweakers user ThinkPad, zondag 10 november 2019 17:03

Interessante blog! Maakt dit nou ook nog veel uit qua bootsnelheid?
Is het sneller dan booten van SD-kaart of misschien juist langzamer?

Door Tweakers user synoniem, zondag 10 november 2019 20:44

ThinkPad schreef op zondag 10 november 2019 @ 17:03:
Interessante blog! Maakt dit nou ook nog veel uit qua bootsnelheid?
Is het sneller dan booten van SD-kaart of misschien juist langzamer?
Je verliest wat tijd omdat de Pi 3 eerst wacht op de SD-kaart maar het booten zelf is voor mijn idee sneller. Bij de Pi 2 zeker omdat je de wachttijd op de SD-kaart niet hebt. Maar ik heb het (nog) niet met een stopwatch gecontroleerd.

Het hele idee was ook om het beheer te vereenvoudigen. Geen wear out van de SD-kaart en op een eenvoudige manier een heel stel Pi's tegelijk backuppen i.p.v. elke Pi afzonderlijk.

Reactie formulier
(verplicht)
(verplicht, maar wordt niet getoond)
(optioneel)