32.8. 从 PXE 启动一个 NFS 根文件系统

原作者 Craig Rodrigues.

Intel® 预启动执行环境 (PXE) 能让操作系统从网络启动。 通常由近代主板的 BIOS 提供 PXE 支持,它可以通过在 BIOS 设置里选择从网络启动开启。 一个功能完整的 PXE 配置还需要正确地设置 DHCPTFTP 服务。

当计算机启动的时候, 通过 DHCP 获取关于 从 TFTP 得到引导加载器(boot loader)的信息。 在计算机接受此信息以后, 便通过 TFTP 下载并执行引导加载器。 这些记载于 预启动执行环境 (PXE) 规范 的 2.2.1 章节中。 在 FreeBSD 中, 在 PXE 过程中获取的引导加载器为 /boot/pxeboot。 在 /boot/pxeboot 执行之后, FreeBSD 的内核被加载, 接着是其他的 FreeBSD 相关引导部分依次被执行。 更多关于 FreeBSD 启动过程的详细信息请参阅 第 13 章 FreeBSD 引导过程

32.8.1. 配置用于 NFS 根文件系统的 chroot 环境

  1. Choose a directory which will have a FreeBSD installation which will be NFS mountable. For example, a directory such as /b/tftpboot/FreeBSD/install can be used.

    选择一个可被用户 NFS 挂载并安装有 FreeBSD 的目录。 比如可以使用像 /b/tftpboot/FreeBSD/install 这样的一个目录。

    # export NFSROOTDIR=/b/tftpboot/FreeBSD/install# mkdir -p ${NFSROOTDIR}
  2. 使用如下的命令开启 NFS 服务 第 30.3.2 节 “配置NFS.

  3. 将下面这行加入 /etc/exports 用以通过 NFS 导出此目录:

    /b -ro -alldirs
  4. 重起 NFS 服务:

    # /etc/rc.d/nfsd restart
  5. 按照 第 30.2.2 节 “设置” 中标明的步骤启用 inetd(8)

  6. 将如下这行加入到 /etc/inetd.conf

    tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /b/tftpboot
  7. 重启 inetd:

    # /etc/rc.d/inetd restart
  8. 重新编译 FreeBSD 内核和用户态

    # cd /usr/src# make buildworld# make buildkernel
  9. 把 FreeBSD 安装到 NFS 挂载目录:

    # make installworld DESTDIR=${NFSROOTDIR}# make installkernel DESTDIR=${NFSROOTDIR}# make distribution DESTDIR=${NFSROOTDIR}
  10. 测试 TFTP 服务是否能下载将从 PXE 获取的引导加载器:

    # tftp localhosttftp> get FreeBSD/install/boot/pxebootReceived 264951 bytes in 0.1 seconds
  11. 编辑 ${NFSROOTDIR}/etc/fstab 并加入以下这行挂载 NFS 根文件系统:

    # Device Mountpoint FSType Options Dump Passmyhost.example.com:/b/tftpboot/FreeBSD/install / nfs ro 0 0

    用你的 NFS 服务器主机名或者 IP 地址替换 myhost.example.com。 在此例中, 根文件系统是以“只读”的方式挂载用来防止 NFS 客户端可能意外删除根文件系统上的文件。

  12. 设置 chroot(8) 环境中的 root 密码。

    # chroot ${NFSROOTDIR}# passwd

    此为设置从 PXE 启动的客户机的 root 密码。

  13. 允许 ssh root 登录从 PXE 启动的客户机, 编辑 ${NFSROOTDIR}/etc/ssh/sshd_config 并开启 PermitRootLogin 选项。 关于此选项的说明请参阅 sshd_config(5)

  14. 对 ${NFSROOTDIR} 的 chroot(8) 环境做些其他的定制。 这可以是像使用 pkg_add(1) 安装二进制包, 使用 vipw(8) 修改密码, 或者编辑 amd.conf(5) 映射自动挂载等。例如:

    # chroot ${NFSROOTDIR}# pkg_add -r bash

32.8.2. 配置 /etc/rc.initdiskless 中用到的内存文件系统

如果你从一个 NFS 根卷启动, /etc/rc 如果检测到是从 NFS 启动便会运行 /etc/rc.initdiskless 脚本。 请阅读此脚本中的注释部分以便了解到底发生了什么。 我们需要把 /etc/var 做成内存文件系统的原因是这些目录需要能被写入, 但 NFS 根文件系统是只读的。

# chroot ${NFSROOTDIR}# mkdir -p conf/base# tar -c -v -f conf/base/etc.cpio.gz --format cpio --gzip etc# tar -c -v -f conf/base/var.cpio.gz --format cpio --gzip var

当系统启动的时候, /etc/var 内存文件系统就会被创建并挂载, cpio.gz 就会被复制进去。

32.8.3. 配置 DHCP 服务

PXE 需要配置一个 TFTP 服务器和一个 DHCP 服务器。 DHCP 服务并不要求与 TFTP 服务在同一台机器上, 但是必须能够从你的网络访问到它。

  1. 按照此文档处 第 30.5.7 节 “安装和配置 DHCP 服务器” 方法安装 DHCP 服务。 确保 /etc/rc.conf/usr/local/etc/dhcpd.conf 都配置正确。

  2. /usr/local/etc/dhcpd.conf 中配置 next-serverfilenameoption root-path 选项指向你的 TFTP 服务器的 IP 地址, 以及 TFTP/boot/pxeboot 文件的路径, 和 NFS 根文件系统的路径。 这里一份 dhcpd.conf 实例:

    subnet 192.168.0.0 netmask 255.255.255.0 { range 192.168.0.2 192.168.0.3 ; option subnet-mask 255.255.255.0 ; option routers 192.168.0.1 ; option broadcast-address 192.168.0.255 ; option domain-name-server 192.168.35.35, 192.168.35.36 ; option domain-name "example.com"; # IP address of TFTP server next-server 192.168.0.1 ; # path of boot loader obtained # via tftp filename "FreeBSD/install/boot/pxeboot" ; # pxeboot boot loader will try to NFS mount this directory for root FS option root-path "192.168.0.1:/b/tftpboot/FreeBSD/install/" ;}

32.8.4. 配置 PXE 客户端与调试连接问题

  1. 当客户端启动的时候, 进入 BIOS 配置菜单。 设置 BIOS 从网络启动。 如果之前你所有的配置步骤都正确的话, 那么所有部分应该能 "正常工作"。

  2. 使用 net/wireshark port 查看 DHCPTFTP 的网络流量来调试各种问题。

  3. 确保 pxeboot 能从 TFTP 获取。 在你的 TFTP 服务器上检查 /var/log/xferlog 日志确保 pxeboot 被从正确的位置获取。 可以这样测试上面例子 dhcpd.conf 中所设置的:

    # tftp 192.168.0.1tftp> get FreeBSD/install/boot/pxebootReceived 264951 bytes in 0.1 seconds

    请阅读 tftpd(8)tftp(1)。 其中的 BUGS 列出了 TFTP 的一些限制。

  4. 确保根文件系统能够从 NFS 挂载。 可以这样测试上面例子 dhcpd.conf 中所设置的:

    # mount -t nfs 192.168.0.1:/b/tftpboot/FreeBSD/install /mnt
  5. 阅读 src/sys/boot/i386/libi386/pxe.c 中的代码以了解 pxeboot 加载器如何设置诸如 boot.nfsroot.serverboot.nfsroot.path 之类的变量。 这些变量被用在了 src/sys/nfsclient/nfs_diskless.c 的 NFS 无盘根挂载代码中。

  6. Read pxeboot(8) and loader(8).

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.