PXE Netzwerk-Boot mit Ubuntu Client & Debian Server

Nachdem ich neulich einen Ubuntu-Server mit VMware-Server auf einem 1GB USB-Stick aufgesetz habe und mir erst dann die Erkenntnis zuteil wurde, dass dieses Speichermedium aufgrund des Flash-Memory nur eine begrenze Lebensdauer hat, die maßgeblich durch die Schreibzyklen bestimmt wird, musste ich nun rasch bemüht sein, eine Lösung zu finden. Dabei wollte ich möglichst die bereits durchgeführten Arbeitsschriftte für das Aufsetzen des System inkl. VMware-Server auf den 1 GB Stick nicht noch einmal durchführen müssen.

Nachdem ich auf dem Client-Rechner das BIOS geflashed habe, war die Netzwerkkarte PXE fähig und ich konnte mich am Leitfaden DisklessUbunto HowTo orientieren, der in nahezu idealer Weise meine Anforderungen umsetzt.

Abweichend von dem HowTo verwende ich einen Debian Sarge Server. Hier zunächst die Schritte auf dem Debian Server, den ich zunächst mit

apt-get install tftpd-hpa dhcp3-server

um erforderliche Pakete erweitert habe. An dieser Stelle habe ich auch mein Firewall-Regeln entsprechend für diese Dienste erweitert. Und dann mit

vi /etc/dhcp3/dhcpd.conf

der MAC-Adresse der PXE bootfähigen Netzwerkkarte eine statische IP zugewiesen. Beim PXE Boot holt sich der Client als erstes diese statische IP. Auch die IP des Routers and NameServers wird festgelegt:

[code]
allow booting;
allow bootp;

subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.xxx 192.168.2.xxx;
option broadcast-address 192.168.2.255;
option routers 192.168.2.xxx;
option domain-name-servers 192.168.2.xxx;

filename “/pxelinux.0”;
}

# force the client to this ip for pxe.
# This is only necessary assuming you want to send different images to different computers.
host pxe_client {
hardware ethernet xx:xx:xx:xx:xx:xx;
fixed-address 192.168.2.xxx;
}
[/code]
(IP-Adressen nur beispielhaft verwendet)

In /etc/inetd.conf wurde bei der Installation folgende Zeile eingefügt:

tftp dgram udp wait root /usr/sbin/in.tftpd /usr/sbin/in.tftpd -s /var/lib/tftpboot

Nun mit

apt-get install syslinux nfs-kernel-server

die noch evtl. fehlenden Pakete nachinstallieren. syslinux stellt einen speziellen Bootloader bereit, den ich gleich benötige um ihn per TFTP an den Client zu übermitteln.

mkdir /var/lib/tftpboot/pxelinux.cfg
cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot/

Mit

vi /var/lib/tftpboot/pxelinux.cfg/default

lege ich nun die Parameter für den pxe Bootloader fest:

[code]
LABEL linux
KERNEL vmlinuz-2.6.15-26-server
APPEND root=/dev/nfs initrd=initrd.img-2.6.15-26-server.nfs nfsroot=10.10.1.5:/nfsroot ip=dhcp rw
[/code]
wobei ich den Kernel vmlinuz-2.6.15-26-server von meinem bereits existierenden Ubuntu-System nehme und den speziellen initrd.img-2.6.15-26-server.nfs gleich noch auf dem Ubuntu-System erstellen werde.

Aber zunächst geht es weiter auf dem Server mit dem Einrichten der NFS-Freigabe. Evtl. die Firewall-Regeln für den NFS-Server weitern und die Folder anlegen und exportieren:

mkdir /nfsroot
vi /etc/exports

/nfsroot *Client-IP*(rw,no_root_squash,async)

exportfs -rv

Das war es erstmal auf dem Debian-Server. Nun geht’s weiter auf dem Client (dem Ubuntu-System):

vi /etc/mkinitramfs/initramfs.conf

#BOOT=local
BOOT=nf

und dann die initramfs erstellen:

mkinitramfs -o /boot/initrd.img-2.6.15-26-server.nfs

Zunächst liegt das initramfs nur auf dem Ubuntu-Client, später muss es auf dem Server unter /var/lib/tftpboot/initrd.img-2.6.15-26-server.nfs liegen. Doch dazu gleich.

Jetzt wird auf dem Ubuntu-System erstmal die NFS-Freigabe vom Debian-Server gemounted, damit das gesamte Filesystem in die NFS-Freigabe kopiert und später per NFS vom Diskless Ubuntu-System genutzt werden kann:

mkdir /mnt/nfsroot
mount -tnfs -onolock *SERVER-IP*:/nfsroot /mnt/nfsroot
cp -ax /. /mnt/nfsroot/.
cp -ax /dev/. /mnt/nfsroot/dev/.

Das war’s auf dem Ubuntu Client. Das lokale Filesystem (zZ. noch auf dem USB Stick) wird jetzt nicht mehr benötigt. Das Ubuntu-System kann heruntergefahren werden und der USB-Stick kann rausgezogen werden. Im BIOS nun nur noch ggf. das PXE Boot aktivieren.

Auf dem Debian-Server sind noch folgende letzte Schritte erforderlich: Das spezielle NFS-fähige initramfs und der Kernel müssen noch in dem TFTP Folder verfügbar gemacht werden:

cp /nfsroot/boot/initrd.img-2.6.15-26-server.nfs /var/lib/tftpboot/initrd.img-2.6.15-26-server.nfs
cp /nfsroot/boot/vmlinuz-2.6.15-26-server /var/lib/tftpboot/vmlinuz-2.6.15-26-server

Last but not least muss mit

vi /nfsroot/etc/network/interfaces

# auto eth0

auskommentiert werden, weil sonst beim Hochfahren des Ubuntu-Systems die bereits vom Kernel aktivierte eth0 erneut hochgefahren würde und man dann die Verbindung zum NFS verlieren würde und das root-FS abhängen würde.

Wenn kein vorhandenes System verfügbar ist, welches man in die NFS-Freigabe transferieren kann oder will, so kann auch eine komplette Neuinstallation über PXE erfolgen. Mehr dazu kann man in den Ubuntu PXE wiki nachlesen.

Einen interessanten weiterführenden Artikel zum Thema Iptables und NFS habe ich hier gefunden.

4 comments Write a comment

  1. hi,

    ich hab nen fehler gefunden, bei “vi /etc/mkinitramfs/initramfs.conf” fehlt in der eingabe ein ‘s’ bei nfs

    aber sehr gute howto

    gruss
    –aleex

  2. Hallo,

    Danke für dieses tolle Howto, hat mir echt weiter geholfen. Ich hab anstatt Ubuntu als ClientOS Debian genommen (ist ja eh das selbe).

    Allerdings musste ich noch einen kleinen Trick anwenden:
    Da das Betriebssystem vorher auf einer Festplatte installiert war, hab ich alle Einträge in der /etc/fstab bis auf “proc” auskommentiert. Erst dann wollte Debian auch über Netzwerk vom nfsmount booten.

    Ansonsten: SUPER! Danke! Ich glaube ohne diese Seite wäre ich immer noch am rätseln, wie sowas funktioniert.

  3. Sehr gutes HOWTO. Hat mir sehr geholfen.
    Ich musste noch den NetworkManager entfernen, damit der die Netzwerkkarte nicht neu konfiguriert. Am einfachsten per

    apt-get purge network-manager

    Gruß Bernd

  4. Hallo!
    Bei mir funktionierts auch einwandfrei, bis der Bootvorgang mit folgender Meldung in einer Endlosschleife hängt:
    IP Config: failed to set default route to eth0
    IP Config: eth0 complete from 192.168.178.10:
    adress: 192.168.178.15
    gateway: 192.168.178.1
    broadcast: 192.168.178.1
    remoteserver: 192.168.178.10 rootpath
    filename: pxelinux.0

    Begin: Running /scripts/nfs-premount …
    Done
    connect: Network is unreachable
    connect: Network is unreachable
    nfs over tcp not available from 192.168.178.10

    Hat vielleicht jemand eine Idee wo mein Fehler liegt?

    grüße