Zum Inhalt

Festplattenloser Netzwerk-Boot (PXE) & Zentraler NFS-Root

Die Verwaltung einzelner Speichermedien – ob MicroSD-Karten oder lokale NVMe-SSDs – über eine Flotte von 10, 50 oder 200 Edge-Knoten hinweg erzeugt erheblichen Wartungsaufwand. Das manuelle Flashen von Speicherkarten, dezentrale Firmware-Updates und der Austausch defekter Flash-Zellen in Schaltschränken kosten wertvolle Ingenieurszeit und führen zu Konfigurationsabweichungen (Configuration Drift).

Indem du deinen Raspberry Pi Cluster für den festplattenlosen Netzwerk-Boot (PXE) konfigurierst, machst du lokale Festspeicher komplett überflüssig. Das On-Chip-EEPROM bootet das Board direkt über Gigabit-Ethernet: Kernel und Device-Tree-Dateien werden per TFTP geladen, während das unveränderliche Betriebssystem über NFS (Network File System) von einem zentralen Server eingehängt wird. Ein defekter Knoten wird in 60 Sekunden ausgetauscht, indem man einfach eine fabrikneue Platine ansteckt.


1. Die Netzwerk-Boot-Sequenz: Vom EEPROM zum RootFS

Im Gegensatz zu klassischen x86-Servern, die auf BIOS-Interrupts und Legacy-PXE setzen, wickeln moderne Raspberry Pi Modelle (3B+, 4, 5 sowie CM4/CM5) den Netzwerk-Boot direkt über ihren integrierten SPI-EEPROM-Bootloader ab.

%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
    subgraph Phase1["Phase 1: DHCP & IP-Zuweisung"]
        direction TB
        PI_BOOT1["Raspberry Pi EEPROM"]
        DHCP["Zentraler DHCP / ProxyDHCP"]
        PI_BOOT1 -->|DHCP-Broadcast| DHCP
        DHCP -->|Client-IP + TFTP-Info| PI_BOOT1
    end

    subgraph Phase2["Phase 2: TFTP Kernel-Download"]
        direction TB
        PI_BOOT2["Raspberry Pi TFTP-Client"]
        TFTP["Zentraler TFTP-Server"]
        PI_BOOT2 -->|Download: config.txt, DTB| TFTP
        TFTP -->|Uebertraegt kernel8.img| PI_BOOT2
    end

    subgraph Phase3["Phase 3: NFS-Mount & Betrieb"]
        direction TB
        KERNEL["Linux Kernel (RAM-Phase)"]
        NFS["Zentraler NFS-Server"]
        DISKLESS["Node betriebsbereit"]
        KERNEL -->|Mountet RootFS via TCP| NFS
        NFS ==> DISKLESS
    end

    Phase1 --> Phase2 --> Phase3

Die drei Boot-Phasen

  1. Phase 1 (DHCP & Boot-Informationen): Der Raspberry Pi sendet einen DHCP-Discover-Broadcast mit der Vendor Class Identifier (Option 60) PXEClient:Arch:00000:UNDI:002001. Der DHCP-Server weist eine IP zu und teilt dem Pi die IP des TFTP-Servers (Option 66) sowie den Pfad (Option 67) mit.
  2. Phase 2 (TFTP-Firmware-Transfer): Der integrierte TFTP-Client des Pi verbindet sich auf Port 69 und lädt die Inhalte von /boot/firmware herunter: bcm2712-rpi-5-b.dtb, Device-Tree-Overlays, cmdline.txt und den komprimierten 64-Bit-Kernel kernel8.img.
  3. Phase 3 (NFS-Root-Dateisystem): Der Kernel entpackt sich im RAM, konfiguriert die Netzwerkschnittstelle per DHCP und bindet das zentrale Root-Dateisystem über den in cmdline.txt hinterlegten NFSv4-Share ein.

2. Server-Einrichtung: dnsmasq & NFS auf Debian / TrueNAS

Du musst deinen bestehenden Firmen- oder Heim-Router nicht austauschen. Durch den Einsatz von dnsmasq im ProxyDHCP-Modus auf einem zentralen Linux-Server (oder TrueNAS/Synology NAS) schleust dnsmasq die nötigen Boot-Parameter in bestehende DHCP-Leases ein, ohne die IP-Adressvergabe an sich zu reißen.

Schritt 1: dnsmasq und NFS-Server installieren

Auf dem zentralen Server (z. B. Debian 12 unter 192.168.10.10):

sudo apt update
sudo apt install -y dnsmasq nfs-kernel-server rpcbind

Schritt 2: dnsmasq fuer TFTP und ProxyDHCP konfigurieren

Konfigurationsdatei /etc/dnsmasq.d/rpi-pxe.conf anlegen:

sudo nano /etc/dnsmasq.d/rpi-pxe.conf

Folgende Konfiguration einfügen:

# DNS-Server auf Port 53 deaktivieren
port=0

# Nur auf interner Management-Schnittstelle lauschen
interface=eth0
bind-interfaces

# ProxyDHCP-Modus aktivieren (ergaenzt bestehende DHCP-Server)
# Format: dhcp-range=<Subnetz-IP>,proxy,<Subnetzmaske>
dhcp-range=192.168.10.0,proxy,255.255.255.0

# Raspberry Pi Bootloader-Clients identifizieren
dhcp-vendorclass=set:rpi,PXEClient:Arch:00000:UNDI:002001

# Vendor-Option 43 uebertragen
dhcp-option=tag:rpi,43,Raspberry Pi Boot

# TFTP-Server aktivieren
enable-tftp
tftp-root=/srv/tftp
tftp-secure

dnsmasq neu starten:

sudo systemctl restart dnsmasq

3. TFTP-Dateien & Golden-Master NFS-Root bereitstellen

Schritt 1: Ordnerstruktur erstellen

Wir strukturieren die TFTP-Verzeichnisse nach Client-Namen bzw. MAC-Adressen, damit jeder Knoten bei Bedarf individuelle Device-Tree-Dateien erhalten kann:

sudo mkdir -p /srv/tftp/client-node01
sudo mkdir -p /srv/nfs/rpi-root-golden

Schritt 2: Root-Dateisystem einspielen

Ein sauberes Raspberry Pi OS 64-Bit Lite Image in das NFS-Verzeichnis entpacken:

# Loop-Device fuer Original-Image erstellen
LOOP_DEV=$(sudo losetup -fP --show 2024-10-22-raspios-bookworm-arm64-lite.img)

# Boot-Dateien in den TFTP-Ordner kopieren
sudo mount "${LOOP_DEV}p1" /mnt
sudo cp -r /mnt/* /srv/tftp/client-node01/
sudo umount /mnt

# Gesamtes RootFS in den NFS-Ordner kopieren
sudo mount "${LOOP_DEV}p2" /mnt
sudo cp -a /mnt/* /srv/nfs/rpi-root-golden/
sudo umount /mnt
sudo losetup -d "$LOOP_DEV"

Schritt 3: NFS-Freigabe konfigurieren

Datei /etc/exports bearbeiten:

sudo nano /etc/exports

Freigabe eintragen (wichtig: no_root_squash, damit der Client-Kernel Systemdienste als Root ausführen kann):

/srv/nfs/rpi-root-golden 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)

Freigaben neu laden:

sudo exportfs -rav

4. Boot-Parameter & Dateisystemtabellen anpassen

Dem Raspberry Pi muss mitgeteilt werden, dass das Root-Dateisystem nicht auf einer lokalen Partition, sondern im Netzwerk liegt.

Schritt 1: cmdline.txt im TFTP-Verzeichnis anpassen

Datei /srv/tftp/client-node01/cmdline.txt bearbeiten:

sudo nano /srv/tftp/client-node01/cmdline.txt

Den gesamten Dateiinhalt durch diese einzelne, ununterbrochene Zeile ersetzen:

console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=192.168.10.10:/srv/nfs/rpi-root-golden,vers=4,tcp rw ip=dhcp rootwait elevator=deadline
  • root=/dev/nfs: Weist den Kernel an, das RootFS über NFS zu mounten.
  • nfsroot=192.168.10.10:...: IP des zentralen NFS-Servers und Exportpfad.
  • vers=4,tcp: Erzwingt modernes, zuverlässiges NFSv4 über TCP.
  • ip=dhcp: Hält die IP-Adresse während des Boot-Übergangs stabil.

Schritt 2: Lokale Datenträger aus /etc/fstab entfernen

Auf dem NFS-Root-Dateisystem alle physischen SD-/NVMe-Partitionen aus /etc/fstab löschen:

sudo nano /srv/nfs/rpi-root-golden/etc/fstab

Nur virtuelle Dateisysteme behalten:

proc            /proc           proc    defaults          0       0
tmpfs           /tmp            tmpfs   defaults          0       0
tmpfs           /var/tmp        tmpfs   defaults          0       0
tmpfs           /var/log        tmpfs   defaults          0       0

5. Client-EEPROM für Netzwerk-Boot konfigurieren

Um den Netzwerk-Boot auf der Hardware zu aktivieren, konfigurieren wir das SPI-EEPROM des Raspberry Pi.

Eine temporäre SD-Karte einlegen, booten und die aktuelle Boot-Reihenfolge abfragen:

rpi-eeprom-config

Das Register BOOT_ORDER bestimmt die Boot-Priorität (von rechts nach links): - 1 = SD-Karte - 2 = Netzwerk PXE-Boot - 4 = USB-Speicher - 6 = NVMe-SSD (PCIe) - f = Schleife von vorne beginnen

Um Netzwerk-Boot an erste Stelle zu setzen und die SD-Karte als Notfall-Fallback zu behalten, setzen wir BOOT_ORDER=0xf21:

rpi-eeprom-config --extract custom-eeprom.conf
sed -i 's/^BOOT_ORDER=.*/BOOT_ORDER=0xf21/' custom-eeprom.conf
sudo rpi-eeprom-config --apply custom-eeprom.conf

Der erste festplattenlose Bootvorgang

  1. Raspberry Pi herunterfahren: sudo poweroff.
  2. Die MicroSD-Karte entnehmen und sämtliche USB-Sticks/NVMe-SSDs abziehen.
  3. Netzwerkkabel in den Gigabit-Switch einstecken.
  4. Stromversorgung einschalten.

Die Boot-Meldungen im Protokoll

Bootloader initialising...
BOOT_ORDER: 0xf21
Trying Bootloader: Network...
Link is UP, speed 1000 Mbps full duplex
DHCP request sent...
DHCP offer received: IP 192.168.10.85, TFTP Server: 192.168.10.10
TFTP: Loading bcm2712-rpi-5-b.dtb... OK
TFTP: Loading kernel8.img... OK
Kernel entry: 0x00080000
[    0.000000] Linux version 6.6.31+rpt-rpi-2712...
[    2.104921] eth0: Link is Up - 1Gbps/Full
[    3.498112] IP-Config: Complete:
[    3.498145]   device=eth0, addr=192.168.10.85, mask=255.255.255.0, gw=192.168.10.1
[    3.510928] VFS: Mounted root (nfs4 filesystem) on device 0:18.
[    4.103984] Welcome to Debian GNU/Linux 12 (bookworm)!

Nach rund 15 Sekunden kannst du dich per SSH auf dem vollständig datenträgerlosen Raspberry Pi einloggen!


6. Shared Golden Master mit RAM-Overlay für 20+ Knoten

Werden 20 Knoten aus demselben NFS-Verzeichnis gebootet, führen Dateikonflikte (wie identische SSH-Hostschlüssel oder Hostnamen) zu Netzwerkchaos.

Die professionelle Architektur nutzt einen unveränderlichen Golden Master mit individuellem RAM-Overlay:

%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
    NFS_GOLDEN["Zentraler NFS-Server (/srv/nfs):<br/>Strikt READ-ONLY gemountet (:ro)"]

    subgraph Node1["Diskless Node 01 (MAC: ...A1)"]
        direction TB
        OV1["OverlayFS: Transparente Sicht (/)"]
        RAM1["RAM tmpfs<br/>(Eigener Hostname & Keys)"]
        OV1 --- RAM1
    end

    subgraph Node2["Diskless Node 02 (MAC: ...B2)"]
        direction TB
        OV2["OverlayFS: Transparente Sicht (/)"]
        RAM2["RAM tmpfs<br/>(Eigener Hostname & Keys)"]
        OV2 --- RAM2
    end

    NFS_GOLDEN --> Node1
    Node1 --> Node2

Über ein schlankes initramfs-Skript wird das NFS-Wurzelverzeichnis als lowerdir (Read-Only) und ein flüchtiges tmpfs im RAM als upperdir verbunden. So lässt sich eine unbegrenzte Anzahl von Raspberry Pis aus einem einzigen 4-GB-Master-Image booten. Systemupdates werden einmalig zentral auf dem Server installiert – beim nächsten Neustart ist die gesamte Flotte aktualisiert!


Nächste Schritte

Damit beherrschst du Enterprise-Edge-Infrastrukturen auf höchstem Niveau! Vertiefe dein Wissen in den praxisorientierten Workshops: