Raspberry Pi PXEのTFTP artifactとNFS rootfsを同じrelease境界で扱う

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.txtcmdline.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 後に残す。