Read-Only RootFS & Stromausfallsicherheit
In industriellen Umgebungen und IoT-Installationen werden Einplatinencomputer häufig an Orten betrieben, an denen ein sauberes Herunterfahren über sudo poweroff in der Praxis nicht stattfindet. Gabelstapler trennen Batterieladestationen, Sicherungen im Schaltschrank lösen aus oder Techniker ziehen ohne Vorwarnung den Netzstecker.
Auf einem standardmäßig beschreibbaren Linux-System führen abrupte Stromausfälle während laufender Schreibvorgänge zu unvollständigen Journal-Einträgen im ext4-Dateisystem, zerstörten Superblöcken und Inkonsistenzen im Flash Translation Layer (FTL) der Speicherkarte. Binnen weniger Wochen schlägt der Bootvorgang fehl, das System bootet nur noch in eine Notfall-Shell oder die SD-Karte ist physisch unbrauchbar.
Indem Raspberry Pi OS mithilfe von OverlayFS und tmpfs in eine zustandslose Read-Only-Appliance verwandelt wird, finden im laufenden Betrieb keinerlei Schreibzugriffe auf das Speichermedium statt. Das System wird damit zu 100 % immun gegen plötzliche Stromausfälle.
1. Schadensmechanik: Warum Stromausfälle Flash-Speicher zerstören
Um die Notwendigkeit eines unveränderlichen Dateisystems zu verstehen, lohnt sich ein Blick auf die physikalischen Vorgänge im Flash-Speicher bei plötzlichem Spannungsverlust:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph Danger["Klassisches beschreibbares OS (Gefaehrdet)"]
direction TB
W1["Anwendung schreibt Daten"] --> W2["Page Cache (RAM)"]
W2 -->|Verzoegerter Flush| W3["ext4 Dateisystem-Journal"]
W3 -->|NAND-Schreibzyklus| W4["Speichermedium (SD/NVMe)"]
POWER1["Ploetzlicher Stromausfall!"] -.->|Unterbricht Schreibzyklus| W4
W4 ==> CORRUPT["Beschaedigter Superblock /<br/>Dateisystem defekt"]
end
subgraph Safe["OverlayFS-Architektur (Ausfallsicher)"]
direction TB
RO_BASE["Unterste Ebene (Flash):<br/>Strikter READ-ONLY Mount"]
RAM_UPPER["Oberste Ebene (tmpfs im RAM):<br/>Alle dynamischen Daten"]
OVERLAY["Vereinte Sicht (/):<br/>Transparent fuer systemd & Apps"]
RO_BASE --> OVERLAY
RAM_UPPER --> OVERLAY
POWER2["Stromausfall zu jedem Zeitpunkt!"] -.-> RAM_UPPER
RAM_UPPER ==> SAFE_REBOOT["RAM leert sich sofort.<br/>Flash unberuehrt, sauberer Boot!"]
end
Danger -->|"Haertungsmethode: OverlayFS"| Safe
Die Physik des NAND-Flash-Speichers: Löschblöcke & Verschleiß
Flash-Speicher kann einzelne Speicherzellen nicht direkt überschreiben. Der interne Controller muss stets einen gesamten Löschblock (typischerweise 128 KB bis 4 MB) leeren, bevor neue 4-KB-Seiten programmiert werden können. Bricht die Versorgungsspannung genau in dem Moment ein, in dem die interne Ladungspumpe des Flash-Controllers aktiv ist: 1. Verbleiben Speicherzellen in einem undefinierten Zwischenladungszustand (Partial Write). 2. Geht die Zuordnungstabelle (Flash Translation Layer, FTL) im RAM des Speicherkontrollers verloren. 3. Erkennt der Speichercontroller beim nächsten Start inkonsistente Blockprüfsummen – die Partitionstabelle ist beschädigt oder das gesamte Medium sperrt sich irreversibel im Nur-Lese-Modus.
2. Die Linux-OverlayFS-Architektur
OverlayFS ist ein moderner Union-Mount-Dateisystemtreiber des Linux-Kernels. Er legt zwei verschiedene Verzeichnisse transparent übereinander:
- Untere Schicht (
lowerdir): Das physische Betriebssystem auf der SD-Karte oder NVMe-SSD. Es wird strikt im Read-Only (ro)-Modus gemountet. Physische Schreibvorgänge auf diesen Datenträger sind vom Kernel blockiert. - Obere Schicht (
upperdir): Ein flüchtiges Dateisystem, das ausschließlich im Arbeitsspeicher (tmpfs) liegt. - Zusammengeführte Sicht (
merged): Das Wurzeldateisystem (/), das Anwendungen und Dienste sehen.
Modifiziert ein Prozess eine Datei (z. B. Konfiguration in /etc/ oder Installation von Paketen), kopiert der Kernel die Originaldatei in den RAM-Bereich (Copy-on-Write - CoW). Auf dem physischen Festspeicher verändert sich kein einziges Bit. Bei einem Stromausfall verflüchtigt sich der RAM-Inhalt sofort, und beim Neustart startet das System garantiert im ursprünglichen, fehlerfreien Zustand.
3. Umsetzung A: Das native raspi-config Overlay
Für kompakte Edge-Geräte stellt Raspberry Pi OS ein kernelintegriertes OverlayFS-Feature bereit, das direkt per raspi-config aktiviert werden kann.
Schritt 1: System vorbereiten und bereinigen
Vor der Aktivierung sollten temporäre Altlasten und Swap-Dateien bereinigt werden, um unnötigen RAM-Verbrauch zu verhindern:
# Pakete aktualisieren und Paket-Cache leeren
sudo apt update && sudo apt autoremove -y
sudo apt clean
# Swap-Speicher dauerhaft deaktivieren (OverlayFS operiert im RAM)
sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo systemctl disable dphys-swapfile
Schritt 2: OverlayFS aktivieren
Befehl im non-interactive Modus ausführen:
# OverlayFS fuer das Root-Dateisystem aktivieren
sudo raspi-config nonint enable_overlayfs
# Optional auch /boot/firmware schreibschuetzen
sudo raspi-config nonint enable_bootro
System neu starten:
Schritt 3: Schreibschutz überprüfen
Nach dem Wiederverbinden per SSH den Root-Mount prüfen:
Erwartete Ausgabe:
Test auf Stromausfallsicherheit: Datei anlegen und harten Kernel-Absturz simulieren:
# Test-Datei erzeugen
touch ~/stromausfall_test.txt
ls -l ~/stromausfall_test.txt
# Sofortigen, unvorbereiteten Kernel-Neustart erzwingen (entspricht Stecker ziehen)
echo b | sudo tee /proc/sysrq-trigger
Nach dem erneuten Booten das Verzeichnis prüfen:
ls -l ~/stromausfall_test.txt
# Ausgabe: ls: Zugriff auf '...' nicht moeglich: Datei oder Verzeichnis nicht gefunden
Die Datei ist spurlos verschwunden, und der Datenträger hat keinerlei Schäden davongetragen!
4. Umsetzung B: Manuelle tmpfs-Umleitungen in /etc/fstab
Benötigt eine Anwendung gezielte Lese-/Schreibrechte in bestimmten Pfaden, können temporäre Verzeichnisse auch gezielt in /etc/fstab als tmpfs ausgelagert werden.
Datei /etc/fstab bearbeiten:
Folgende Mount-Punkte für flüchtige Daten im RAM ergänzen:
# Temporaere Verzeichnisse im RAM anlegen
tmpfs /tmp tmpfs nodev,nosuid,size=128M 0 0
tmpfs /var/tmp tmpfs nodev,nosuid,size=64M 0 0
tmpfs /var/log tmpfs nodev,nosuid,size=64M 0 0
tmpfs /var/run tmpfs nodev,nosuid,size=32M 0 0
Systemd Journal auf RAM umstellen
Standardmäßig schreibt systemd-journald Logs auf die Festplatte. Stelle den Dienst so ein, dass er Protokolle nur im RAM vorhält:
Eintrag anpassen:
Dienst neu starten:
5. Wartung im Read-Only-Modus: Updates sicher einspielen
Ein häufiges Hindernis bei schreibgeschützten Systemen ist die Wartung: Wie lassen sich Updates einspielen, ohne das System neu aufzusetzen?
Der ro / rw Wartungs-Workflow
Über zwei kurze Hilfsskripte lässt sich das System kontrolliert zwischen Wartungsmodus und Schutzmodus umschalten.
Skripte /usr/local/bin/ro und /usr/local/bin/rw anlegen:
#!/usr/bin/env bash
set -euo pipefail
echo "[*] Deaktiviere OverlayFS fuer Wartungsarbeiten..."
sudo raspi-config nonint disable_overlayfs
sudo raspi-config nonint disable_bootro
echo "[+] Wartungsmodus aktiv. Starte neu in beschreibbaren Modus..."
sudo reboot
#!/usr/bin/env bash
set -euo pipefail
echo "[*] Aktiviere OverlayFS Schutzmodus..."
sudo raspi-config nonint enable_overlayfs
sudo raspi-config nonint enable_bootro
echo "[+] System gehaertet. Starte neu in unzerstoerbaren Read-Only Modus..."
sudo reboot
Skripte ausführbar machen:
Ablauf für Updates:
- Per SSH einloggen und
rwausführen (System startet beschreibbar neu). - Updates durchführen:
sudo apt update && sudo apt upgrade -yoder Konfigurationen editieren. - Änderungen testen.
roausführen (System startet geschützt als Read-Only-Appliance neu).
6. Architektur-Muster: Getrennte Datenpartition
Die meisten Industrie-Anwendungen müssen ausgewählte Daten dauerhaft über Stromausfälle hinweg speichern: TLS-Zertifikate, SQLite-Messwertdatenbanken oder Netzwerkkonfigurationen.
Hierfür wird das Split-Partition-Muster eingesetzt:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph Disk["Physischer Speicher (NVMe / eMMC / SD)"]
direction TB
P1["Partition 1: /boot/firmware<br/>(FAT32, Read-Only)"]
P2["Partition 2: RootFS /<br/>(ext4, OverlayFS RO + tmpfs)"]
P3["Partition 3: /data<br/>(ext4, Crash-Resistent RW)"]
end
subgraph System["Laufzeitumgebung"]
direction TB
OS["Betriebssystem & Programme<br/>(/usr, /bin)"]
LOGS["System-Logs<br/>(/var/log -> RAM tmpfs)"]
DB["SQLite Zeitreihen-Datenbank<br/>(/data/telemetrie.db)"]
end
Disk --> System
P2 --> OS
P3 --> DB
P2 -.-> LOGS
Robuste Datenpartition einrichten
Partition 3 mit ext4 und maximal robuster Journal-Konfiguration formatieren:
Eintrag in /etc/fstab:
# Robuste Datenpartition fuer Messwerte und Konfiguration
PARTUUID=deine-uuid-03 /data ext4 noatime,data=journal,commit=1,barrier=1,errors=remount-ro 0 2
data=journal: Metadaten und Nutzdaten werden zwingend vor dem Schreiben ins Dateisystem im Journal protokolliert. Verhindert unvollständig geschriebene Dateien bei plötzlichem Stromausfall.commit=1: Schreibt das Journal im Sekundentakt auf den Flash-Speicher (Standard: alle 5 Sekunden).errors=remount-ro: Schaltet die Partition bei einem erkannten Fehler sofort auf schreibgeschützt, um weitere Schäden zu verhindern.
Nächste Schritte
Nachdem das Dateisystem vor Hardware-Stromausfällen geschützt ist, sorgen wir für Ausfallsicherheit bei Software-Hängern:
- Hardware-Watchdog & Autonome Wiederherstellung: Konfiguriere den Broadcom Hardware-Timer, um das System bei Kernel-Panics automatisch neu zu starten.
- Edge-Containerisierung & K3s-Clustering: Verwalte containerisierte Workloads deklarativ auf gehärteten Edge-Nodes.