Raspberry Pi PXEのTFTP artifactとNFS rootfsを同じrelease境界で扱う
Posted:
Raspberry Pi PXEのTFTP artifactとNFS rootfsを同じrelease境界で扱う
目的
Raspberry Pi を PXE / network boot で運用すると、boot firmware が読む TFTP artifact と、Linux が mount する NFS rootfs が別々の場所に置かれる。
この 2 つの対応がずれると、kernel / DTB / initramfs / module set / rootfs のどこで壊れたかを追いにくい。
ここでは、TFTP artifact と NFS rootfs を同じ release 境界で promote する設計をまとめる。
前提
構成は次のように分ける。
DHCP / TFTP server
-> TFTP root
dates/<release>/
<board-or-host-prefix>/
NFS server
-> rootfs/<release>/
Raspberry Pi firmware は board 固有の prefix directory を読める。host directory には config.txt、cmdline.txt、symlink などを置き、cmdline.txt で NFS rootfs release を切り替える。
採用案: paired clean release bundle
通常運用では、TFTP artifact と NFS rootfs を同じ release 名に揃える。
bundle date: 20260601
Pi 4:
tftp_release: 20260601-rpi4
rootfs_release: 20260601-rpi4
Pi 5:
tftp_release: 20260601-rpi5
rootfs_release: 20260601-rpi5
stage 側には日付だけを持つ。
pxe_release_stage_dates:
staging: "20260601"
automation は board generation から 20260601-rpi4 / 20260601-rpi5 を導出し、通常 promote では tftp_release == rootfs_release を gate にする。
構成
flowchart TD
inv["stage date<br/>YYYYMMDD"]
build["release bundle build"]
root4["rootfs/YYYYMMDD-rpi4"]
tftp4["tftp/dates/YYYYMMDD-rpi4"]
root5["rootfs/YYYYMMDD-rpi5"]
tftp5["tftp/dates/YYYYMMDD-rpi5"]
guard["bundle guard<br/>marker / manifest / release pair"]
hostdir["board or host directory<br/>cmdline.txt"]
pi4["Raspberry Pi 4"]
pi5["Raspberry Pi 5"]
inv --> build
build --> root4
build --> tftp4
build --> root5
build --> tftp5
root4 --> guard
tftp4 --> guard
root5 --> guard
tftp5 --> guard
guard --> hostdir
hostdir --> pi4
hostdir --> pi5
メリット
- release 名だけで boot artifact と rootfs の対応を追える。
- boot 失敗時に、TFTP 側が古いのか、rootfs 側が古いのかを判断しやすい。
- rollback は stage 日付または host 個別 override を旧 paired release へ戻すだけでよい。
cmdline.txt、board directory、NFS export、TFTP artifact の確認が単純になる。
デメリット
- Pi 世代ごとに同一内容の TFTP artifact が重複する場合がある。
- pruning は Pi4/Pi5 の paired release をまとめて扱う必要がある。
- rootfs だけを canary したい場合は、通常 promote ではなく一時 override として扱う必要がある。
不採用案: shared TFTP generation
TFTP artifact を日付単位で 1 つにまとめ、rootfs だけ Pi 世代ごとに分ける案もある。
bundle date: 20260601
TFTP:
tftp_release: 20260601
Pi 4:
rootfs_release: 20260601-rpi4
Pi 5:
rootfs_release: 20260601-rpi5
この案は storage の重複を減らせる。ただし tftp_release != rootfs_release が通常状態になるため、manifest を見ないと対応関係を判断しにくい。
家庭内や小規模検証では、storage 節約よりも障害時の判断の単純さを優先し、paired clean release bundle を採用する方が扱いやすい。
Gate
promote 前後では、最低限次を確認する。
# host directory が期待 release を指すこと
find /srv/tftp -maxdepth 2 -type f -name cmdline.txt -print
# TFTP artifact と rootfs の marker / manifest が一致すること
find /srv -name '.release_bundle_*' -print
# boot 後に kernel cmdline が期待 rootfs を指すこと
cat /proc/cmdline
# root が overlayfs / NFS rootfs 経由で mount されていること
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
実機 gate では、boot、NFS root mount、root overlay、systemd failed unit、必要な workload readiness を分けて確認する。
注意点
- 稼働中 client が参照している NFS lower rootfs を更新すると stale file handle が出ることがある。
- host 固有 canary / rollback override は一時設定として扱い、検証後は stage 日付由来へ戻す。
- paired release の片側だけ build に失敗した状態で promote しない。
- manifest は release pruning の判断材料にもなるため、build 後に残す。