DisklessClient#
Im Prinzip geht es hier darum, einen Rechner, der keine eigene Festplatte hat, über das Netzwerk von einem Fileserver aus booten zu lassen. Ansonsten soll der Rechner aber wie ein normaler Rechner installiert sein, d.h. alle Applikationen laufen auf dem Client, der Server ist nur für die Festplatte zuständig. Wer sich für einen noch einfacheren Client interessiert, der nur noch Bildschirmausgaben des Servers macht, findet auf der Seite LinuxTerminalServer Informationen hierzu (z.B. LTSP). Ein älterer und etwas allgemeiner gehaltener Artikel zum Thema ist BootenVomNetzwerk.
Die Tatsache, daß die Preise für ThinClients teilweise höher liegen als die für billige (aber komplette) PCs und die Tatsache, daß ich rechenintensive Applikationen benötige, hat mich auf den Gedanken gebracht, die eigentliche Applikation auf dem Client zu belassen. Dort benötigen wir dann einen normalen Prozessor (im Gegensatz zu embedded Prozessoren wie z.B. dem 266 MHz-Geode, die in ThinClients oft benutzt werden) und mehr Speicher. Der Nachteil ist, daß man wieder einzelne Systeme hat (wenn auch auf einem Rechner), die einzeln gewartet werden müssen (wenn man hierfür keine intelligente Lösung findet, was ich jedoch vorhabe).
Ein Vorteil eines Client-Systems zu einem LTSP-System ist, daß wir keine besonderen Pakete und Installationen benötigen. Im Grunde haben wir ja ein ganz normales Standard-Debian-System. Lediglich ein paar Konfigurationen sind zu ändern. Dazu gehen wir jetzt zuerst durch die einzelnen Dienste, die wir auf dem Server aufsetzen müssen und richten danach einen einfachen Client ein, den der geneigte Leser dann nach belieben anpassen kann. Als letztes gibt es Änderungen, die man benötigt, um auch mehrere Clients effektiv verwalten zu können.
Einrichtung des Servers#
DHCP-Server#
Der DHCP-Server gibt einem Client, der gar nicht weiss, wo er im Leben steht (weil er keine Festplatte hat, die es ihm sagt), eine erste Orientierung. Er gibt ihm seine Netzwerkkonfiguration und Informationen darüber, wie es weitergeht, bzw. wo er ein Betriebssystem herbekommt.
Man kann die folgende Konfiguration ohne große Probleme in einen im Netzwerk vorhanden DHCP-Server (z.B. KrefixLinux bzw. DHCPServerMitDNS) einpflegen, man kann aber auch einen DHCP-Server auf dem Terminalserver installieren. Es ist ledglich zu beachten, daß man nicht beides tut (es sollte immer nur einen DHCP-Server in jedem Netzwerksegment geben).
Auf dem Server folgendes in die dhcpd.conf (z.B. hinten anfügen):
group { allow bootp; server-name "terminalserver.bayen.loc"; next-server terminalserver.bayen.loc; option root-path "192.168.201.2:/var/nfs/sarge"; filename "pxelinux.0"; option routers 192.168.201.1; option domain-name-servers 192.168.201.1; option domain-name "bayen.loc"; host client1 { fixed-address 192.168.201.5; hardware ethernet 00:aa:bb:cc:dd:ee; option host-name = "client1"; } host qemu { fixed-address 192.168.201.5; hardware ethernet 00:47:11:47:11:01; option host-name = "qemu"; } }
TFTP-Server#
Mittels des tftp-Protokolls holt sich der Client laut den vom DHCP-Server erhaltenen Daten eine Bootdatei, die er dann ausführt. Diese Bootdatei soll in unserem Beispiel pxelinux sein (eine Netzwerk-Variante des Bootloaders syslinux).
aptitude install tftpd-hpa syslinux aptitude install kernel-image-2.6-686
(Soll auf dem Terminalserver ein anderer Kernel als auf den Clients laufen, muss ggf. die GRUB-Konfiguration des Servers angepasst werden.)
Nun wird im Verzeichnis /var/lib/tftpboot einiges installiert:
cd /var/lib/tftpboot cp /usr/lib/syslinux/pxelinux.0 . mkdir pxelinux.cfg mkdir boot
Nun muss für jeden Server die hexadezimale IP-Adresse (C0A8C98C für 192.168.201.140, kann z.B. mit gethostip festgestellt werden) festgestellt werden und im Verzeichnis pxelinux.cfg eine Datei dieses Namens angelegt werden. Dort kommt die Bootkonfiguration für pxelinux hinein:
label linux kernel boot/linux... append vga=normal initrd=boot/initrd.img-2.6... ramdisk_size=9424 root=/dev/nfs nfsroot=192.168.201.2:/var/nfs/sarge ip=dhcp devfs=mount rw --
In das boot-Verzeichnis kommen später der Kernel und die initrd hinein (nach aufsetzen des Systems).
NFS-Server#
Hierzu muss in einem vom NFS-Server (per exports-Datei) freigegebenen Bereich ein root-Verzeichnis angelegt werden. Dort wird eine Debian-Installation hineingelegt und diese angepasst:
aptitude install nfs-kernel-server mkdir -p /var/nfs/sarge
Dann installiert man ein DeBootstrapBasisSystem in dieses neue Verzeichnis. Dabei nimmt man folgende besondere Konfigurationen vor:
echo "terminalserver:/var/nfs/testclient / nfs defaults 0 0" >>etc/fstab echo "none /proc/bus/usb usbfs defaults 0 0" >>etc/fstab cp -a /lib/modules/2.6.8-2-686 lib/modules/ # (ist diese Zeile noch nötig, wenn der Kernel später installiert wird? -- TB) aptitude install udev # Alternativ Devices mit MAKEDEV anlegen oder devfs benutzen aptitude install initrd-netboot-tools aptitude install kernel-image-2.6-686
Nun kopiert man dem Kernel und die Initrd nach /var/lib/tftpboot/boot, passt die pxe-Konfiguration auf die Kernelversion an und der Kernel sollte booten können.
cp boot/vmlinuz* /var/lib/tftpboot/boot cp boot/initrd* /var/lib/tftpboot/boot
In /etc/exports:
/var/nfs/testclient/ 192.168.201.5(rw,no_root_squash,sync)
Konfigurieren der initrd / Debugging#
Damit der Kernel nun auch wirklich das root-Dateisystem vom NFS holt, sind u.U. noch einige Anpassungen in der initrd nötig. Die Grundlagen hierzu werden bereits vom Paket initrd-netboot-tools gelegt, allerdings läuft das nicht immer von ganz alleine. Bei Debugging hat es sich als günstig erwiesen, die initrd öfters neu zu erstellen, um Bootskripten anpassen zu können. Hierzu geht man in das chroot-Jail (wo auch die o.a. Pakete installiert wurden, ändert die Konfigurations-Dateien und aktiviert dann den Kernel mit
dpkg-reconfigure kernel-image-2.6.8-2-686
innerhalb des chroot-Jail und
cp /var/nfs/testclient/boot/initrd.img-2.6.8-2-686 /var/lib/tftpboot/boot/
außerhalb desselben (also direkt auf dem Terminalserver). Danach steht einem Reboot des Clients nichts im Wege.
Sinnvoll kann z.B. sein, in der Datei /etc/lessdisks/mkinitrd/install_scripts/90_mount_nfs_root ganz unten das mounten von devfs auszukommentieren, wenn man das neuere udev nutzen will.
Einrichtung des Clients#
Wenn wir eine Netzwerkkarte habe, die ein Bootrom hat oder ein Motherboard mit integrierter Netzwerkkarte, kann man normalerweise im BIOS das LAN als Bootdevice angeben. Bei einem älteren Rechner oder einer zusätzlich eingebauten Netzwerkkarte kann man mit Hilfe von Etherboot eine Bootdiskette oder Boot-CD erzeugen. Den so vorbereiteten Client schaltet man nu ein und los gehts. Beim ersten Mal wird das Booten ggf. noch nicht klappen, weil der DHCP-Server die Mac-Adresse noch nicht kennt. Diese sollte dann bei dem (gescheiterten) Bootversuch angezeigt werden und kann daraufhin von Hand in der DHCP-Konfiguration eingefügt werden.
Besonderheiten für bestimmte Softwarepakete#
Wer udev nutzen will, sollte wie oben beschrieben das Mounten von devfs verhindern (ob es läuft, sieht man am sichersten in "/proc/mounts"), dann das System booten und dort folgendes machen:
aptitude install udev cd /dev MAKEDEV update reboot
Um einen X-Server starten zu können, empfiehlt sich udev. Wenn man das psmouse-Modul lädt, sollte das Device /dev/input/mice auftauchen. Dann kann man den X-Server installieren:
aptitude install x-window-system
Leider wird die Konfiguration so nicht laufen. Hier gibt es einen Bug im Debian-X-Server Konfigurationstool, der bei NFS-Laufwerken auftritt. Man muss in der Datei /usr/bin/dexconf ganz unten eine Zeile vor der rm ...-Zeile einfügen:
exec 4>/dev/null
Dann den X-Server neu konfigurieren mit:
dpkg-reconfigure xserver-xfree86
Um ein vernünftiges Desktop-System mit KDE zu installieren, macht man am besten folgendes:
aptitude install xserver-xfree86 aptitude install kde kde-i18n-de
Um KDE per kdm zu starten, muss in der Datei /etc/kde3/kdm/kdmrc RandomDevice=/dev/urandom gesetzt werden. (siehe KDE Bug-Report).
QEMU-Client mit netboot#
Auf http://rom-o-matic.net/ einen Treiber für eine ne-Karte (ns8390) z.B. als .liso-Image herunterladen und dann qemu starten mit
/usr/local/bin/qemu -m 128 -macaddr 00:47:11:12:00:01 -boot d -cdrom ~/qemu/etherboot-5.4.1-ns8390.iso
Fertig! :-)
Ubuntu (?)#
Leider habe ich nes nicht hinbekommen, ein Ubuntu-System netboot-fähig zu machen. Der X-Server war nicht zu konfigurieren.
Ob es überhaupt sinnvoll ist, Ubuntu per Netboot zu installieren, bedarf auch noch einer Erörterung. Der Hautpvorteil von Ubuntu liegt in der einfachen und automatischen Konfiguration. Ebendiese wollen wir allerdings dem Benutzer eigentlich abnehmen und sie zentral auf dem Server belassen. Man müsste bei Ubuntu evtl. einige Dinge herausnehmen (alles, was Root-Zugriff erfordert), um den Benutzer nicht zu verwirren...
Eine gute Anleitung zum Thema gibts auf der Seite https://wiki.ubuntu.com/Installation/OnNFSDrive. Natürlich wird auch auf dieser Seite wieder um den heissen Brei herumgetanzt, wenn es um den Kernel (ggf. die intird) und den Bootvorgang geht. Da wir diese Probleme jedoch gerade (oben für Debian) gelöst haben, hindert uns keiner daran, beide Erkenntnisse zusammenzufassen. Dazu erzeugen wir zuerst ein neues Verzeichnis, z.B. /var/nfs/ubuntu für die Installation. Die eigentliche Arbeit macht debootstrap, da es sich bei Ubuntu ja technisch gesehen um eine (besondere) Debian-Distribution handelt. Allerdings benötigt dieses nicht nur einfach den Paket-Mirror, sondern auch ein angepasstes Installations-Skript. Damit dieses für die Ubuntu-Distributionen dabei ist, installieren wir erstmal von Hand das debootstrap-Paket von Ubuntu (Link auf o.g. Seite, jedoch nicht
- tar.gz, sondern *.deb). Danach starten wir das Programm mit entsprechenden Parametern. Das ist dann auch schon die Hauptarbeit
cd /var/nfs dpkg -i /root/debootstrap_0.3.3.0ubuntu1_all.deb debootstrap breezy ubuntu/ http://archive.ubuntulinux.org/ubuntu chroot ubuntu
hostname, hosts und fstab erstellen wie auf https://wiki.ubuntu.com/Installation/FromAnotherDistro beschrieben. In /etc/mkinitramfs/initramfs.conf eintragen: BOOT=nfs und NETOPTS="-o udp".
Kernel installieren:
aptitude install linux-image-686 exit cp /var/nfs/ubuntu/boot/vmlinuz-2.6.12-9-686 /var/lib/tftpboot/boot/ cp /var/nfs/ubuntu/boot/initrd.img-2.6.12-9-686 /var/lib/tftpboot/boot/ (dann entweder Link auf Kernel-Image neu setzen oder Eintrag in pxelinux.cfg entsprechend anpassen)
Am besten noch den nfs-Server restarten und dann kann's losgehen!
Die Textkonsole unseres Netboot-Ubuntu läuft nun. Dann als nächstes vielleicht(?)
aptitude --without-recommends install ubuntu-standard ubuntu-desktop
Synergien für mehrere Clients#
Meine Überlegung: Bisher haben wir genau einen Client, der in genau einem Verzeichnis "residiert". Wollen wir einen zweiten haben, müssten wir dieses Verzeichnis komplett kopieren. Sinnvoll wäre, wenn man den Root-Baum readonly an mehrere Clients geben kann und die beschreibbaren Teile (/var und /home, evtl. /etc) gesondert mounten würde. Diese könnten dann für jedes System angepasst sein. Auf der anderen Seite müsste ein Multitaskingsystem theoretisch an vielen Stellen auch damit fertig werden, wenn mehrere Clients gleichzeitig das gleiche Verzeichnis read-write mounten.
Um die Abgrenzung vorzunehmen, sollte man den Filesystem Hierarchy Standard beachten. Einen deutschen (etwas älteren) Artikel zum Thema gibts im Linux Magazin
Man kann nun die o.g. Verzeichnisse gesondert exportieren und beim Bootvorgang des Clients über das normale Root-Verzeichnis (das nur read-only ist) mounten. Hierbei entsteht das Problem, daß man für jeden Client eine komplette Kopie von /etc benötigt. Installiert man nun auf dem Hauptsystem ein neues Paket (oder ein Update), so müssen die Kopien auch irgendwie geupdatet werden. Dies könnte man vielleicht mit sowas wie rsync oder ein paar Skripten, die die Änderungsdaten auswerten, machen. Eine Alternative ist, UnionFS zu benutzen, um das gesamte Read-Only-System "beschreibbar" zu machen.
Eine sehr gute Lösung, um dieses Problem anzugehen, scheint der Copy-on-Write NFS-Server zu sein. Hiermit kann man mehrere NFS-Freigaben quasi "übereinanderlegen".