PXE
- 预启动执行环境(Preboot eXecution Environment,PXE,也被称为预执行环境)提供了一种使用网络接口(Network Interface)启动计算机的机制。这种机制让计算机的启动可以不依赖本地数据存储设备(如硬盘)或本地已安装的操作系统。
在本指南中,PXE 用于通过支持 PXE 的 Option ROM 在目标机器上启动安装介质,适用于安装了服务器的情况。
在开始前,需要先了解下 PXE 启动流程,以理解#服务器搭建,目标设备上的#安装流程以及所需的 Arch Linux 文件。
目标设备会先广播数据包,请求 DHCP 服务器并包含特定的 PXE 选项。接下来,DHCP 服务器会发送包含网络信息(分配给目标设备的 IP 地址)的回应,并通过 DHCP 的特定引导协议(bootstrap protocol,BOOTP)参数提供如 TFTP 服务器地址,初始网络引导程序(initial network bootstrap program,NBP)的下载路径或启动配置文件名称等额外信息。
NBP 会通过 TFTP 从 PXE 服务器传输到目标设备上,然后加载到内存中并执行。内核以及 initramfs 也是通过一样的方式进行传输。
接下来根文件系统会通过以下协议之一进行传输:HTTP,NFS 或 NBD。
首先从下载页获取最新的官方安装映像,以获取启动时需要从服务器传输到客户端的文件。
接下来需要挂载映像:
# mount --mkdir -o loop,ro archlinux-release_date-x86_64.iso /mnt/archiso
其中 release_date 是 ISO 文件名中的发布日期,例如 2022.10.01。
Arch Linux 网络引导映像可以在系统启动时即时下载最新发布的 Arch Linux 版本。请下载适用于你的配置的版本。
pixiecore 提供了一体化解决方案:
- 安装 pixiecore-gitAUR
- 以根用户身份执行
pixiecore quick arch --dhcp-no-bind - 通过 PXE 进行引导
你需要搭建一个 DHCP 服务器和一个 TFTP 服务器来传输 NBP,以及下列服务之一来传输根文件系统:HTTP 服务器,NFS 或 NBD。
激活网卡,并分配一个合适的地址。
# ip link set eth0 up # ip addr add 192.168.0.1/24 dev eth0
你还可以使用网络管理器来配置静态 IP。
为了在安装目标上配置网络并在 PXE 服务端和客户端之间传输文件,需要搭建 DHCP 和 TFTP 服务器。dnsmasq 能同时做到这两点,也很容易配置。
接下来需要配置 dnsmasq,请参考 dnsmasq#TFTP 服务器和 dnsmasq#PXE 服务器。
以下为一些常用配置,其中 tftp_root 为 Arch ISO 的挂载目录(例如 /mnt/archiso)或网络引导程序的挂载路径:
# /etc/dnsmasq.conf
# Listen only to the specified interface interface=eth0 # Do not function as DNS server port=0 # TFTP server setup enable-tftp tftp-root=tftp_root # Log extra information about DHCP transactions (for debug purposes) log-dhcp
要启用 DHCP 服务器并分配 IPv4 地址段,需在配置文件中添加如下一行:
dhcp-range=192.168.0.50,192.168.0.150
如果已有 DHCP 服务器并希望与其搭配使用,请参考 dnsmasq#Proxy DHCP。
下文提供了两种通过不同方式启动到安装介质的示例。
配置完成后,启动 dnsmasq.service。
在配置文件中,使用 dhcp-boot 选项定义要发送的初始引导程序的路径:
dhcp-boot=/boot/syslinux/lpxelinux.0
要发送如配置文件路径等特定引导协议(bootstrap protocol,BOOTP)参数,需使用 dhcp-option-force=flag,value 配置:
dhcp-option-force=209,archiso_pxe.cfg # this file might be under /mnt/archiso/boot/syslinux dhcp-option-force=210,
要根据架构发送文件(此处为用于 UEFI 引导的网络引导映像),请使用:
pxe-service=BC_EFI, "Boot from network BC EFI", ipxe.efi pxe-service=X86-64_EFI, "Boot from network X86-64 EFI", ipxe.efi
剩余的服务器搭建环节仅适用于 Arch ISO,如果使用了网络引导(netboot),那以下部分将不再适用。
得益于 archiso 中的 archiso_pxe_http,archiso_pxe_nfs 和 archiso_pxe_nbd initcpio 钩子,你可以选择使用 HTTP,NFS 或 NBD 进行启动。这三种方式的启动时间基本没有区别,但使用 HTTP 方式能以百分比形式查看 airootfs.sfs 的下载进度。
在所有备选方案中,darkhttpd 是最容易设置的(也是最轻量的)。
然后以 /mnt/archiso 作为文件根目录启动 darkhttpd:
# darkhttpd /mnt/archiso
darkhttpd/1.8, copyright (c) 2003-2011 Emil Mikulic. listening on: http://0.0.0.0:80/
80 端口。如果你没有以根用户启动 darkhttpd,那么它会默认使用 8080 端口,导致目标设备尝试访问无效的 80 端口并启动失败。您需搭建 NFS 服务器并将安装镜像的挂载点作为出口(export)。如果您按照#准备段落做了的话,出口就是 /mnt/archiso。服务器搭建起来后,往 /etc/exports 写入这行:
/etc/exports
/mnt/archiso 192.168.0.0/24(ro,no_subtree_check)
如果服务器已经在运行了,用 exportfs -r -a -v 重新导出文件系统。
安装程序会在 /run/archiso/bootmnt/ 查找 NFS,因此您需要编辑启动选项。在启动菜单按下 Tab,参考如下修改 archiso_nfs_srv:
archiso_nfs_srv=${pxeserver}:/mnt/archiso
或者,您也可以整个过程中都使用 /run/archiso/bootmnt。
在内核加载后,Arch bootstrap 镜像会通过 NFS 复制根文件系统到引导主机(booting host)。这需要一定的时间。一旦复制完成,您就有可运作的系统了。
/etc/nbd-server/config
[generic]
[archiso]
readonly = true
exportname = /srv/archlinux-release_date-x86_64.iso
其中 release_date 是 ISO 文件名中的发布日期,例如 2022.10.01。
启动 nbd.service。
如果已经有了 PXELINUX 配置(例如 DHCP + TFTP)的 PXE 服务器,可以通过在 /tftpboot/pxelinux.cfg/default 文件中添加以下菜单项来通过偏好的方式启动 Arch。
鉴于 PXELINUX 支持 HTTP,可以只通过 TFTP 发送引导加载程序,其它的都通过 HTTP 进行传输,例如:
LABEL archlinux
MENU LABEL Arch Linux x86_64
LINUX http://httpserver/path/to/extracted/Arch/ISO/arch/boot/x86_64/vmlinuz-linux
INITRD http://httpserver/path/to/extracted/Arch/ISO/arch/boot/x86_64/initramfs-linux.img
APPEND archisobasedir=arch archiso_http_srv=http://httpserver/path/to/extracted/Arch/ISO/ cms_verify=y
SYSAPPEND 3
TEXT HELP
Arch Linux 2022.10.01 x86_64
ENDTEXT
如果使用 NFS 和 NBD,那么必须通过 TFTP 传输内核及 initramfs。以 NFS 为例:
LABEL archlinux
MENU LABEL Arch Linux x86_64
LINUX /path/to/extracted/Arch/ISO/arch/boot/x86_64/vmlinuz-linux
INITRD /path/to/extracted/Arch/ISO/arch/boot/x86_64/initramfs-linux.img
APPEND archisobasedir=arch archiso_nfs_srv=pxeserver:/run/archiso/bootmnt cms_verify=y
SYSAPPEND 3
TEXT HELP
Arch Linux 2022.10.01 x86_64
ENDTEXT
其中 LINUX 和 INITRD 路径是相对于 TFTP 根路径的。对于 NBD,需要将上面的 archiso_nfs_srv 替换为 archiso_nbd_srv。可以参考一下 Arch Linux ISO 中的 boot/syslinux/archiso_pxe.cfg 示例文件。
无论使用了哪种方法,都必须在尝试通过网络挂载安装介质前通过 ip= 参数让内核拉起网络接口。如果目标设备上有多个有线网卡,或是需要在 archiso 启动后预配置 resolv.conf,就需要传递 BOOTIF= 参数。你可以通过 sysappend mask 3(即 1 + 2)来自动传递这些参数。所有可用启动参数请参考 README.bootparams。
在进行该部分操作前,需要知道如何让你的目标设备进行 PXE 引导,通常在正常引导时屏幕角落会提示进行 PXE 引导需要按下的按键。例如在 IBM x3650 上按下 F12 会出现一个引导菜单,可以选择第一项 Network;在 Dell PE 1950/2950 上按下 F12 会直接进行 PXE 引导。
通过查看 PXE 服务器的 journald,可以了解 PXE 早期启动阶段时的具体流程:
# journalctl -u dnsmasq.service -f
dnsmasq-dhcp[2544]: DHCPDISCOVER(eth1) 00:1a:64:6a:a2:4d dnsmasq-dhcp[2544]: DHCPOFFER(eth1) 192.168.0.110 00:1a:64:6a:a2:4d dnsmasq-dhcp[2544]: DHCPREQUEST(eth1) 192.168.0.110 00:1a:64:6a:a2:4d dnsmasq-dhcp[2544]: DHCPACK(eth1) 192.168.0.110 00:1a:64:6a:a2:4d dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/pxelinux.0 to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/whichsys.c32 to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_pxe_choose.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/ifcpu64.c32 to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_pxe_both_inc.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_head.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_pxe32.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_pxe64.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/archiso_tail.cfg to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/vesamenu.c32 to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/boot/syslinux/splash.png to 192.168.0.110
在通过 TFTP 加载了 pxelinux.0 和 archiso.cfg 后,应该会出现带有多个选项的 syslinux 菜单,这时候需选择 Boot Arch Linux (x86_64) (HTTP)。
接下来将通过 TFTP 传输架构对应的内核与 initramfs:
dnsmasq-tftp[2544]: sent /mnt/archiso/arch/boot/x86_64/vmlinuz to 192.168.0.110 dnsmasq-tftp[2544]: sent /mnt/archiso/arch/boot/x86_64/initramfs-linux.img to 192.168.0.110
如果一切正常,你将可以在 darkhttpd 上看到 PXE 目标设备的一系列活动。这时 PXE 目标设备将加载内核并初始化:
1348347586 192.168.0.110 "GET /arch/aitab" 200 678 "" "curl/7.27.0" 1348347587 192.168.0.110 "GET /arch/x86_64/root-image.fs.sfs" 200 107860206 "" "curl/7.27.0" 1348347588 192.168.0.110 "GET /arch/x86_64/usr-lib-modules.fs.sfs" 200 36819181 "" "curl/7.27.0" 1348347588 192.168.0.110 "GET /arch/any/usr-share.fs.sfs" 200 63693037 "" "curl/7.27.0"
在通过 HTTP 下载根文件系统后,最终将看到正常 live 环境的根用户 zsh 提示符。
除非你想让所有流量都路由过 PXE 服务器(在正确配置前都无法使用),否则就需要停止 dnsmasq.service 服务,并根据网络环境为安装目标获取新的租约。
你还可以杀掉 darkhttpd:目标已经下载好了根文件系统,不再需要该进程。在进行该操作时,可以顺便卸载掉安装映像:
# umount /mnt/archiso
这时候就可以根据安装指南进行安装了。
copytoram initramfs 选项可以控制在启动早期时是否将整个根文件系统复制到内存中。
强烈建议不去改动该选项,且只在必要的时候禁用(物理内存小于 ~256MB)。如果要这么做,需向内核参数加入 copytoram=n 设置。
copytoram=n 和 archiso_pxe_http 不能同时使用。如果 PXE 目标设备使用的是内部网络(例如 192.168.1.0/24),但还需要访问互联网(如需要安装软件包),那么就需要配置 masquerade/source nat。PXE 服务器上必须有连接到互联网的单独网卡。可以使用如下命令让目标设备访问到互联网:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
要将配置持久化,需使用如下命令:
iptables-save -f /etc/iptables/iptables.rules
然后启用 iptables.service。
具体信息请参考 Simple stateful firewall#Setting up a NAT gateway 和网络分享#启用 NAT。
FS#36749 causes default predictable network interface renaming to fail and then DHCP client to fail because of it. A workaround is to add the kernel boot parameter net.ifnames=0 to disable predictable interface names.
When using VirtualBox to test your configuration, the virtual machine may get stuck at:
Probing EDD (edd=off to disable)... ok
While PXE booting with a real machine works fine. The problem may be because you have set several CPU cores to your client machine, and you set its type as Other and version as Other/Unknown (64 bit). So VirtualBox does not know which paravirtualization interface to use by default.
Adding loglevel=7 to the kernel parameters lets you see where it actually got stuck:
[ 0.063697] smp: Bringing up secondary CPUs... [ 0.103768] x86: Booting SMP configuration:
To resolve this, either use one CPU core, or go to Machine > Settings > System > Acceleration and set one of the following paravirtualization interface: Minimal, Hyper-V or KVM.