恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
PXE批量装机从原理到实战:DHCP+TFTP+HTTP+kickstart无人值守部署
首页
资讯中心
/
PXE批量装机从原理到实战:DHCP+TFTP+HTTP+kickstart无人值守部署
PXE批量装机从原理到实战:DHCP+TFTP+HTTP+kickstart无人值守部署
发布时间:2026/10/16 8:12:45
做运维的人迟早会遇到批量装机这件事。一天一两台机器手工插U盘还能忍可一旦面对几十上百台的物理机或虚拟机一个人通宵装系统装到后面手指头都是机械动作甚至还会因为某个镜像版本漏了更新把整批机器装成旧版本第二天又要推倒重来。我的解决办法是搭一套PXE批量装机环境让客户端开机时从网卡引导自动完成系统安装。这篇文章就从原理、部署、配置到踩坑完整拆一遍PXE批量装机适合正在做Linux运维、网络管理或者负责机房/实验室环境交付的工程师。1. 为什么需要PXE批量装机1.1 传统装机方式的痛点手工装机的方式看着简单实际上一旦规模上来问题非常多。拿U盘安装来说你需要先准备一个安装盘一台一台插上去选择启动项等待复制文件然后手工分区、设置密码、配置网络。如果是同样的系统装十台重复劳动就非常明显。更难受的是机器数量一多很容易搞混哪台装了哪个版本、哪台配了哪组网段。我见过有同事在新一批机器上因为U盘镜像版本不一致装出来的系统底层驱动都不一样最后排查环境问题时浪费了大半天时间。光盘装机更不用提还得一台台换盘光驱故障率也不低盘片损坏、读取变慢都是实际会遇到的事。远程机房场景下尤其麻烦不可能为了重新装一台机器专门跑一趟现场哪怕有远程管理卡能不能挂载ISO还要看硬件环境。PXE批量装机解决的正是这类问题客户端只要支持网络启动现在主流服务器和多数虚拟化平台都支持开机后就能从网络自动获取引导文件走完安装流程全程不需要人工干预。整个过程中人的工作被集中到“准备服务端”这一步之后只要批量开机就行。1.2 PXE的工作流程PXE全称是Preboot eXecution Environment本质是Intel定义的一套网络引导标准。客户端在BIOS/UEFI阶段如果配置了网卡启动它会向网络发DHCP请求拿到IP之后还会拿到两个关键参数一个是TFTP服务器的地址另一个是要下载的引导文件名称。整个流程拆开看是这样客户端开机网卡固件发出DHCP广播。DHCP服务器分配IP并同时返回next-server和filename字段。客户端从TFTP服务器下载PXE引导程序传统BIOS下通常是pxelinux.0UEFI下是grubx64.efi之类。引导程序读取TFTP根目录下的配置文件如pxelinux.cfg/default里面写明了要加载哪个内核、initrd以及启动参数。内核和initrd下载完成后内核启动挂载HTTP/NFS服务器上的系统镜像源。安装程序以Linux为例是Anaconda开始工作如果配置了kickstart文件就能全自动安装否则会进入手动安装界面。理解了这条链路后面的配置就有方向了。PXE不是一个独立服务而是DHCP、TFTP、HTTP/NFS、引导程序、安装镜像这几个组件互相配合的结果。1.3 适用场景判断PXE不是所有场景都适合。我的经验是以下情况收益最大同一型号或同一批硬件规格的机器数量较多系统版本要求一致。无人值守场景比如机房巡检后需要批量重装或者实验环境需要快速恢复。多台机器需要同时安装不同系统版本可以通过启动菜单选择仍然比插盘高效。远程机房物理接触困难但网卡启动和服务器电源管理可用。如果只是单台机器急需重装或者网络环境极不稳定、交换机端口有安全限制那就老老实实用U盘/ISO没必要为了单台机器搭一套PXE。另外PXE依赖广播和DHCP如果网络里存在严格的端口隔离或DHCP Snooping策略需要先协调好网络配置否则会出现各种“找不到启动服务”的问题。2. 环境准备与组件选型2.1 最小化组件清单在动手之前先把需要准备的东西列全。基于我实际搭建的最小体系以下组件缺一不可组件作用常见实现DHCP服务分配IP同时告知引导文件位置dnsmasq、isc-dhcp-serverTFTP服务提供pxelinux.0、内核、initrd等小文件tftp-hpa、dnsmasq内置tftpHTTP服务提供系统镜像和kickstart文件nginx、apache、lighttpd引导程序负责读取菜单并加载内核syslinuxBIOS、grub2-efiUEFI系统镜像安装源可以是ISO挂载目录也可以解包后的树CentOS/Debian/Ubuntu的ISO额外建议准备一台测试用的虚拟机或物理机配置成“磁盘启动失败后自动回退到网络启动”这样不影响已有系统可以反复验证。我比较推荐的组合是DHCP用dnsmasq或isc-dhcp-serverTFTP用tftp-hpaHTTP用nginx。如果你只是为了快速测试也可以用dnsmasq同时承担DHCP和TFTP进一步减少服务数量。不过正式环境我更倾向于拆开便于日志排查和故障隔离这个问题下面会详细说。2.2 网络规划与IP分配策略PXE环境里的网络规划需要提前想好否则后面会非常痛苦。我通常用一个独立的管理网段来跑PXE比如模拟项目环境里用192.168.30.0/24这个网段。服务器IP固定为192.168.30.10网关是192.168.30.1DHCP地址池设为192.168.30.100到192.168.30.200池子外面再预留一些IP给管理口、网络设备和其他固定主机。地址池大小的估算逻辑是如果单次批量装50台池子最好至少能有2倍数量的地址避免客户端因租约问题反复冲突。DHCP租约时间在PXE安装场景下可以缩短比如600秒因为安装完成后系统就不再用这个临时租约了。如果你的环境是跨VLAN部署需要在三层交换机上配置DHCP RelayDHCP服务器还要能识别来自不同VLAN的请求并且返回对应的TFTP服务器地址。这部分配置相对复杂建议第一次搭PXE时先在同网段跑通再考虑跨VLAN。2.3 传输协议的选型思路PXE引导阶段小文件用的是TFTP这点由PXE标准决定。但进入安装程序后系统镜像源的访问协议是可以自由选择的常见的有NFS、HTTP、FTP。我更推荐用HTTP做安装源理由有几个HTTP的端口固定是80/8080防火墙策略简洁不容易被中间设备拦截。HTTP是基于TCP的传输大文件时比NFS和TFTP更稳定特别在并发客户端多的时候不会像TFTP那样频繁丢包重传。权限配置简单只要nginx或apache目录可读即可不需要考虑NFS的exports、SELinux布尔值、客户端挂载选项等一堆细节。NFS也不是不能用早期很多教程喜欢用NFS因为它挂载后可以直接读取镜像目录。但实际用下来NFS对网络抖动更敏感且NFS服务端配置稍有不慎就会出现nobody权限问题客户端挂载后看到目录但无法读取文件。HTTP则没有这个烦恼你只需要确保目录索引可读安装器直接从URL拉文件就行。3. 核心服务部署DHCP、TFTP、HTTP与PXE引导3.1 DHCP地址池与引导参数配置以isc-dhcp-server为例核心配置写在/etc/dhcp/dhcpd.conf里。针对PXE关键不是地址池而是next-server和filename这两个参数它们是客户端找到引导程序的钥匙。subnet 192.168.30.0 netmask 255.255.255.0 { range 192.168.30.100 192.168.30.200; option routers 192.168.30.1; option domain-name-servers 192.168.30.1; default-lease-time 600; max-lease-time 7200; next-server 192.168.30.10; filename pxelinux.0; }next-server告诉客户端“你去192.168.30.10下载引导文件”filename告诉它“要下载的文件名是pxelinux.0”。这两个字段协同工作缺一不可。如果你的网络里已经有其他DHCP服务器比如路由器或防火墙自带DHCP一定要避免冲突。同一个广播域里出现多个DHCP服务器客户端获得的IP可能随机来自其中任何一个PXE引导也会变得不稳定。我的做法是在DHCP服务器上配置ignore unknown-clients或者直接把PXE专用DHCP独立部署在测试VLAN里不让它和日常办公网络混在一起。3.2 TFTP服务与pxelinux.0TFTP的部署不复杂但有几个坑需要注意。先装好tftp-hpa和syslinuxyum install -y tftp-server syslinux # 或是 apt install -y tftpd-hpa pxelinux syslinux-commonsyslinux软件包里提供pxelinux.0引导文件。传统BIOS模式下把它复制到TFTP根目录。TFTP根目录我习惯设置为/var/lib/tftpboot。mkdir -p /var/lib/tftpboot/pxelinux.cfg cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/这里有个容易踩的坑systemd管理的tftp服务默认使用socket激活模式也就是有请求时才启动响应会有一点延迟。批量安装时几十台机器同时请求socket模式很容易出现部分客户端连接超时。建议禁用tftp.socket只启动tftp.service让进程常驻systemctl disable tftp.socket systemctl enable tftp.service systemctl restart tftp.service接下来是引导菜单文件/var/lib/tftpboot/pxelinux.cfg/default。一个最基础的菜单如下DEFAULT menu.c32 PROMPT 0 TIMEOUT 60 MENU TITLE PXE Boot Menu LABEL linux MENU LABEL Install CentOS 7 x86_64 KERNEL vmlinuz APPEND initrdinitrd.img inst.repohttp://192.168.30.10/ISO/CentOS7 kshttp://192.168.30.10/ks/ks.cfg这里KERNEL指向的vmlinuz和APPEND里的initrd.img都是从系统镜像的isolinux目录里拷贝出来的。注意它们的路径是相对TFTP根目录的所以直接放在根目录即可。menu.c32来自syslinux它让菜单有基本的图形渲染效果。如果没有这个文件可以只保留DEFAULT和APPEND配置也能启动只是界面是文本列表。3.3 HTTP镜像源和内核启动参数HTTP服务我选择nginx配置也比较省心。把ISO解压到网站目录或者直接挂载ISO到目录也完全可以。mkdir -p /var/www/html/ISO/CentOS7 mount -o loop CentOS-7-x86_64-Minimal.iso /var/www/html/ISO/CentOS7这时候客户端在启动参数里写inst.repohttp://192.168.30.10/ISO/CentOS7安装程序就会从这个HTTP目录里读取安装包元数据和软件包。这里有一个重要细节Anaconda安装程序从内核启动参数获取repo源和kickstart源。如果只给repo不给ks安装程序会进入交互界面询问你语言、键盘、磁盘等设置顶多省去镜像介质步骤。要实现真正无人值守必须用kickstart文件也就是在上面的APPEND里同时指定ks参数。另外如果客户端是UEFI启动pxelinux.0是不能用的。UEFI环境需要对应的EFI引导文件比如grubx64.efi或者shimx64.efi配置文件也变成grub.cfg。检测方法很简单进入启动菜单如果报“文件找不到”而你又确定pxelinux.0位置没问题那就要确认机器是不是UEFI模式。现在新出的服务器和笔记本默认UEFI居多所以我在搭建PXE时会同时准备BIOS和UEFI两套引导文件。4. 自动化无人值守kickstart配置解密4.1 ks.cfg核心段kickstart会自动弹出的安装界面翻译成一份配置文件Anaconda读过之后按文件内容执行。它本质上就是一个文本文件任何人拿到模板都能看懂。一个最小可用的CentOS 7 ks.cfg大致是这样#versionDEVEL install url --urlhttp://192.168.30.10/ISO/CentOS7 lang en_US.UTF-8 keyboard us network --bootprotodhcp rootpw --iscrypted $1$somehash... authconfig --enableshadow --passalgosha512 selinux --disabled firewall --disabled clearpart --all part /boot --fstypexfs --size1024 part / --fstypexfs --size1 --grow part swap --size4096 bootloader --locationmbr %packages core wget vim %end各段的逻辑很清楚url指定安装源network指定网卡获取IP方式clearpart和part负责分区rootpw设置加密后的root密码%packages里写需要安装的软件包组。要注意rootpw字段里的加密hash不能直接放明文密码Anaconda在生成ks时可以通过grub-md5-crypt或openssl生成。实际运维中我习惯先把明文密码写在一个临时文件里用openssl passwd -6一次性生成再粘到ks中这样内容不会泄露。4.2 从手动到无人值守有人可能觉得既然有了ks文件是不是所有情况都能无人值守了并不是。ks配置里如果缺少某些必填项或者写了无效参数Anaconda会弹回交互界面。比如network段如果同时写了多个网卡且没有指定哪块安装器可能还是会问你网络配置。我的建议是第一次测试时不要把ks配置写得太复杂先用最简模板跑通再逐步增加软件包、分区、网络、自定义脚本。让问题减到最少才方便定位是PXE链路的问题还是ks本身的问题。在启动参数里加上kshttp://192.168.30.10/ks/ks.cfg后客户端安装过程完全不需要键盘鼠标。如果你在一个物理机房间里同时开50台机器只需要保证所有机器都从网卡启动然后等待即可。安装完的系统会自动重启到时候根据预设策略就能进入正式系统了。4.3 批量场景中的参数化技巧批量装机真正的难点不在“装完”而在“每台机器拿到符合预期的配置”。如果50台机器都通过DHCP拿到临时IP安装出来的系统也都用DHCP看起来可以但生产环境通常希望服务器分配固定IP或者主机名按照一定规则生成。一个很实用的技巧是用%pre脚本在系统安装前执行一段shell然后动态生成一个包含网络配置的ks片段再通过%include引入。比如我在HTTP服务器上放一个mac_ip.txt文件每行格式是“MAC地址 IP地址”%pre脚本里用客户端自身的MAC匹配行把IP写入临时文件/tmp/network.ks%pre MAC$(cat /sys/class/net/$(ls /sys/class/net | grep -E ^e|^en | head -1)/address) IP$(curl -s http://192.168.30.10/ks/mac_ip.txt | grep $MAC | awk {print $2}) echo network --bootprotostatic --ip$IP --netmask255.255.255.0 --gateway192.168.30.1 --nameserver192.168.30.1 --hostnamenode-${IP##*.} /tmp/network.ks %end %include /tmp/network.ks这样每台机器在开始分区前就已经确定了IP和主机名后续安装完可以直接投入使用。如果一台机器临时换了网卡MAC对不上脚本会生成空文件安装就会失败或退回交互界面这反而会提醒我们“这台机器的资产信息要更新了”。5. 完整安装流与故障排查手册5.1 端到端启动流程演示把前面所有配置串起来完整的装机流程如下在PXE服务器上启动nginx、tftp、dhcp服务。确保系统镜像目录可访问在测试机浏览器或curl验证http://192.168.30.10/ISO/CentOS7/repodata/repomd.xml返回正常。测试机开机进入BIOS/UEFI启动菜单选择网络启动通常名字里有PXE或Network Boot字样。网卡从DHCP拿IP再通过TFTP下载引导文件。屏幕上出现PXE菜单默认配置指向Linux安装项。内核和initrd加载Anaconda启动。安装程序读取ks.cfg自动分区、安装软件包、设置root密码。安装完成后机器自动重启此时要提前设置下一次启动从硬盘启动避免再次进入PXE循环。这里特别强调第八步PXE装完重启后再进PXE的话系统会重复安装。解决办法有三个一是控制启动顺序让硬盘启动优先于网络启动二是在ks最后加一个reboot命令并且把dhcp的租约时间设短让客户端重启时已经拿不到原地址三是用Cobbler这类系统自动处理。最推荐第一种因为最可控。5.2 五个高频问题速查表这些年排查PXE问题我总结了一些固定套路。下面这张表可以直接作为排查手册用现象常见原因处理方法客户端提示PXE-E61: Media test failure网卡没有获取到DHCP地址或网线/交换机端口问题确认DHCP服务运行、交换机端口UP、VLAN没配错能获取IP但下载pxelinux.0超时TFTP服务没开或防火墙拦截检查tftp进程和防火墙禁用tftp.socket直接常驻服务提示找不到配置文件或文件格式错误pxelinux.0路径不对或pxelinux.cfg/default缺失核对TFTP根目录结构并用tftp客户端在本机测试下载文件引导菜单能显示但加载内核卡住vmlinuz/initrd.img文件缺失或路径错误确认文件在TFTP根目录且文件名大小写一致安装开始后报“找不到安装源”HTTP目录无法访问或inst.repo参数写错用curl验证URL检查nginx配置核对镜像挂载路径UEFI机器无法通过PXE启动BIOS菜单缺少EFI引导文件或DHCPfilename指向pxelinux.0改用grubx64.efi引导并为UEFI客户端准备grub.cfg5.3 从PXE到更完整的批量装机系统PXE只是批量装机的地基真正生产级的环境往往需要在此基础上增加更多能力比如资产登记、版本管理、装机任务编排、事后审计等。我见过不少团队在PXE上面再封装一层Web界面让操作人员不用直接编辑DHCP和TFTP配置文件而是通过界面提交装机任务后端自动生成对应菜单项并记录MAC/IP的对应关系。这个方向有两个收益一是减少误操作因为所有配置都从模板生成不会再出现手误删掉一个参数导致整批失败的情况二是装机状态可视化每台机器处于“待装中、安装中、已完成、失败”的哪个状态有没有进入安装界面都能通过日志和API汇总。如果你只是个人维护几十台机器写几个shell脚本也能做到类似效果。核心把下面几个动作自动化起来就不会差根据MAC地址自动生成IP和主机名。根据主机名自动选择对应软件包配置。每一次装机都打印完整日志方便回看失败原因。PXE不会替代所有装机方式但它是批量运维体系里不可回避的基础能力。我自己的体会是第一次完整跑通PXE链路后再去接触更复杂的自动化运维系统很多概念都会豁然开朗。因为那些系统再怎么封装底层仍然是DHCP、TFTP、HTTP、引导文件和kickstart这些组件在协同工作。如果看完这篇文章想动手验证建议先用虚拟机做一套最小环境把服务端和客户端放在同一个虚拟网络里用snapshot随时回滚试错成本几乎为零。等你在虚拟环境把流程走顺了再找一台空闲物理机做真机验证最后再考虑推广到批量场景。这个小项目最大的价值不是炫技而是让你真正理解“网络引导装系统”这条链路的每一环遇到问题时脑子里能直接浮现出对应的服务日志。