问题

问题

我可以使用 Synology DS 1618+ 作为 TFTP 和 NFS 服务器,通过 NFS 在 Raspberry Pi 4b 上网络启动 Ubuntu 20.04。但我想保护根文件系统,以便overlayroot多台机器可以从同一个根目录同时运行。这对我来说行不通。我问了一个问题几天前我在 Ask Ubuntu 上问过这个问题,但并没有得到任何有用的见解。我现在对这个问题有了更多的了解,想在这里为更广泛的受众重新表述这个问题。

问题

虽然我可以使用 NFS 在 RPi4 上通过网络启动 Ubuntu 20.04,但只要我启用overlayroot( overlayroot="tmpfs:recurse=0"),系统就会以degraded( systemctl is-system-running) 的状态启动。这似乎很明显某物与……有关overlayroot

在这种状态下,只有root可以登录。其他用户都无法通过登录/密码提示。

检查syslog发现,启动过程中出现的第一个错误是 的启动system-networkd,它失败并显示消息(“不支持操作”)。进一步检查发现systemd-networkd试图以用户身份运行(system-network)。由于system-netwworkd无法启动,因此许多其他服务也无法启动:

  UNIT                      LOAD   ACTIVE SUB    DESCRIPTION                   
● atd.service               loaded failed failed Deferred execution scheduler  
● avahi-daemon.service      loaded failed failed Avahi mDNS/DNS-SD Stack       
● systemd-networkd.service  loaded failed failed Network Service               
● systemd-resolved.service  loaded failed failed Network Name Resolution       
● systemd-timesyncd.service loaded failed failed Network Time Synchronization  
● systemd-networkd.socket   loaded failed failed Network Service Netlink Socket

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

6 loaded units listed.

配置

DHCP服务器

我有一对 ISC DHCP 服务器,它们已经运行了一年多。我对它们的配置进行了以下更改以支持网络启动:

# DHCP configuration for PXE boot of RPI4

option tftp-server-name "192.168.8.20"; #option 66
option bootfile-name "bootcode.bin"; #option 67

option vendor-class-identifier code 60 = string;
option vendor-encapsulated-options code 43 = string;
option space RPi code width 1 length width 1;
option RPi.discovery code 6 = unsigned integer 8;
option RPi.menu-prompt code 10 = text;
option RPi.menu-item code 9 = text;

option vendor-class-identifier "PXEClient";
option vendor-encapsulated-options "Raspberry Pi Boot";
vendor-option-space RPi;
option RPi.discovery 3;
option RPi.menu-prompt "PXE";
option RPi.menu-item "Raspberry Pi Boot";

filename "pxelinux.0";

next-server 192.168.8.20;
option tftp-server-address 192.168.8.20;

我承认我并不完全理解这一点,但它确实有效:-) 我确信其中有些东西是 RPi4 没有使用到的。

树莓派 4b

我已经设置了 RPi4 引导加载程序,如下所示:

$ sudo rpi-eeprom-config 
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=1
BOOT_ORDER=0xf21
TFTP_PREFIX=1
TFTP_PREFIX_STR=RPi4-Ubuntu/

Synology DS 1618+ NAS

TFTP 服务器

在启动时,RPi4 发送TFTP_PREFIX_STR上述文件并从 Synology NAS 上的 TFTP 服务器接收以下文件:

bcm2710-rpi-2-b.dtb       bootcode.bin  initrd.img
bcm2710-rpi-3-b.dtb       boot.scr      overlay_map.dtb
bcm2710-rpi-3-b-plus.dtb  cmdline.txt   overlays
bcm2710-rpi-cm3.dtb       config.txt    start4cd.elf
bcm2710-rpi-zero-2.dtb    fixup4cd.dat  start4db.elf
bcm2711-rpi-400.dtb       fixup4.dat    start4.elf
bcm2711-rpi-4-b.dtb       fixup4db.dat  start4x.elf
bcm2711-rpi-cm4.dtb       fixup4x.dat   start_cd.elf
bcm2837-rpi-3-a-plus.dtb  fixup_cd.dat  start_db.elf
bcm2837-rpi-3-b.dtb       fixup.dat     start.elf
bcm2837-rpi-3-b-plus.dtb  fixup_db.dat  start_x.elf
bcm2837-rpi-cm3-io3.dtb   fixup_x.dat   vmlinuz

这些来自 RPi 的 Ubuntu 20.04 安装映像(分区boot)。我对进行了以下修改config.txt

[pi4]
# Run as fast as firmware / board allows
arm_boost=1

[all]
arm_64bit=1
device_tree_address=0x03000000
enable_uart=1
cmdline=cmdline.txt
kernel=vmlinuz
initramfs initrd.img followkernel

include syscfg.txt
include usercfg.txt

cmdline.txt

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=192.168.8.20:/volume3/pxe/nfs/RPi4-Ubuntu/OS,tcp,rw ip=dhcp rootfstype=nfs elevator=deadline rootwait

NFS 服务器

NFS 服务器提供nfsroot中提到的cmdline.txt根目录 ( /)。这基本上是rootfsUbuntu 发行版的分区。它还提供 Ubuntu 发行版boot分区中的文件,这些文件安装在/boot

exports -v显示以下内容:

/volume3/pxe    192.168.0.0/21(rw,async,no_wdelay,hide,crossmnt,no_subtree_check,insecure_locks,anonuid=1024,anongid=100,sec=sys,insecure,root_squash,no_all_squash)
/volume3/pxe    192.168.8.0/21(rw,async,no_wdelay,hide,crossmnt,no_subtree_check,insecure_locks,anonuid=1024,anongid=100,sec=sys,insecure,root_squash,no_all_squash)
/volume3/pxe    192.168.32.0/21(rw,async,no_wdelay,hide,crossmnt,no_subtree_check,insecure_locks,anonuid=1024,anongid=100,sec=sys,insecure,root_squash,no_all_squash)
/volume3/pxe    192.168.72.0/21(rw,async,no_wdelay,hide,crossmnt,no_subtree_check,insecure_locks,anonuid=1024,anongid=100,sec=sys,insecure,root_squash,no_all_squash)

在启动过程中,Synology NFS 和 RPi4 似乎只会使用 NFSv3。/etc/fstab然而,它们似乎都乐于使用 NFSv4/NFSv4.1。

回到 Pi

有了这样的配置,RPi 就可以以 root 身份通过 NFS 文件系统在网络上顺利启动和运行。然而,此时,为了保护根文件系统不被写入,我继续修改配置文件,使其如下overlayroot所示/etc/overlayroot.conf

overlayroot_cfgdisk="disabled"
#overlayroot=""
overlayroot="tmpfs:recurse=0,debug=1"

(我省略了之前的 160 多行注释。)

当我重新启动时,上述问题又出现了。

请帮助?

我已经尝试了上述方法,分别在 32 位和 64 位 Ubuntu 22.04 上,结果完全相同。我尝试了 Raspberry OS 11(64 位),但它没有提供overlayroot选项。它的替代方案内置于 中raspi-config,不适用于 NFS。所以我没有继续尝试。

然而,基于 Raspberry OS 的做法,我大大简化了 Ubuntu 的 TFTP 配置。

如果问题与 Synology NFS 服务器有关,我不会感到惊讶,但我真的不知道从哪里开始查找。

我当然不会排除我在某个地方犯了错误的想法,所以如果有人能指出这一点,我将不胜感激。

一旦 Ubuntu 22.04 推出,我也会尝试一下。

网上有很多人讨论过如何做这件事。我读了很多文章,并试图采纳他们的意见。我看到过一两篇关于 NFS 根文件系统可能存在问题的文章overlayroot。但我没有看到任何准确描述我试图做的事情的文章。

答案1

虽然花了很长时间才找到答案,但答案相对简单。

如果您在 RPi4 上使用 NFS 网络启动 Ubuntu,则nfsmount随附的klibc(由 Ubuntu 提供)仅支持 NFS v2 和 v3。如果您代替使用nfsmount支持 NFSv4 的系统并且您的根文件系统已成功由 NFSv4 挂载,则overlayroot可以正常工作。

剧透:它是一个上游(即 Debian)漏洞自 2007 年起就存在了。重复:2007 年。

答案2

从 askubuntu 上的同一个问题复制而来:

根本问题似乎是在某些 NFS 服务器配置中行为不正确。也就是说,在未实现 NFSv3 导出的服务器上使用overlayfs时,会出现问题overlayfsv3 的可选 NFSACL 协议扩展. 看起来像这样并不是唯一一个overlayfs在 ACL 方面非常脆弱的情况显然,v3 和 v4 NFS 都存在(仍然存在?)问题。

我能够将问题简化为不涉及启动的问题,而只需 overlayfs 和 NFS 导出。使用从 Ubuntu 机器(确实实现了 NFSACLv3)提供的 Ubuntu 映像的 NFS 导出以及其中带有/tmp/overlaygames/空的upperworkoverlay目录的目录,以下脚本将运行而不会出错:

#!/bin/bash
sudo mount -t nfs -o ro,vers=3 10.99.0.1:/srv/nfs/ubuntu-20.04.3 /media/nfs/
sudo mount -t overlay -o lowerdir=/media/nfs,upperdir=/tmp/overlaygames/upper,workdir=/tmp/overlaygames/workdir/ overlay /tmp/overlaygames/overlay
ls /tmp/overlaygames/overlay/home

运行该脚本后,运行此脚本来卸载并清理:

#!/bin/bash
pushd /tmp/overlaygames
sudo umount overlay
rm -rf workdir
mkdir workdir
sudo umount /media/nfs
popd

现在运行完全相同的脚本,但使用 noacl 选项禁用 NFSACLv3 客户端:

#!/bin/bash
sudo mount -t nfs -o ro,noacl,vers=3 10.99.0.1:/srv/nfs/ubuntu-20.04.3 /media/nfs/
sudo mount -t overlay -o lowerdir=/media/nfs,upperdir=/tmp/overlaygames/upper,workdir=/tmp/overlaygames/workdir/ overlay /tmp/overlaygames/overlay
ls /tmp/overlaygames/overlay/home

将回归熟悉的

ls: cannot open directory '/tmp/overlaygames/overlay/home': Operation not supported

同样,从第一个脚本开始但将 NFS 导出放在 FreeNAS/TrueNAS(FreeBSD)机器上,也会返回,Operation not supported因为 FreeBSD 没有实现 NFSACLv3(通过捕获数据包验证)。

有趣的是,在 FreeBSD 上使用 NFS 共享时指定vers=2似乎工作得很好。当然,与 NFSv3 相比,NFSv2 有一些限制。

相关内容