Vor ein paar Wochen bin ich auf einen – wie ich damals dachte – sehr speziellen Anwendungsfall gestoßen, als ich zahlreiche VMs in meinem Home-Lab auf Kubernetes migriert habe: das automatische Einbinden eines NFS-Volumes in eine Linux-Maschine oder einen Docker-Container.
Hintergrund war, dass ich den Backing Store von InfluxDB, MySQL und Grafana auf mein NAS auslagern wollte, statt ihn auf dem lokalen Dateisystem des jeweiligen Geräts liegen zu lassen. NFS setze ich in meinem Netzwerk recht häufig ein, um Dateien für mehrere Geräte freizugeben – wegen der Einfachheit und der breiten Geräteunterstützung.
Nachdem das Setup im Home-Lab lief, wurde mir klar, dass dieser Anwendungsfall doch nicht so einzigartig ist – schließlich kommt NFS weltweit massenhaft zum Einsatz. In einer Cloud-Umgebung lässt sich damit beispielsweise eine On-Premise-NFS-Freigabe einbinden, um Daten abzurufen, Prozessen Lese- oder Schreibzugriff auf eine NFS-Freigabe zu geben, Home-Verzeichnisse von Nutzern per NFS einzubinden – und vieles mehr.
Das Problem – und der Schlüssel zum funktionierenden Auto-Mounting
Zuerst ging ich den mir vertrauten Weg über fstab, das ich seit Jahrzehnten immer wieder verwende. Sehr schnell zeigte sich jedoch, dass die NFS-Freigabe nicht schnell genug eingebunden wurde, damit die Datenbank-Daemons sie rechtzeitig erkennen konnten – und das verursachte erhebliche Probleme.
Dann bin ich auf das Linux-Paket autofs gestoßen. Bis es lief, war einiges an Herumprobieren nötig, denn viele Anleitungen im Netz waren veraltet oder ließen wichtige Details aus. Diese Anleitung zeigt Ihnen direkt, wie es geht, damit Sie nicht selbst einen halben Tag damit verbringen müssen – Zeit haben wir in der Branche schließlich nie genug.
Im Kern ist autofs ein Daemon, der Freigaben bei Bedarf im Hintergrund automatisch ein- und wieder aushängt. Anders als bei fstab geschieht das auf Anforderung, sodass es schon beim Booten funktioniert, ohne dass die Startreihenfolge der Daemons eine Rolle spielt.
Voraussetzungen
Der Einfachheit halber gehe ich in dieser Anleitung davon aus, dass Sie bereits einen NFS-Server auf Ihrem NAS oder einer Linux-Maschine eingerichtet haben oder etwas wie Google Clouds Filestore als NAS nutzen.
Stellen Sie sicher, dass Ihnen für jede einzubindende Freigabe der vollständige NFS-Pfad vorliegt. Manchmal sehen die Pfade anders aus als erwartet – also lieber zweimal prüfen. Bei Synology-NAS-Geräten ist beispielsweise der Volume-Name vorangestellt, etwa /volume1/share_path.
Außerdem halte ich die Befehle distributionsspezifisch für Debian-Derivate – sie funktionieren also mit Debian, Ubuntu, Kali usw. In jedem Abschnitt ergänze ich zusätzlich den passenden Befehl für Red-Hat-Derivate, sodass Sie unter RHEL oder CentOS nichts übersetzen müssen.
Bitte beachten Sie: NFS-Sicherheitspraktiken behandle ich in dieser Anleitung nicht, denn das ist ein sehr umfangreiches Thema. Es würde eine Komplexitätsebene hinzufügen, die diese Anleitung gut und gerne doppelt so lang machen könnte – deshalb lasse ich es weg. Verstehen Sie mich nicht falsch, das Thema IST sehr wichtig, aber ich behandle es in diesem Artikel nicht und empfehle Ihnen, sich einzulesen und es nach der Grundeinrichtung passend zu Ihrer Organisation zu integrieren. Wer mehr erfahren möchte, dem empfehle ich als Einstieg diesen ausgezeichneten Artikel von Red Hat zu den Grundlagen.
Das Vorgehen
Installieren Sie das autofs-Paket mit dem zu Ihrer Distribution passenden Befehl:
Ubuntu:
sudo apt -y install nfs-common autofsRed Hat:sudo yum -y install nfs-common autofsÖffnen Sie die Datei
/etc/auto.masterin Ihrem bevorzugten Editor.Scrollen Sie ans Dateiende und fügen Sie für jede Einbindung eine Zeile wie diese hinzu, wobei Sie das Wort
shareinauto.sharedurch Ihren Wunschnamen für die Freigabe ersetzen:/- /etc/auto.share -nosuid,noowners(Wenn Sie möchten, fügen Sie für eine bessere Lesbarkeit zusätzliche Leerzeichen ein – Medium erlaubt in Codeblöcken innerhalb nummerierter Listen leider nur ein einzelnes Leerzeichen.)Als Nächstes legen Sie jede der im vorherigen Schritt referenzierten Dateien an. Sie liegen alle in
/etcund folgen dem Formatauto.[share_name]. Für jede oben hinzugefügteauto.share-Zeile öffnen Sie die entsprechende Datei in Ihrem Texteditor, um sie zu erstellen. Tragen Sie dort folgende Zeile ein und ersetzen Sie Freigabenamen (mein persönlicher Favorit ist es, alles unter /mnt zu halten – das können Sie aber nach Belieben anpassen), Servernamen und Freigabepfad:/mnt/[share_name] -fstyle=nfs,user,nolock,nosuid,rw [server_name]:[share_path](Auch hier gilt: Bei Bedarf zusätzliche Leerzeichen für die Lesbarkeit. Wenn Sie nur Lesezugriff statt Lese-/Schreibzugriff wünschen, ändern Sie oben rw in ro.)Sobald das erledigt ist, starten Sie den autofs-Dienst mit folgendem Befehl neu:
Ubuntu:
sudo service autofs restartRed Hat:
sudo systemctl restart autofsAnschließend prüfen Sie, ob der Dienst korrekt gestartet ist und beim Start keine Syntax-, Netzwerk- oder sonstigen Fehler aufgetreten sind. Mit folgendem Befehl sehen Sie den Status:
Ubuntu:
sudo service autofs statusRed Hat:
sudo systemctl status autofsIn der Ausgabe des vorherigen Schritts sollte stehen, dass der Status "running" ist und alles in Ordnung. Falls nicht, zeigt die Ausgabe die letzten Logzeilen, mit denen Sie das Problem eingrenzen können. Am Ende habe ich zudem einen Abschnitt mit grundlegenden Debugging-Schritten ergänzt.
Jetzt können Sie mit dem
cd-Befehl in die oben in den Dateien hinterlegten Verzeichnisse wechseln, um auf die Freigaben zuzugreifen. Beachten Sie: Diese Verzeichnisse müssen Sie nicht selbst anlegen – der autofs-Daemon erstellt sie automatisch.Eine letzte Verifizierung: Mit dem Befehl
mountlassen sich alle Mounts der Instanz auflisten. Eine einfache Möglichkeit, alle von autofs erzeugten Mounts herauszufiltern, istmount | grep autofs.Ab jetzt werden die Mounts automatisch geladen und bei Bedarf wieder eingebunden.
An diesem Punkt empfehle ich dringend, sich mit NFS-Sicherheit zu befassen, Ihre Mounts abzusichern und anschließend die für Ihren Einsatzzweck am besten geeignete Sicherheitsmethode umzusetzen.
Debugging gängiger Probleme
Bei der Einarbeitung bin ich auf einige Stolpersteine gestoßen, die ich hier samt Lösungsweg auflisten möchte.
Das erste Problem: Der Daemon warf jede Menge Fehler, weil keine Verbindung zu NFS möglich sei. Es stellte sich heraus, dass Synology die Volume-Nummer dem Freigabenamen voranstellt – das war mir damals nicht bewusst. Diagnostiziert habe ich das, indem ich versucht habe, die NFS-Freigabe manuell in einen Ordner in meinem Home-Verzeichnis einzubinden, und zwar mit folgendem Befehl: mkdir tmp_mnt && sudo mount -v -r -o user,nolock,nosuid [server_name]:[share_path] tmp_mnt. Das bindet die Freigabe in ein lokales Verzeichnis ein und liefert entweder eine Erfolgsmeldung oder einen Fehler, der genau beschreibt, was schiefläuft. Zum Aushängen verwenden Sie sudo umount tmp_mnt.
Ein weiterer Fehler war, dass der Server nicht über seinen Hostnamen erreichbar war. Das entpuppte sich als internes DNS-Problem – der Hostname wurde nicht aufgelöst. Diagnostiziert habe ich das, indem die Freigabe per IP-Adresse erreichbar war und ich anschließend mit nslookup hostname festgestellt habe, dass die Auflösung von IP zu Hostname fehlschlug. Hinweis: Gegebenenfalls müssen Sie die Pakete bind-utils (Red Hat: sudo yum -y install bind-utils) bzw. dnsutils (Debian: sudo apt install -y dnsutils) installieren.
Das letzte Problem ist Kubernetes-spezifisch. Aus einem Pod im Cluster konnte ich keine externen Dienste – einschließlich NFS-Freigaben – erreichen, die außerhalb des Clusters lagen. Der Grund: Der Hostname ließ sich per DNS nicht auflösen, weil der Cluster meinen internen DNS-Server außerhalb des Clusters nicht kannte. Die Theorie dahinter sprengt den Rahmen dieser Anleitung – deshalb beschränke ich mich auf die Lösung und einen weiterführenden Link.
- Bearbeiten Sie die CoreDNS-ConfigMap mit folgendem Befehl:
kubectl edit configmap coredns -n kube-system. - Es öffnet sich ein Editor mit der YAML-Datei für CoreDNS. Darin finden Sie einen Abschnitt namens Corefile mit einem YAML-Block, der mit
.:53beginnt. - Ermitteln Sie Ihre interne Domain. Diese richtet sich danach, wofür Ihr interner DNS-Server konfiguriert ist. Falls Sie keinen internen DNS-Server haben, verwenden Sie einfach
local. - Ermitteln Sie die IP-Adresse Ihres DNS-Servers. Falls Sie keinen haben, ist das mit hoher Wahrscheinlichkeit die IP-Adresse Ihres Routers.
- Fügen Sie den folgenden Codeblock – mit Ihren Werten ersetzt – darunter in einer neuen Zeile ein (achten Sie auf Leerzeichen, keine Tabs!), speichern und schließen Sie den Editor:
[domain_name]:53 {
errors
cache 30
forward . [dns_server]
}
Weitere Informationen, warum das funktioniert, finden Sie hier.