Ideen - Werkstatt - Projekte - Basteln - Hausbau

Bau eines MP3-Players mit Grafik-LCD

Diskless Clients

PC ohne Festplatte als Mp3player

Fast alle PCs können per Netzwerk booten. Diese Webseite beschreibt, wie Linux per Netzwerk gebootet werden kann.

Vorteile

  • PC nicht mehr hörbar. Dies reduziert die Geräuschentwicklung praktisch auf Null, wenn zusätzlich Prozessor und Netzteil passiv gekühlt werden.
  • Geringerer Stromverbrauch. Der Rechner verbraucht ohne Festplatte ca. 10 Watt weniger Strom. Dieses Argument gilt jedoch nicht, wenn stattdessen ein zusätzlicher Rechner laufen muss, auf dem das Root-Dateisystem liegt. Eine Notebookfestplatte an Stelle einer 3,5 Zoll Desktop-Platte reduziert den Stromverbrauch übrigens in fast gleicher Weise.
  • Mehrere Clients mit nur einer Installation. Wenn man mehrere (Festplatten-lose) Rechner in seinem Netzwerk betreiben möchte, muss die Installation nur einmal vorgenommen werden. Jeder Rechner kann mit dem gleichen Dateisystem/Kernel arbeiten.

Nachteile

  • Ein ständig laufender PC ist notwendig, der das Betriebssystem bereit hält. Dieser kann aber im Keller seinen Dienst verrichten und noch viele andere nützliche Aufgaben (z.B. Backup) erledigen.
  • Der Rechner bootet deutlich länger. Das Starten von Programmen im laufenden Betrieb dauert ebenfalls etwas länger, ist aber (meiner Meinung nach) noch tolerierbar, wenn die Verbindung zum Server mindestens 100 MBit erreicht.

Funktionsweise

Die folgende Liste beschreibt den Ablauf während des Bootens per Netzwerk. Der Rechner ohne Festplatte wird als Client bezeichnet, der Rechner, der das zu bootende Betriebssystem bereithält, als Server:
  • Netzwerkanschluss konfigurieren. Das Bios des Clients fordert per DHCP eine IP-Adresse mit "Zubehör" an. Der entsprechend konfigurierte Server antwortet und weist dem Client, entsprechend seiner MAC-Adresse, eine IP-Adresse zu. Zusätzlich erhält der Client die Adresse des Rechners, von dem er seinen Bootloader, den Kernel und gegebenenfalls die Init-Ramdisk erhält. In unserem Fall ist dies ebenfalls der Server.
  • Der Client fordert per TFTP den Bootloader, Kernel und Init-Ramdisk an. Der Kernel wird entpackt und gestartet.
  • Der Kernel muss das Root-Dateisystem per NFS mounten. Mittels NFS kann auf ein Verzeichnis auf einem entfernten Rechner so zugegriffen werden, als ob das Verzeichnis auf der lokalen Festplatte liegen würde.
    Zuvor muss der Kernel jedoch die Netzwerkkarte einrichten, d.h. den entsprechenden Treiber laden und IP-Adresse etc. konfigurieren.
  • Ab hier verläuft das Booten wie mit einer lokalen Festplatte. Es werden die Init-Skripte ausgeführt und evtl. X-Windows gestartet.

Schritt für Schritt Anleitung

Der folgende Abschnitt beschreibt die Installation Schritt für Schritt. Um die Beschreibung anschaulicher zu machen (und um Fehler meinerseits zu vermeiden), beschreibe ich die Installation so, wie ich sie bei mir vorgenommen habe. Wenn Änderungen an Konfigurationsdateien notwendig sind, ist dies erwähnt, die entsprechenden Stellen sind deutlich markiert.

Ausgangssituation bei mir war die folgende: In der Scheune, die unmittelbar an unser Haus anschließt, war bereits unser "Home-Server" installiert, basierend auf einem stromsparenden Via Epia 5000 Mainboard. Der Mp3-Player im Wohnzimmer lief mit eigener Festplatte. Auf beiden Systemen befand sich SuSE Linux 9.3. Nun sollte also das Betriebssystem des Mp3players vom Server bereit gehalten werden, so dass der Mp3player ohne Festplatte auskommt. Die Musikdateien liegen dann ebenfalls auf dem Server.

Um das Verständnis der abgedruckten Beispiel-Konfigurationsdateien zu erleichtern:
Bei mir ist der Server mit der IP-Adresse 192.168.0.100 und der Client mit 192.168.0.10 konfiguriert. Diese Einstellungen müssen unbedingt dem eigenen Netz angepasst werden! Ich führe sie hier lediglich des besseren Verständnisses wegen im Klartext auf!
  1. Zuerst wird das bereits auf der lokalen Festplatte des Clients installierte Root-Dateisystem in ein Verzeichnis auf dem Server kopiert (hier: /data/pxeroot). Das Verzeichnis /proc muss nicht kopiert werden, es reicht aus, ein leeres Verzeichnis auf dem Server anzulegen. Alternativ kann das Client-System direkt in ein Verzeichnis auf dem Server installiert werden, z.B. mittels Yast.

  2. Für die hier vorgestellte Methode muss der Linux-Kernel mit den folgenden Optionen kompiliert worden sein:
    Networking/Networking options/TCP/IP networking/IP: Kernel level autoconfiguration
    Networking/Networking options/TCP/IP networking/IP: Kernel level autoconfiguration/IP: DHCP support
    File Systems/Network File Systems/NFS file system support
    File Systems/Network File Systems/Root file system on NFS

    Ist er das nicht, so muss er neu kompiliert werden. In Kürze:
    1. Die Pakete "kernel-source" und "qt3-devel" installieren. Dies sollte auf dem Server geschehen, um die Installation der Kernel-Module (siehe Punkt 9.) zu erleichtern.
    2. cd /usr/src/linux
      Dieses Verzeichnis enthält die Kernel-Quellen.
    3. su
      Bei SuSE 9.3 muss man Super-User sein, um den Kernel konfigurieren zu können.
    4. make xconfig
      Dies erzeugt und startet das Programm zur Konfiguration des Kernels.
    5. Die oben erwähnten Optionen auswählen, Speichern und Config-Programm beenden
    6. make clean
    7. make bzImage
      Dies kompiliert den Kernel. Der neue Kernel befindet sich unter /usr/src/linux/arch/i386/boot/bzImage. Diese Datei muss in /tftboot auf dem Server kopiert werdern und im zugehörigen Config-File referenziert werden.
    8. make modules
      Dies kompiliert die Kernel-Module (Treiber).
    9. chroot /data/pxeroot make modules_install
      Nun müssen die neu kompilierten Kernel-Module installiert werden. Sie dürfen jedoch nicht in das momentan laufende Betriebssystem des Servers oder Clients kopiert werden, sondern in das Betriebssystem des Clients, welches sich unter /data/pxeroot auf dem Server befindet. Die Modul-Installation (normalerweise: "make modules_install") startet man dazu am besten mit den chroot Befehl auf dem Server(!), der ein beliebiges Verzeichnis als neues Root-Verzeichnis "/" benutzt.
    10. Wird eine Init-Ramdisk benötigt, so muss diese ebenfalls neu erstellt werden. Wird der Kernel ohnehin neu kompiliert, empfiehlt es sich aber, alle benötigten Treiber in den Kernel zu integrieren und auf die Init-Ramdisk zu verzichten.

    Eine ausführliche Anleitung zum Kernel-Kompilieren findet sich unter http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html.

  3. Das Verzeichnis /data/pxeroot muss per NFS freigegeben werden, d.h. der NFS-Server muss installiert und entsprechend konfiguriert sein. Die Freigabe erfolgt mit den Optionen rw,no_root_squash, mehr dazu im Abschnitt "Bemerkungen". Yast (Netzwerk-Dienste / NFS-Server) bietet dabei gleich an, den entsprechenden Port in der Firewall freizuschalten. Dies funktioniert jedoch nicht, da einige benötigte Ports zufällig ausgewählt werden. Ausweg: In der Konfigurationsdatei des NFS-Servers muss der Bereich, aus dem Ports ausgewählt werden, eingeschränkt werden. Anschließend müssen alle Ports in der Firewall geöffnet werden.

  4. Auf dem Server müssen folgende Programme installiert sein: dhcp-server, tft und syslinux. Außerdem muss sichergestellt sein, dass sich im Netzwerk (bzw. Sub-Netz) kein weiterer aktiver DHCP-Server, z.B. im Router für den Internetzugang, befindet.
    Der DHCP-Server vergibt IP-Adressen an alle oder bestimmte Rechner, die an das Netzwerk angeschlossen werden.
    Der TFTP-Server liefert dem Boot-Loader, den Kernel und die Init-Ramdisk an den Client aus. Ein "normaler" FTP-Server ist dazu nicht geeignet.
    Syslinux enthält den Bootloader (die Datei pxelinux.0), der per Netzwerk Kernel und Init-Ramdisk anfordert. Früher hieß dieses Paket "pxelinux", wobei PXE für "Preboot Execution Environment" steht; ein Verfahren, um einen netzwerkbasierten Bootvorgang zu ermöglichen.

  5. Die Konfiguration von DHCP befindet sich in der Datei /etc/dhcpd.conf. Sie sollte in etwa wie folgt aussehen:

    option domain-name "[domain]";
    option domain-name-servers [name server 1], [ip von name server 2];
    option routers 192.168.0.1;
    default-lease-time 14400;
    ddns-update-style none;
    subnet 192.168.0.0 netmask 255.255.255.0 {
    range 192.168.0.200 192.168.0.220;
    default-lease-time 14400;
    max-lease-time 172800;
    }

    host pxeclient {
    hardware ethernet 00:40:63:CB:AC:24;
    fixed-address 192.168.0.10;
    option host-name "pxeclient";

    filename "/pxelinux.0";
    next-server 192.168.0.100;
    }
    Achtung: Die fett und rot eingefärbten Angaben müssen unbedingt geändert bzw. angepasst werden!
    Ein Großteil dieser Einstellungen kann mit Yast vorgenommen werden (Netzwerk Dienste, DHCP Server). Die speziellen Einstellungen zum Booten per Netzwerk müssen jedoch nachträglich von Hand hinzugefügt werden:
    hardware ethernet ist die MAC- bzw. HW-Adresse des Clients. Sie wird z.B. mit dem Befehl ifconfig angezeigt (HWaddr). Mein Client zeigt sie auch beim Booten an, unmittelbar nach dem BIOS-Post.
    fixed-address ist die IP-Adresse, die dem Client zugewiesen werden soll.
    filename bezeichnet den Boot-Loader, der an den Client geschickt wird.
    next-server ist die IP-Adresse des TFTP-Servers, in unserem Fall die des Servers.

  6. Konfiguration des TFTP-Servers kann mit Yast erfolgen. In das root-Verzeichnis des TFTP-Servers (normalerweise /tftpboot) wird die Datei /usr/share/syslinux/pxelinux.0 kopiert, welche Teil des Syslinux-Pakets ist. In /tftpboot wird außerdem das Verzeichnis pxelinux.cfg erzeugt (mkdir pxelinux.cfg) welches die Konfigurationsdatei "default" für den Bootloader enthält. Das Format dieser Datei (/tftpboot/pxelinux.cfg/default) ähnelt den üblichen Boot-Loader-Konfigurationsdateien und sieht bei mir so aus:

    LABEL linux
       KERNEL bzImage-viaboot
       APPEND ip=dhcp root=192.168.0.100:/data/pxeroot initrd=initrd-suse9.3 ramdisk_size=8192
    Die fetten roten Felder sind wieder entsprechend anzupassen:
    KERNEL enthält den zu bootenden Kernel. Er muss sich im Root-Verzeichnis des tftp-Servers (/tftpboot) befinden.
    APPEND enthält die Parameter, die dem Kernel beim Start übergeben werden. Dies ist die Aufforderung, sein Netzwerk via DHCP zu konfigurieren id=dhcp, die Angabe, dass das Root-Verzeichnis via NFS zu mounten ist root=192.168.0.100:/data/pxeroot und eine Init-Ramdisk, falls externe Treiber benötigt werden. Die Init-Ramdisk (hier: initrd-suse9.3) muss sich ebenfalls im Root-Verzeichnis des tftp-Servers befinden.
    Im Internet wird über verschiedene Möglichkeiten berichtet, wie der Kernel veranlasst werden kann, sein Netzwerk zu konfigurieren und das Root-Dateisystem via NFS zu mounten. Bis auf die hier vorgestellte Methode hat bei mir jedoch nichts funktioniert, auch das in der Kernel-Dokumentation beschriebene Verfahren (von 1997!) nicht.

  7. Nun muss nur noch dem Bios des Clients mitgeteilt werden, dass per Netzwerk gebootet werden soll. Und dann heisst es: Einschalten und Daumen drücken!

Bemerkungen

Das Root-Dateisystem wird gemäß dieser Anleitung mit den Optionen rw,no_root_squash freigegeben, d.h. der Client darf in das Verzeichnis schreiben, und dies sogar als Root-User. Dies birgt ein gewisses Risiko in sich: Jeder PC, der das Verzeichnis mounten darf, darf es auch ändern oder löschen. Wenn ein unbefugtes mounten nicht verhindert werden kann, muss das Root-Dateisystem read-only, also ohne Schreibrechte gemountet werden. Dies erfordert jedoch einige spezielle Konfigurationen:

  • Sämtliche Dateien, die das System im laufenden Betrieb ändern muss, werden in einem separaten, beschreibbaren NFS Verzeichnis untergebracht. Im Root-Dateisystem, welches keine Schreibzugriffe zulässt, befinden sich an deren Stelle symbolische Links auf die entsprechenden Dateien im beschreibbaren Verzeichnis. Anleitung folgt.
  • Um die Anzahl editierbarer Dateien klein zu halten, kann der Syslog-Service umkonfiguriert werden. Normalerweise schreibt dieser Service alle wichtigen Systemmeldungen in eine Datei (/var/log/messages). Auf Wunsch kann er die Meldungen aber auch an den Server schicken, der sie in sein Syslog schreibt:
    Dazu muss der Server (hier: SuSE mit syslog-ng) angewiesen werden, Systemmeldungen anderer Rechner entgegenzunehmen. In der Datei /etc/syslog-ng/syslog-ng.conf wird die Zeile udp(ip("0.0.0.0") port(514)); auskommentiert und in der Datei /etc/sysconfig/syslog die Zeile SYSLOGD_PARAMS="-r" angepasst. Anschließend Syslog neu starten:
    /etc/init.d/syslog restart
    Der Client muss angewiesen werden, seine Meldungen an den Server zu senden. Dazu werden in der Datei /etc/syslog-ng/syslog-ng.conf alle destination/log Blöcke deaktiviert - bis auf einen:
    destination allmessages { udp(server); };
    log { source(src); destination(allmessages); };