
🌐 Auch auf: English · Français · Español
📦 Was als kurzes „Ich richte mal eben am Wochenende ein NAS ein“ gedacht war, wurde zu einer Woche voller Kaninchenbauten, Yak Shaving und einer unvernünftigen Menge an Git-Commits. Aber hey – das Homelab ist dadurch besser geworden, und alles ist jetzt automatisiert und dokumentiert. Wie immer liegt der komplette Ansible-Code hier:
👉 github.com/aptupgrademe/www_k3s
Bevor ich zum NAS und zu OpenZFS komme – dem eigentlichen Hauptprogramm –, kippe ich kurz die Nebenquests aus, die unterwegs passiert sind. Wer ungeduldig ist, springt direkt zum ZFS-Abschnitt. Ich verurteile niemanden.
🐿️ Nebenquests: alles, was nicht das NAS war
Du kennst das. Du fängst an, ein NAS zu konfigurieren, und drei Tage später reparierst du Grafana-Alert-Regeln und schreibst ein Betriebshandbuch auf Französisch. Das ist passiert:
🔒 Sicherheitsfixes (die „Moment, das war offen?!“-Edition)
- rpcbind lauschte auf Port 111 – öffentlich. NFS wird nirgends genutzt. Behoben. 😬
- rkhunter verschickte jeden Morgen „infected!“-Mails – weil SourceForge auf HTTPS-Redirects umgestellt hatte und
curlihnen nicht folgte.curl -Lergänzt. Außerdem läuftrkhunter --propupdjetzt automatisch nachdnf-automatic, damit nächtliche Sicherheitsupdates nicht wie Rootkits aussehen. - Grafana-Alert-Regeln hatten die Schwellwerte fest im PromQL eingebaut, was zu „condition must not be empty“-Fehlern führte, sobald die Metriken unter dem Schwellwert lagen. Schwellwerte in den Evaluator verschoben. Funktioniert jetzt tatsächlich.
- systemd-Härtung per Drop-ins ausgerollt:
sshdging beim Exposure-Score von 9,6 → 7,8,node_exporterundprometheusjeweils von 9,2 → 4,4. - Unnötige Dienste gestrichen:
rpcbind,gssproxy,sssd– keiner davon gebraucht, alle liefen.
⚡ Performance
- Autoptimize auf WordPress installiert: Die Zahl der JS/CSS-Tags fiel von 40 auf 6. Seitengröße um ca. 18 % kleiner.
- robots.txt lieferte 404. Yoast SEO erzeugt sie dynamisch per PHP, aber nginx behandelte sie als statische Datei. Eine
try_files-Direktive später – behoben. tcp_max_syn_backlogvon 512 auf 4096 angehoben, passend zusomaxconn.- Transparent Huge Pages von
alwaysaufmadviseumgestellt – der Standard verursacht Latenzspitzen in K3s-Pods, MariaDB und Redis.
🎨 Design & SEO
- Der Blog-Header hat ein Redesign bekommen: Das Superman-Logo sitzt jetzt rechts (gespiegelt, damit er nach innen schaut, statt aus der Seite zu fliegen), der Seitentitel links, dunkler Hintergrund passend zu den Navigationsleisten. Kleine Dinge, großer Unterschied.
- 165 Bilder hatten keinen Alt-Text. Behoben mit einem WP-CLI-Skript, das die Beschreibungen automatisch aus den Dateinamen ableitet. Das hat länger gedauert als das NAS-Setup.
- robots.txt zeigt Suchmaschinen jetzt ordentlich die von Yoast erzeugte Sitemap.
- „Home“ als ersten Eintrag ins Navigationsmenü aufgenommen. Wie man zurück zur Startseite kommt, war offenbar nicht offensichtlich. Ups.
📚 Dokumentation
Weil ich anscheinend lieber Doku schreibe, als gesund ist: Die Betriebshandbücher gibt es jetzt auf Deutsch, Englisch und Französisch für WordPress, Nextcloud und das neue NAS. Ja, Französisch. Im Ordner docs/ im Repo liegen alle sechs HTML-Dateien.
🗄️ Das Hauptprogramm: OpenZFS-NAS auf Debian 13
Gut. Das, was ich eigentlich vorhatte.
Warum ZFS? Ein kurzer Rückblick
ZFS wurde ursprünglich von Sun Microsystems entwickelt und kam 2005 erstmals mit Solaris 10 heraus. Der Name stand für „Zettabyte File System“ – Bescheidenheit war nicht Suns Ding. Es wurde von Grund auf neu entworfen, um Probleme zu lösen, die klassische UNIX-Dateisysteme seit Jahrzehnten übertüncht hatten: stille Datenkorruption, inkonsistente Zustände nach Abstürzen und der allgemeine Horror von fsck auf großen Volumes.
Als Oracle 2010 Sun übernahm, spaltete sich die Open-Source-Entwicklung von ZFS als OpenZFS ab – heute das aktiv gepflegte Community-Projekt, das unter Linux, FreeBSD, macOS und anderen läuft. Das ist es, was wir verwenden.
Eine Sache habe ich lange angenommen: ZFS sei ein FreeBSD-Ding. Stimmt so nicht ganz. OpenZFS ist in den Repos von Debian 13 enthalten und lässt sich sauber installieren. Ich setze es zum ersten Mal ein, habe also noch keine Zahlen aus der Praxis. Meine Vermutung: Der reine Durchsatz könnte etwas niedriger sein als bei einem getunten ext4/mdadm-Setup – aber Prüfsummen, Erkennung stiller Korruption und Snapshots machen die Daten deutlich sicherer. Mal sehen, wie es sich schlägt. 🧪
✅ Was ZFS großartig macht
- End-to-End-Prüfsummen – jeder Block bekommt beim Schreiben eine Prüfsumme, die beim Lesen verifiziert wird. Stille Korruption („Bit Rot“) wird erkannt und in einem redundanten Pool automatisch repariert.
- Copy-on-Write (CoW) – Daten werden nie an Ort und Stelle überschrieben. Dadurch sind Snapshots praktisch gratis, und das Write-Hole-Problem von RAID 5 entfällt.
- Snapshots – zeitpunktgenaue Kopien eines Datasets, sofort erstellt und platzsparend gespeichert. Rollback in Sekunden.
- Eingebautes RAID (RAIDZ) – kein separater RAID-Controller, keine stille Metadaten-Korruption. RAIDZ1/2/3 sind ZFS-nativ.
- Kompression – transparent, pro Dataset.
zstdspart bei Dokumenten und Backups 30–50 % Platz bei vernachlässigbarer CPU-Last. - ARC-Cache – ZFS verwaltet seinen eigenen adaptiven Lesecache im RAM. Mehr RAM = schnellere Lesezugriffe.
- Gepoolter Speicher – alle Datasets teilen sich den Platz des Pools dynamisch. Schluss mit dem Zurechtschneiden fester Partitionen.
⚠️ Die Kehrseiten
- RAM-hungrig – der ARC ist gierig. Ein echtes NAS will 16–32 GB.
- RAIDZ lässt sich nicht einfach vergrößern – man kann nicht einfach eine Platte zu einem bestehenden RAIDZ-vdev hinzufügen. ZFS 2.2+ hat eine Erweiterung eingeführt, aber sofort geht das immer noch nicht.
- ECC-RAM dringend empfohlen – ZFS vertraut dem RAM. Kippt im RAM unbemerkt ein Bit vor dem Schreiben, versieht ZFS die Korruption mit einer gültigen Prüfsumme. ECC verhindert das.
- Lernkurve – Pools, vdevs, Datasets, Properties. Ein anderes Denkmodell als bei klassischen Dateisystemen. Lohnt sich, aber ein Wochenende steckt da drin.
🏗️ Das eigentliche Setup
Vorher lief auf denselben drei SSDs ein klassisches Linux-Software-RAID5 (md) mit ext4 obendrauf. Hat funktioniert, bot aber keine der Integritätsgarantien, Snapshots oder Kompression von ZFS. Zeit für ein Upgrade.
Die Hardware ist ein HP MicroServer Gen10 Plus V2 – Intel Xeon E-2314, 31 GB RAM. Speicheraufteilung:
sdb(465-GB-SSD) → Debian 13 als Betriebssystemsda+sdc+sdd(3× 1,8 TB WD Red SA500 SSD) → ZFS RAIDZ1sde(1,8-TB-HDD von Toshiba) →/mnt/usbals externes Backup
Die Ansible-Rolle legt den Pool so an:
zpool create -f
-o ashift=12 # 4K sector alignment for modern SSDs
-o autotrim=on # TRIM commands for SSD health
-O compression=zstd # transparent compression
-O atime=off # no access-time writes on reads
-O xattr=sa # Samba xattrs in inodes (faster)
-O recordsize=128k # overridden to 1M per dataset
-O mountpoint=/raid5
data raidz /dev/disk/by-id/ata-WD_Red_SA500_...
📁 Samba – Single Source of Truth
Die zentrale Designentscheidung: Die Samba-Share-Definitionen in vars.yml steuern alles. Die Ansible-Rolle läuft in einer Schleife über sie, legt ZFS-Datasets an, setzt die Besitzrechte und schreibt die smb.conf. Share an einer Stelle hinzufügen – der Rest folgt automatisch:
nas_samba_shares:
- name: shared
path: "{{ nas_zfs_mountpoint }}/shared"
valid_users: user3
force_user: user3
- name: user1
path: "{{ nas_zfs_mountpoint }}/user1"
valid_users: user3
force_user: user3
Samba läuft mit SMB3, Multi-Channel-Unterstützung und asynchronem I/O. Die ZFS-Property xattr=sa speichert erweiterte Windows-Attribute direkt im Inode statt in versteckten Punktdateien, was Metadaten spürbar schneller macht. 🎛️
🤖 Jenkins, GitLab & Pi-hole
Der MicroServer kann etwas mehr als nur Dateien ausliefern:
Jenkins (Port 8090) fährt zwei nächtliche Backup-Jobs – rsync-basierte Sicherungen zweier entfernter Nextcloud-Instanzen (instance-a und instance-b). Der SSH-Schlüssel für diese Verbindungen liegt verschlüsselt in Ansible Vault und wird bei jeder Neuinstallation nach /home/user3/.ssh/ zurückgespielt. Selbst eine komplette Neuinstallation des Betriebssystems bricht die Backup-Verbindung nicht.
GitLab CE 19.1 (Port 80) dient als lokaler Git-Server. Ein eigenes GitLab im Haus heißt: keine Abhängigkeit von externen Diensten für die Homelab-Projekte. Die Ansible-Rolle erledigt die komplette Nachinstallation über die GitLab-API: setzt das root-Passwort, legt einen Standardbenutzer an, erstellt eine Gruppe homelab und ein leeres Projekt www_k3s – alles idempotent.
Pi-hole v6 (Port 8000 für die Weboberfläche, Port 53 für DNS) blockt Werbung auf Netzwerkebene. Es läuft auf Port 8000 statt auf dem Standardport 80, weil dort schon GitLab wohnt. Als DNS-Upstream dienen 8.8.8.8/8.8.4.4.
Und weil es ein HP-Server ist: HPE AMSD (Agentless Management Service) wird als Erstes installiert – vor allem anderen. Ohne ihn bekommt der iLO-BMC keine Temperaturdaten vom Betriebssystem, und die Lüfter drehen auf Volllast. Laut. Sehr laut.
All das – NAS und Internet-Server gleichermaßen – ist nur einen ansible-playbook-Befehl von einem frischen Neuaufbau entfernt:
👉 github.com/aptupgrademe/www_k3s
Als Nächstes: hp1 tatsächlich neu installieren und das Playbook zum ersten Mal auf einem sauberen Debian 13 laufen lassen. Ich berichte, ob ZFS unter Linux hält, was der Hype verspricht. 🤞






