PXE批量安装系统:从原理到实战部署指南

发布时间:2026/8/3 1:43:38
PXE批量安装系统:从原理到实战部署指南 1. 项目概述PXE批量安装系统在服务器机房或者运维中心最头疼的场景之一就是面对几十上百台裸机需要安装操作系统。一台台插U盘、挂光驱效率低到令人发指而且容易出错。PXEPreboot eXecution Environment技术就是为了解决这个痛点而生的。简单来说它允许计算机通过网络从远端服务器下载镜像并启动安装程序整个过程无需本地存储介质。对于需要大规模部署Linux或Windows服务器的企业、教育机构、云计算服务商而言掌握PXE批量安装是运维自动化的基本功。这个项目的核心就是搭建一套完整的PXE服务环境实现客户机开机后自动从网络获取引导文件、内核、镜像并完成无人值守的自动化安装。它不仅仅是运行几个命令更涉及到DHCP、TFTP、HTTP/NFS等多种服务的协同以及自动化应答文件的精细配置。下面我将结合自己多次从零搭建和排错的经验拆解整个流程让你不仅能照着做出来更能理解每一步背后的原理遇到问题知道从何下手。2. 核心组件与工作原理拆解在动手之前必须搞清楚PXE启动的“接力赛”是怎么跑的。这能让你在配置时思路清晰排错时有的放矢。2.1 PXE启动流程详解当你给一台支持PXE的客户机通电并设置从网络启动后会发生以下一连串事件DHCP Discover客户机的网卡PXE芯片广播一个DHCP请求。这个请求比较特殊它里面包含了客户机自己是PXE客户端的信息。DHCP Offer (带PXE扩展)网络中的DHCP服务器收到请求后不仅分配一个IP地址给客户机还会在回复报文中附加两个关键选项Next-Server告诉客户机TFTP服务器的IP地址是什么。Bootfile-Name告诉客户机要从TFTP服务器下载的第一个引导文件的名字通常是pxelinux.0或grubx64.efi。TFTP获取引导文件客户机根据DHCP提供的信息向指定的TFTP服务器请求并下载Bootfile-Name指定的文件。这个文件是一个网络引导程序。引导程序执行与配置加载引导程序如PXELINUX或GRUB2被加载到客户机内存并执行。它接着会通过TFTP协议从服务器下载自己的配置文件如pxelinux.cfg/default以及可能需要的模块如ldlinux.c32。内核与初始文件系统下载根据配置文件中的指令引导程序继续通过TFTP或更高效的HTTP、NFS下载操作系统的内核vmlinuz和初始内存盘initrd.img。启动安装程序内核被加载并利用initrd中的工具初始化环境最后启动真正的系统安装程序如Anaconda。获取安装源与应答文件安装程序会按照预设通过HTTP、FTP或NFS协议从服务器获取完整的系统安装包Repository并读取自动化安装的应答文件如Kickstart的.cfg文件。无人值守安装根据应答文件的配置自动完成磁盘分区、软件包选择、用户设置等所有步骤直至安装结束重启。整个流程环环相扣任何一个环节的配置错误都可能导致启动失败。其中DHCP负责指路TFTP负责传递最初的“火种”引导文件而HTTP/NFS则负责搬运“建筑材料”系统镜像。2.2 服务角色与选型考量基于上述流程我们需要部署以下服务DHCP 服务为PXE客户机分配IP并指明引导路径。可以选择isc-dhcp-serverLinux或Windows Server DHCP角色。在简单实验环境甚至可以用路由器自带的DHCP但需要其支持设置Option 66(Next-Server) 和Option 67(Bootfile-Name)。生产环境建议使用独立、可控的DHCP服务器。TFTP 服务用于传输小体积的引导文件。协议简单无需认证。常用tftp-hpa。注意TFTP默认使用UDP 69端口防火墙需放行。文件共享服务用于存放体积庞大的系统镜像和安装包。TFTP效率太低不适合传大文件。通常选择HTTP最通用兼容性最好。可以用Apache、Nginx。推荐Nginx轻量高效。NFS在Linux对Linux的场景下性能很好但Windows客户机支持需要额外配置。FTP较老的方式现在用得少了。引导程序PXELINUX (Syslinux项目)传统BIOS启动的经典选择配置简单直观。GRUB2支持BIOS和UEFI功能更强大是目前的趋势特别是UEFI启动必须用它。自动化应答文件KickstartRed Hat系RHEL, CentOS, Fedora的无人值守安装配置文件。PreseedDebian/Ubuntu系的无人值守安装配置文件。Autounattend.xmlWindows系统的无人值守应答文件。实操心得对于新手我建议从CentOS/RHEL 系统 HTTP(Nginx) PXELINUX/GRUB2 Kickstart这个组合开始。资料最多社区最活跃踩坑了也容易找到解决方案。等这套流程跑通了再迁移到其他发行版或Windows会轻松很多。3. 服务端环境搭建与配置实战我们以一台CentOS 7/8 Stream作为PXE服务器为例IP为192.168.1.10。目标是部署一个可以批量安装CentOS 7和CentOS 8的PXE环境。3.1 基础环境准备首先确保服务器有固定的IP地址关闭SELinux和防火墙或配置正确的放行规则并更新系统。# 设置静态IP (根据你的网络环境修改) # 编辑 /etc/sysconfig/network-scripts/ifcfg-ens33 (网卡名可能不同) BOOTPROTOstatic ONBOOTyes IPADDR192.168.1.10 NETMASK255.255.255.0 GATEWAY192.168.1.1 DNS18.8.8.8 # 关闭并禁用防火墙实验环境生产环境需配置规则 systemctl stop firewalld systemctl disable firewalld # 临时关闭SELinux或设置为permissive模式 setenforce 0 # 永久关闭需修改 /etc/selinux/config将 SELINUXenforcing 改为 SELINUXdisabled # 更新系统 yum update -y3.2 安装并配置DHCP服务安装ISC DHCP服务器yum install dhcp -y编辑DHCP主配置文件/etc/dhcp/dhcpd.conf。一个最简化的、针对PXE的配置示例如下# /etc/dhcp/dhcpd.conf authoritative; # 声明此服务器为权威DHCP服务器 subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; # 分配的IP地址池 option routers 192.168.1.1; # 客户机的默认网关 option subnet-mask 255.255.255.0; option domain-name-servers 8.8.8.8; # DNS服务器 next-server 192.168.1.10; # 关键指向TFTP服务器的IP filename grubx64.efi; # 关键为UEFI客户机指定的引导文件 # 如果还需要支持传统BIOS可以添加一个class和if判断但更常见的做法是统一用GRUB2处理 }注意next-server和filename是PXE的核心。filename的值取决于你准备的引导文件。这里我们先以UEFI模式的grubx64.efi为例。传统BIOS模式下文件名可能是pxelinux.0。启动并设置开机自启systemctl start dhcpd systemctl enable dhcpd检查服务状态和端口监听systemctl status dhcpd netstat -ulnp | grep :67 # DHCP服务监听UDP 67端口3.3 安装并配置TFTP服务安装TFTP服务器和客户端用于测试yum install tftp-server tftp -yTFTP服务由xinetd超级守护进程管理。编辑其配置文件/etc/xinetd.d/tftpservice tftp { socket_type dgram protocol udp wait yes user root server /usr/sbin/in.tftpd server_args -s /var/lib/tftpboot -v # -s 指定根目录-v 启用详细日志排错用 disable no # 关键将yes改为no启用服务 per_source 11 cps 100 2 flags IPv4 }这里指定了TFTP的根目录为/var/lib/tftpboot所有引导文件都将放在这里。启动xinetd服务systemctl start xinetd systemctl enable xinetd验证TFTP服务是否正常# 在服务器本机测试 echo test /var/lib/tftpboot/test.txt tftp localhost -c get test.txt cat test.txt # 应该能看到“test”3.4 准备引导程序GRUB2与启动菜单我们使用GRUB2来同时支持BIOS和UEFI。首先安装GRUB2相关包和syslinux提供pxelinux.0等文件GRUB2的grub2-pc模块会用到yum install grub2-efi-x64-modules grub2-pc grub2-pc-modules grub2-tools syslinux -y创建TFTP根目录结构并复制必要的引导文件mkdir -p /var/lib/tftpboot/{grub,centos7,centos8} # 复制BIOS PXE引导文件 (由syslinux提供) cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ cp /usr/share/syslinux/menu.c32 /var/lib/tftpboot/ # 提供菜单支持 cp /usr/share/syslinux/ldlinux.c32 /var/lib/tftpboot/ # 提供库支持 cp /usr/share/syslinux/libutil.c32 /var/lib/tftpboot/ # 复制UEFI PXE引导文件 (由grub2-efi提供) cp /boot/efi/EFI/centos/grubx64.efi /var/lib/tftpboot/grub/ # 注意路径可能因系统而异 # 或者使用 cp /usr/lib/grub/x86_64-efi/monolithic/grubx64.efi /var/lib/tftpboot/grub/接下来创建GRUB2的配置文件。对于PXEGRUB2会从TFTP根目录下的grub/grub.cfg读取配置。编辑/var/lib/tftpboot/grub/grub.cfgset timeout10 set default0 menuentry Install CentOS 7 - Minimal { set root(tftp,192.168.1.10) linux /centos7/vmlinuz inst.repohttp://192.168.1.10/centos7 inst.kshttp://192.168.1.10/ks/centos7-ks.cfg ipdhcp initrd /centos7/initrd.img } menuentry Install CentOS 8 Stream - Minimal { set root(tftp,192.168.1.10) linux /centos8/vmlinuz inst.repohttp://192.168.1.10/centos8 inst.kshttp://192.168.1.10/ks/centos8-ks.cfg ipdhcp initrd /centos8/initrd.img } menuentry Boot from local disk { exit }关键参数解释set root(tftp,server_ip)指定根设备为TFTP并给出服务器IP。linux /path/to/vmlinuz ...指定内核路径和内核参数。inst.repo指定安装源系统镜像的URL这里我们准备用HTTP服务提供。inst.ks指定Kickstart应答文件的URL实现无人值守。ipdhcp告诉安装程序使用DHCP获取IP。initrd /path/to/initrd.img指定初始内存盘路径。为了让传统BIOS也能通过pxelinux.0引导到GRUB2或直接引导我们还需要配置pxelinux.cfg。创建目录和默认配置文件mkdir -p /var/lib/tftpboot/pxelinux.cfg cat /var/lib/tftpboot/pxelinux.cfg/default EOF default menu.c32 prompt 0 timeout 100 LABEL local MENU LABEL Boot from local drive LOCALBOOT 0 LABEL centos7-grub MENU LABEL Install CentOS 7 via GRUB2 KERNEL grub/grubx64.efi # 对于BIOS可能需要 chain.c32 grub2的core.0 等这里简化直接链式加载UEFI grub如果BIOS支持 # 更标准的做法是为BIOS准备单独的grub2引导这里不展开。 EOF实操心得在实际生产环境中BIOS和UEFI并存是常态。一个干净的策略是让pxelinux.0(BIOS) 和grubx64.efi(UEFI) 都去加载同一个grub.cfg配置文件。这需要为BIOS编译一个grub2-pc格式的core.0镜像并配置pxelinux.cfg/default去加载它。为了简化上述示例做了取舍。如果你的环境全是UEFI可以只配置GRUB2如果全是传统BIOS可以只配置PXELINUX。3.5 配置HTTP服务并放置系统镜像我们使用Nginx提供HTTP服务。安装Nginxyum install nginx -y systemctl start nginx systemctl enable nginx挂载或下载系统ISO镜像。假设你已经下载了CentOS-7-x86_64-Minimal-2009.iso和CentOS-Stream-8-x86_64-latest-boot.iso网络安装镜像更小。# 创建挂载点和镜像存放目录 mkdir -p /mnt/{cdrom7,cdrom8} mkdir -p /usr/share/nginx/html/{centos7,centos8} # 挂载CentOS 7镜像 mount -o loop /path/to/CentOS-7-x86_64-Minimal-2009.iso /mnt/cdrom7 # 复制全部文件到Nginx目录或者只复制Packages和repodata但复制全部最省事 cp -r /mnt/cdrom7/* /usr/share/nginx/html/centos7/ # 挂载CentOS 8 Stream镜像 mount -o loop /path/to/CentOS-Stream-8-x86_64-latest-boot.iso /mnt/cdrom8 cp -r /mnt/cdrom8/* /usr/share/nginx/html/centos8/ # 复制内核和initrd到TFTP目录供引导程序加载 cp /usr/share/nginx/html/centos7/images/pxeboot/vmlinuz /var/lib/tftpboot/centos7/ cp /usr/share/nginx/html/centos7/images/pxeboot/initrd.img /var/lib/tftpboot/centos7/ cp /usr/share/nginx/html/centos8/images/pxeboot/vmlinuz /var/lib/tftpboot/centos8/ cp /usr/share/nginx/html/centos8/images/pxeboot/initrd.img /var/lib/tftpboot/centos8/现在你的HTTP文件结构应该是/usr/share/nginx/html/ ├── centos7/ (包含CentOS 7 ISO全部内容) └── centos8/ (包含CentOS 8 ISO全部内容)确保Nginx有权限读取这些文件并可以通过http://192.168.1.10/centos7/和http://192.168.1.10/centos8/访问。3.6 创建Kickstart无人值守应答文件Kickstart文件定义了安装的所有步骤。我们可以从系统安装后生成的/root/anaconda-ks.cfg作为起点修改或者手动创建。在Nginx目录下创建专门存放ks文件的目录mkdir -p /usr/share/nginx/html/ks编辑/usr/share/nginx/html/ks/centos7-ks.cfg#versionDEVEL # System authorization information auth --enableshadow --passalgosha512 # Use network installation url --urlhttp://192.168.1.10/centos7 # Use graphical install graphical # Run the Setup Agent on first boot firstboot --enable ignoredisk --only-usesda # Keyboard layouts keyboard --vckeymapus --xlayoutsus # System language lang en_US.UTF-8 # Network information network --bootprotodhcp --deviceeth0 --onbooton --ipv6auto --no-activate network --hostnamelocalhost.localdomain # Root password (这里为了演示密码是明文password生产环境务必使用加密密码) rootpw --plaintext password # System services services --enabledchronyd # System timezone timezone Asia/Shanghai --isUtc # System bootloader configuration bootloader --locationmbr --boot-drivesda autopart --typelvm # Partition clearing information clearpart --all --initlabel --drivessda %packages ^minimal core chrony kexec-tools %end %addon com_redhat_kdump --enable --reserve-mbauto %end %post # 安装后脚本可以在这里执行自定义命令如注册系统、安装Agent等 echo PXE Installation Completed on $(date) /root/pxe-install.log %end rebootCentOS 8 Stream的ks文件类似但软件包组名称可能不同如minimal。你需要根据实际需求调整分区、软件包、网络配置等。重要警告示例中使用了明文root密码这是极不安全的生产环境中必须使用加密密码。可以使用python3 -c import crypt; print(crypt.crypt(YourPassword, crypt.mksalt(crypt.METHOD_SHA512)))生成加密密码然后在ks文件中使用rootpw --iscrypted $6$...。4. 客户端测试与全流程验证服务端配置完成后就可以进行客户端测试了。准备一台测试客户机在BIOS/UEFI设置中开启网络引导PXE Boot并将其设置为第一启动项。启动客户机客户机开机后应该会从DHCP服务器获取到IP并显示DHCP...TFTP...等提示信息。加载引导菜单如果一切顺利你会看到我们配置的GRUB2菜单或PXELINUX菜单列出“Install CentOS 7”、“Install CentOS 8”等选项。选择安装项选择“Install CentOS 7 - Minimal”回车。观察启动过程客户机会开始通过TFTP加载内核 (vmlinuz) 和initrd.img然后通过HTTP获取安装源并读取Kickstart文件。无人值守安装之后的过程应该是全自动的无需人工干预直到安装完成自动重启。5. 高级配置与优化技巧基础流程跑通后可以考虑以下优化让系统更健壮、更灵活。5.1 按MAC地址分配固定IP和主机名在生产环境中我们可能希望特定的服务器总是获得固定的IP和主机名。这可以在DHCP配置中通过host声明实现。在/etc/dhcp/dhcpd.conf的subnet块内或外部添加host webserver01 { hardware ethernet 08:00:27:11:22:33; # 客户机的MAC地址 fixed-address 192.168.1.50; # 分配的固定IP option host-name web01.example.com; # 分配的主机名 next-server 192.168.1.10; filename grubx64.efi; }5.2 使用IP或MAC地址定制启动菜单有时我们需要为不同的机器推送不同的安装配置。PXELINUX和GRUB2都支持根据客户机的IP或MAC地址来加载不同的配置文件。PXELINUX它会按特定顺序在pxelinux.cfg目录下查找配置文件。例如客户机IP是192.168.1.123它会依次查找01-08-00-27-11-22-33(MAC地址去掉冒号小写)C0A8017B(IP的16进制192.168.1.123-C0 A8 01 7B)C0A8017(去掉最后一位)C0A801(再去掉一位)... 以此类推直到default你可以为特定机器创建对应的文件实现个性化引导。GRUB2在grub.cfg中可以使用if语句进行条件判断。但更常见的做法是在grub.cfg中设置一个变量然后去加载另一个根据该变量命名的配置文件。或者写一个脚本在GRUB启动时动态生成菜单。5.3 集成多个操作系统镜像除了CentOS你可能还需要安装Ubuntu、Windows等。思路是通用的将对应系统的ISO镜像内容解压到HTTP目录下如/usr/share/nginx/html/ubuntu2004。将其内核 (vmlinuz) 和初始内存盘 (initrd) 复制到TFTP目录下。在GRUB2菜单 (grub.cfg) 或PXELINUX菜单 (pxelinux.cfg/default) 中添加新的启动项指定正确的内核路径、initrd路径和安装源参数。为该系统准备对应的无人值守应答文件Ubuntu用PreseedWindows用Autounattend.xml。5.4 使用Cobbler或Foreman进行自动化管理当需要管理的操作系统版本、硬件类型、配置模板非常多时手动维护PXE配置会变得非常繁琐。这时可以考虑使用像Cobbler或Foreman这样的自动化部署工具。Cobbler一个轻量级的Linux安装服务器它封装了PXE、DHCP、TFTP、HTTP、DNS、Kickstart等服务的配置提供了Web界面和命令行工具来统一管理镜像、配置文件和系统模板。Foreman一个更全面的生命周期管理工具它内置了Cobbler的功能并提供了主机配置、监控、报告等更多功能是大型运维团队的理想选择。使用这些工具你可以通过图形界面轻松添加新镜像、定义安装模板、并将主机分组进行批量部署极大提升了效率。6. 故障排查与常见问题PXE部署过程中难免会遇到问题以下是一些常见故障及排查思路。6.1 客户端无法获取IP地址停留在PXE-E51: No DHCP or proxyDHCP offers were received检查网络物理连接网线、交换机端口。检查DHCP服务状态systemctl status dhcpd查看日志journalctl -u dhcpd -f。检查防火墙确保服务器防火墙放行了UDP 67端口。firewall-cmd --add-servicedhcp --permanent。检查DHCP配置dhcpd配置语法检查dhcpd -t。确认subnet声明覆盖了客户机所在的网段。网络中存在其他DHCP服务器如路由器可能会产生冲突。确保PXE服务器的DHCP响应更快或更优先。6.2 客户端获取IP后TFTP超时或失败PXE-T01/T02/T03错误检查TFTP服务状态systemctl status xinetdnetstat -ulnp | grep :69。检查防火墙放行UDP 69端口。firewall-cmd --add-servicetftp --permanent。检查TFTP根目录权限确保/var/lib/tftpboot及其下的文件有读权限至少or。检查引导文件路径和名称确认filename在DHCP配置中指定的文件名在TFTP根目录下确实存在且文件名大小写匹配。使用tftp客户端本地测试在服务器上tftp localhost -c get grub/grubx64.efi看能否下载。6.3 加载引导菜单后无法下载内核或initrd检查文件路径在GRUB2或PXELINUX配置中指定的vmlinuz和initrd.img路径相对于TFTP根目录是否正确。检查文件是否存在确认文件已正确复制到TFTP目录。查看TFTP服务器日志在/var/log/messages或journalctl -u xinetd中查看TFTP传输日志看是否有“File not found”错误。6.4 内核启动后无法找到安装源Repository检查HTTP/NFS服务确保HTTP服务Nginx正常运行且防火墙放行了80端口。检查安装源URL确认inst.repo或url指定的URL能通过客户机网络正常访问。可以在客户机启动到救援模式用curl测试。检查镜像文件完整性ISO镜像可能损坏重新下载或验证md5/sha256校验和。检查SELinux如果SELinux处于Enforcing模式可能会阻止HTTPD或Nginx访问镜像文件目录。可以暂时设置为Permissive模式排查或使用chcon和semanage fcontext命令修正文件上下文。6.5 Kickstart自动化安装失败检查Kickstart文件语法使用ksvalidator工具检查.cfg文件是否有语法错误。yum install pykickstart -y。检查Kickstart文件URL确保inst.ks指定的URL可访问且文件内容正确。查看安装日志在安装过程中按CtrlAltF2切换到第二个虚拟控制台可以查看详细的安装日志里面通常会有错误信息。安装失败后的/root/ks-post.log和/tmp/anaconda.log也包含重要信息。分区错误这是最常见的失败原因之一。确保Kickstart中的磁盘设备名如sda与目标机器实际磁盘一致。对于多盘机器使用ignoredisk --only-usesda可以避免安装程序误操作其他磁盘。6.6 客户端重启后无法进入系统循环进入PXE检查启动顺序安装完成后客户机BIOS/UEFI中的启动顺序没有改回从硬盘启动。进入BIOS设置调整。DHCP保留如果DHCP服务器为这台客户机固定分配了IP并指定了filename即使安装后它每次网络启动还是会收到PXE引导指令。可以在DHCP配置中为这台主机移除next-server和filename选项或者安装完成后关闭客户机的PXE启动功能。搭建PXE批量安装系统是一个典型的“先苦后甜”的过程。初期配置和排错可能会花费一些时间但一旦体系搭建完成后续的系统部署工作将变得无比轻松和高效。从几台到上百台服务器的安装可能只是喝杯咖啡的功夫。这套体系也是现代数据中心自动化运维、CI/CD流水线中基础设施即代码IaC的重要基石。理解其原理掌握其配置是运维工程师向自动化、平台化进阶的必经之路。