A Raspberry Pi lemeztelenítése

Szabadítsuk meg rendszereinket az SD kártya rabságától a hálózati boot-olás erejével

Egy Raspberry Pi alapú rendszernek nem feltétlenül az SD kártya a legmegbízhatóbb része. Rengeteg történetet lehet olvasni az interneten ezzel kapcsolatos adatvesztésekről és tönkrement adattárolókról. A szerencsém egész sokáig kitartott, sok rendszert futtattam folyamatos jelleggel és egy SD kártya se halt meg ez idő alatt.

Persze minden sikerszéria egyszer véget ér. Nálam ez akkor érkezett el, amikor a tévét próbáltam felokosítani egy Raspberry Pi 4-es modellen futó LibreELEC rendszerrel. Nem tudom miben lehetett ez más, mint az eddig futtatott rendszereim, de egy SD kártyát teljesen hazavágott, egy másikra pedig újra kellett telepítenem a rendszert, miután nem volt hajlandó boot-olni.

Örömmel fogadtam tehát a hírt, hogy már a 4-es modell is támogatja a hálózatról boot-olást, ami egy SD kártya mentes világ ígéretével kecsegtetett. Persze, ahogy az már lenni szokott, nem volt zökkenőmenetes az út odáig.

A hardver felokosítása

Jó esély van rá, hogy a Pi-on egy régi bootloader fut, amiben még nincs meg a megfelelő támogatás, így fura módon először is szükségünk lesz egy SD kártyára az SD kártya mentesítéshez.

Függetlenül attól, hogy később milyen rendszert szeretnénk futtatni, ezen a kártyán most legyen egy Raspberry Pi OS (korábbi nevén Raspbian). A sikeres telepítés és indítás után először is ki kell nyernünk a sorozatszám utolsó nyolc karakterét, amire a későbbiekben még szükségünk lesz.

$ grep Serial /proc/cpuinfo
Serial		: 10000000xxxxxxxx

Aztán egy kis rendszerfrissítés, hogy leszedjük a legfrissebb bootloader-t, amit rögtön frissítünk is és újraindítjuk a masinát, hogy érvényre lépjenek a módosítások.

# apt-get update
# apt-get upgrade
# rpi-eeprom-update
# reboot

Egy apró módosítás a config-ban, hogy a sok boot-opció között a hálózat is szerepeljen. A Boot Options > Boot Order > Network Boot menüpontot kell megnyomni, még egyszer utoljára újraindítani és (ha minden jól megy) meg is szabadulhatunk az SD kártyától örökre.

# raspi-config

Én nyilván ennek a beállítása nélkül próbálkoztam hosszú órákon át és csak csodálkoztam, hogy miért hiányolja még mindig az SD kártyát.

A szerver

A hálózatról boot-oláshoz kell valami a hálózaton, ami partner lesz ebben. A dolog egy részét a DHCP oldja meg, de van benne egy szakaszon TFTP és végül szükségünk van egy NFS (Need For Speed?) szerverre is.

Nem mondom, hogy teljes mértékben értem, hogy mi zajlik a háttérben, de én valahogy úgy képzelem ezt az egészet, hogy DHCP-n lebeszélik, hogy lehet a hálózatról is boot-olni, TFTP-n jön az első pár fájl, amivel elindul annyira a gép, hogy a rendszer maradékát NFS-en keresztül be tudja tölteni.

Tehát első körben szükségünk lesz egy DHCP és TFTP szerverre. Szerencsére a dnsmasq tudja mindkettőt. Akkor sem kell megijedni, ha az IP címeket nem vele szeretnénk kiosztatni, erre is lehet megoldást találni, de én abban a szerencsés helyeztben voltam, hogy már volt egy futó dnsmasq a gépen, ami DHCP szerverként üzemelt.

# apt install dnsmasq

Kelleni fog egy könyvtár, amiből a TFTP kiszolgálja a fájlokat. Itt az xxxxxxxx a korábban megismert sorozatszám utolsó 8 karakterére utal.

# mkdir -p /var/lib/tftpboot/xxxxxxxx

Aztán egy kis dnsmasq beállítás, hogy bekapcsoljuk a TFTP-t.

/etc/dnsmasq.conf
enable-tftp
tftp-root=/var/lib/tftpboot
pxe-service=0,"Raspberry Pi Boot"

Végül egy systemctl restart dnsmasq.service és át is térhetünk az NFS szerver telepítésére.

# apt install nfs-common nfs-kernel-server

Itt is szükségünk lesz pár könyvtárra, amit majd kiszolgálhatunk.

# mkdir -p /nfs/libreelec/{boot,storage}

Valamint össze is kötjük az NFS által kiszolgált boot könyvtárat a TFTP által kiszolgálttal, hogy ugyanaz legyen benne.

/etc/fstab
/nfs/libreelec/boot /var/lib/tftpboot/xxxxxxxx none defaults,bind 0 0

Már csak meg kell mondanunk az NFS szervernek, hogy ha adott IP-ről szépen kérik, akkor adja oda ezeket a fájlokat. Ha nincs fix IP-je a gépnek, akkor használhatunk nagyobb címtartományt vagy akár *-ot is.

/etc/exports
/nfs/libreelec/boot <raspberry ip>/32(ro,sync,no_root_squash,no_subtree_check)
/nfs/libreelec/storage <raspberry ip>/32(rw,sync,no_root_squash,no_subtree_check)

Ha nem hiszünk a tűzfalak jótékony hatásában, akkor itt meg is állhatunk, egyébként még meg kell mondanunk a mountd-nek (bármi is legyen az), hogy milyen porton fusson, hogy tudjuk, hogy hol kell a tűzfalat lyukasztani.

/etc/default/nfs-kernel-server
RPCMOUNTDOPTS="--manage-gids -p 13025"

Dübörögnek a szerverek, nincs más hátra, mint megtölteni a létrehozott könyvtárakat a futtatni kívánt operációs rendszer fájljaival. Mivel még volt egy működőt SD kártyám és nem akartam elveszteni a beállításaimat ezért én onnan mount-oltam fel a fájlrendszereket és másoltam át mindent az új NFS-es könyvtárakba.

# fdisk -l
[...]

Disk /dev/sdb: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb774a380

Device     Boot   Start      End  Sectors  Size Id Type
/dev/sdb1  *       8192  1056767  1048576  512M  c W95 FAT32 (LBA)
/dev/sdb2       1056768 15523839 14467072  6.9G 83 Linux

# mkdir /media/{boot,storage}
# mount /dev/sdb1 /media/boot
# mount /dev/sdb2 /media/storage
# cp -a /media/boot /nfs/libreelec/boot
# cp -a /media/storage /nfs/libreelec/storage
# umount /media/boot
# umount /media/storage
# rmdir /media/{boot,storage}

De ugyanilyen jól tud működni az is, ha egy frissen letöltött image-ből másoljuk ki őket. A storage rész ilyenkor üresen marad, azt majd a LibreELEC fogja megtölteni az első indulás során. A mount-olás kicsit körülményesebb, a fájlrendszer kezdő szektorát kell felszoroznunk a szektor mérettel (esetünkben 8192 * 512), hogy megkapjuk a helyes offset-et.

# fdisk -l LibreELEC-RPi4.arm-9.2.5.img
Disk LibreELEC-RPi4.arm-9.2.5.img: 549 MiB, 575668224 bytes, 1124352 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcb770fc1

Device                        Boot   Start     End Sectors  Size Id Type
LibreELEC-RPi4.arm-9.2.5.img1 *       8192 1056767 1048576  512M  c W95 FAT32 (LBA)
LibreELEC-RPi4.arm-9.2.5.img2      1056768 1122303   65536   32M 83 Linux

# mount -o loop,offset=<sector size * start> LibreELEC-RPi4.arm-9.2.5.img /media/boot

A fájlok a helyére kerültek, de az operációs rendszernek meg kell még mondanunk, hogy hol fogja találni őket.

/nfs/libreelec/boot/cmdline.txt
ip=dhcp boot=NFS=<szerver ip>:/nfs/libreelec/boot disk=NFS=<szerver ip>:/nfs/libreelec/storage

A tűzfal még kicsit bonyolíthatja a helyzetet, érdemes a belső hálózat felé kinyitni UDP-n a 69-es portot a TFTP-nek és TCP-n a 111-es, 2049-es és 13025-ös (vagy amit korábban a config-ban megadtunk) portot az NFS-nek.

A Raspberry Pi-t – most már SD kártya nélkül – áram alá helyezve remélhetőleg tapasztalhatjuk, ahogy ha nem is villám gyorsan, de annál varázslatosabban elindul a masina.

További olvasnivalók

This post is also available in english: Diskless Raspberry Pi

Hozzáfűznél valamit?

Dobj egy emailt a blog kukac deadlime pont hu címre.

Feliratkoznál?

Az RSS feed-et ajánljuk, ha kedveled a régi jó dolgokat.