👋

Raspberry Pi4でdiskless/netbootする

2024/12/13に公開

この記事について

この記事ではRaspberry Pi4を使ってPXE/TFTP/NFSによるdiskless bootをする方法について簡単にまとめます。

情報源

Officialの記事だと https://www.raspberrypi.com/documentation/computers/remote-access.html#network-boot-your-raspberry-pi にありますので、これを参考にすればいいと思います。

実際のイメージ

  • NFS/TFTPの設定 (ここでは省略します)
  • RPi4のシリアル、MACアドレスを取得
  • PXEの設定 (dnsmasqの場合)
  • SDの内容をNFSサーバにコピー
  • /boot/firmwareをTFTPにコピー (/tftpboot/<RPi4のserial>)
  • /tftpboot/<RPi4のserial>/cmdline.txtの起動rootをNFSに指定
  • RPi4のnetbootを有効化

NFS/tftpの設定

各インストールしたNFS/tftpのソフトウェアの設定に従って下さい。
RPi4は起動時にはNFSv3でウントするのでNFSはv3が動く設定にしましょう。

RPi4のシリアル、MACアドレスの取得

最初にSDでブートして以下の情報を取得します。

  • RPi4のシリアル
  • MACアドレス

下のコマンドで取得することが可能です(アウトプット例は適当な文字にしています)。

$ cat /proc/cpuinfo | grep Serial | awk -F ': ' '{print $2}' | tail -c 8
aabbccdd
$ ip addr show eth0 | grep ether | awk '{print $2}'
aa:bb:cc:dd:ee:ff

PXEの設定 (dnsmasqの場合)

対象のRPi4がPXEで起動するようにdhcpサーバ側で設定します(以下はdnsmasqの例)。

dhcp-mac=set:rpi4,aa:bb:cc:dd:ee:ff
pxe-service=tag:rpi4,0,"Raspberry Pi Boot"

SDの内容をNFSサーバにコピー

起動したいOSの中身をNFSサーバにコピーします。NFSのマウント等については自分の設定に変えてください。

sudo apt install rsync
sudo mkdir -p /nfs/client1
sudo mount -t nfs 192.168.1.1:/export/client1 /nfs/client1
sudo rsync -xa --progress --exclude /nfs / /nfs/client1

SSH host keyを以下のコマンドで再度作成します。

cd /nfs/client1
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot .
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
exit
sudo umount dev sys proc

/boot/firmware をNFSにコピー

上のrsyncでは/boot/firmwareをコピーできていません。/boot/firmwareも起動に必要なのでNFSにコピーします。

/etc/fstabの修正

NFSサーバにコピーしたOSの中の/etc/fstab/boot/firmwareのマウントを先程のNFS経由でできるように修正します。

proc            /proc           proc    defaults          0       0
192.168.1.1:/export/.../boot-firmware/ nfs defaults,vers=3 0 0
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

/boot/firmwareをTFTPにコピー (/tftpboot/<RPi4のserial>)

RPi4のbootloader等はNFSではなくTFTPで取得することになります。RPi4ではデフォルト/tftpboot/<RPi4のserial>配下を読み込むことができますので、対応したpathに/boot/firmwareのファイルをコピーします。

/tftpboot/<RPi4のserial>/cmdline.txtの起動rootをNFSに指定

上でコピーしたファイルの中にあるcmdline.txtを修正します。NFSv3でマウントする必要があるのでvers=3は必ず設定しましょう。

root=/dev/nfs nfsroot=192.168.1.1:/export/client1,vers=3 rw ip=dhcp rootwait

RPi4のnetbootを有効化

sudo raspi-configを実行して、Advanced OptionsBoot OrderNetwork Bootを選択することでNetwork Bootを最初にトライ→SDでトライ と起動優先順位を変更することが可能です。 より複雑に設定したい場合には手動でBOOT_ORDERを変更することで設定が可能のはずです。

以上で設定は完了です。あとはRPi4を再起動すればBootloaderをTFTPから読みこみ、NFSで指定したイメージから起動するはずです。

Discussion