PXE GentooでNFS rootにtmpfs overlayを重ねる設計

PXE GentooでNFS rootにtmpfs overlayを重ねる設計

PXE boot の root filesystem を NFS に置くと、rootfs 更新や rollback は楽になる。一方で、各 node が rootfs に直接書き込むと、検証環境ほど状態が散らばりやすい。

そこで、NFS root を read-only lower として扱い、PXE client 側の tmpfs を upper/work にした overlayfs root にする。

この構成では、rootfs の差分は reboot で消える。永続化が必要なものだけを、用途別の volume や明示的な mount に逃がす。

本文中の 192.0.2.0/24 は説明用の documentation range である。OpenWrt 実機で NFS root / TFTP / DHCP を反映する場合は、外部 inventory の openwrt_lan_ipaddropenwrt_dhcp_ntp_serversopenwrt_gentoo_server_host を実値として明示し、documentation range が endpoint に残っていれば止める。

基本構成

flowchart TD
  A[PXE firmware<br/>DHCP + TFTP] --> B[Kernel + initramfs]
  B --> C[dracut<br/>network + nfs]
  C --> D[NFS root<br/>read-only lower]
  C --> E[tmpfs<br/>upper + work]
  D --> F[overlayfs merged root]
  E --> F
  F --> G[switch_root]
  G --> H[systemd]

root overlay の目標状態は次のような形になる。

lowerdir=<nfs-root>
upperdir=/run/overlayfs
workdir=/run/ovlwork
merged=/

dracut-ng の 70overlayfs を使う場合、kernel command line では rd.overlayfs=1 を指定する。

採用する方針

  • root overlay の upper/work は client 側 tmpfs に置く
  • upper/work は reboot で消える前提にする
  • NFS root は release 単位で管理し、boot 側の command line で切り替える
  • 永続化したい data は root upper 全体ではなく、用途ごとの明示的な mount へ分離する
  • role、stage、host classification などの metadata は root overlay の選択と分けて扱う

この設計では「rootfs を更新したのに node が古い差分を見続ける」という問題を避けやすい。

remote upper/workを採用しない理由

host ごとの upper/work を NFS や別ストレージに永続化する案もある。しかし、PXE + mutable rootfs の検証環境では、次の問題が出やすい。

利点問題
tmpfs upper/workreboot で必ず初期化され、再現性が高いreboot 後に rootfs 上の変更は残らない
remote persistent upper/worknode ごとの変更を保持できるbase rootfs 更新を upper が隠す、差分調査が難しい
local disk upper/workNFS 依存を減らせるdisk 故障や古い差分の掃除が別問題になる

rootfs を immutable に近づける目的なら、tmpfs upper/work の方が運用は単純になる。永続化が必要なものは、root overlay ではなくアプリケーション単位で分けた方がよい。

dracutで見る場所

rd.overlayfs=1 で root overlay を作る場合、調査は mountpre-pivot が中心になる。

rd.break=mount
rd.break=pre-pivot
rd.shell

initramfs 内では次を確認する。

cat /proc/cmdline
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /sysroot
mount | grep -E 'nfs|overlay|LiveOS'
ls -ld /run/overlayfs /run/ovlwork

systemd 起動後は次を見る。

findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
mount | grep -E 'overlay|nfs'

/ が overlayfs になっていて、upperdir=/run/overlayfsworkdir=/run/ovlwork を含んでいれば、tmpfs upper の root overlay として成立している。

command lineの考え方

例として、NFS root と overlayfs root を有効にする command line は次のような形になる。

root=nfs4:192.0.2.10:/exports/gentoo/<release>/nfs,vers=4.2,proto=tcp ip=dhcp rw rd.neednet=1 rd.overlayfs=1 rd.shell

本番に近い常用設定では、調査用の rd.break=* は外す。rd.debug もログ量が大きいため、常時有効化するかは環境のログ保存先と相談する。

role metadataとroot overlayを分ける

PXE client に role や stage を渡したい場合、DHCP option や別 metadata で渡すことができる。

ただし、その metadata で root overlay の upper/work を切り替える設計にすると、host ごとの差分が増えやすい。

使い分けは次のようにすると整理しやすい。

種別使い道
kernel command linerootfs release、NFS root、overlayfs 有効化
DHCP option などの metadatarole、stage、ansible-pull の対象制御
persistent volumeapplication data、logs、container runtime data
tmpfs overlayrootfs の一時的な書き込み差分

root overlay は boot の再現性を守るためのもの、metadata は起動後の構成制御のもの、と分けるのが安全である。

よくある失敗

症状見る場所原因候補
NFS root が mount できないrd.break=initqueue / rd.break=mountNIC driver、DHCP、NFS export、root= path
overlay root にならないrd.break=mount / rd.break=pre-pivotrd.overlayfs=1 不足、70overlayfs 不在、overlay module 不足
reboot で変更が消えるsystemd 起動後tmpfs upper 設計どおり
rootfs 更新後も古い状態が見えるmount options / upper locationpersistent upper が古い lower を隠している

検証環境では、まず tmpfs upper を正として成立させ、それでも必要な state だけを後から永続 mount に切り出す方が追いやすい。