PXE GentooでNFS rootにtmpfs overlayを重ねる設計
Posted:
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_ipaddr、openwrt_dhcp_ntp_servers、openwrt_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/work | reboot で必ず初期化され、再現性が高い | reboot 後に rootfs 上の変更は残らない |
| remote persistent upper/work | node ごとの変更を保持できる | base rootfs 更新を upper が隠す、差分調査が難しい |
| local disk upper/work | NFS 依存を減らせる | disk 故障や古い差分の掃除が別問題になる |
rootfs を immutable に近づける目的なら、tmpfs upper/work の方が運用は単純になる。永続化が必要なものは、root overlay ではなくアプリケーション単位で分けた方がよい。
dracutで見る場所
rd.overlayfs=1 で root overlay を作る場合、調査は mount と pre-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/overlayfs、workdir=/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 line | rootfs release、NFS root、overlayfs 有効化 |
| DHCP option などの metadata | role、stage、ansible-pull の対象制御 |
| persistent volume | application data、logs、container runtime data |
| tmpfs overlay | rootfs の一時的な書き込み差分 |
root overlay は boot の再現性を守るためのもの、metadata は起動後の構成制御のもの、と分けるのが安全である。
よくある失敗
| 症状 | 見る場所 | 原因候補 |
|---|---|---|
| NFS root が mount できない | rd.break=initqueue / rd.break=mount | NIC driver、DHCP、NFS export、root= path |
| overlay root にならない | rd.break=mount / rd.break=pre-pivot | rd.overlayfs=1 不足、70overlayfs 不在、overlay module 不足 |
| reboot で変更が消える | systemd 起動後 | tmpfs upper 設計どおり |
| rootfs 更新後も古い状態が見える | mount options / upper location | persistent upper が古い lower を隠している |
検証環境では、まず tmpfs upper を正として成立させ、それでも必要な state だけを後から永続 mount に切り出す方が追いやすい。