做了这么多年Linux运维,我最怕的不是某个服务突然挂掉,而是机房角落里堆着几十台刚拆箱的裸机。光驱已经成了历史遗物,U盘做启动盘做到手软,量产失败的还得再来一遍,装完系统还要一台台改主机名、配IP、敲安全基线。后来我彻底换了一种思路:让机器开机就自动通过网络完成系统部署,这就是PXE批量装机。这篇文章不绕弯子,直接把我从原理到搭建、再到排错的完整经验讲清楚。如果你经常要交付多台Linux服务器,或者想把系统安装这个“最后的手工环节”纳入自动化,这篇应该能帮你省下不少通宵的时间。
1. PXE到底解决什么问题:从人肉装机到网络引导
1.1 为什么说PXE是“网卡上的装机协议”
PXE的全称是Preboot eXecution Environment,预启动执行环境。它是Intel在1999年前后定下来的一套规范,核心思路很简单:让一台还没装任何操作系统的机器,通过网卡固件去网络上寻找启动程序,再一步步把系统拉起来。你可以把它理解成一台“没有硬盘也能开机找系统”的机器。
传统装机的痛点是穷举式的:要么刻光盘,要么量产U盘,要么用IPMI一个个挂载ISO镜像做远程安装。单台机器也就罢了,一旦机器数量上到两位数,每台都要手工干预,连插拔U盘都成了体力活。PXE的价值在于,它把“系统镜像”和“物理介质”彻底解耦,只要网线通,机器开机后自己会去网络里找安装源。批量交付的场景里,这个能力基本是刚需。
我之前在某次集中交付时,一百多台机器从进场到全部装完系统,靠的就是一套PXE服务端加一个kickstart应答文件,整个过程没有碰过一次键盘。这也是为什么我会说,PXE不是某个软件,而是一整套网络引导协议+部署方案的组合。
1.2 什么样的场景真正适合用PXE
不是所有装机场景都必须上PXE,但下面这几种场景,它是真正的高效工具:
- 批量交付:几十上百台服务器需要一致的系统环境,PXE加应答文件可以保证每台机器装出来的系统一模一样。
- 无人值守演练:想把“装机”这个环节纳入自动化流水线,PXE是天然的入口。
- 硬盘故障重建:机器硬盘坏了,更换新盘后不需要人工介入,开机即自动重装。
- 测试环境回收:测试集群用完重置,用PXE一键还原基线系统,比逐台操作快一个量级。
反过来,如果你只是个人电脑、三五台小集群,那用U盘或者ISO挂载就够了,没必要为PXE单独搭一套服务。PXE是按规模效应发挥价值的,规模太小反而显得重。
1.3 开始之前必须先确认的硬件与网络条件
PXE不是装个软件就能跑,它依赖几个硬性前提:
- 客户端网卡支持PXE引导,现代服务器网卡基本都支持,消费级主板也大多带这个选项。
- BIOS/UEFI固件里开了“网络启动”或“UEFI PXE”功能,很多机器默认没开,装完服务端发现客户端毫无反应,先查这里。
- 存在一个二层可达的孤立网段做测试。这点极其重要,PXE依赖DHCP广播,如果生产网络里有其他DHCP服务器会互相干扰,新手踩这个坑的概率很高。
- 准备一台Linux服务器作为PXE服务端,提供DHCP、TFTP和HTTP/NFS服务。
我在下文里给出的部署方案,就是以“独立测试网段+一台Linux服务器”为假设,这也最接近普通实验室环境,不用改动生产网络就能验证整个链路。
2. 引导链路全流程:DHCP、TFTP、内核启动三幕接力
2.1 一次PXE启动完整经历了什么
很多教程上来就给配置,但我更建议你先吃透流程。一次PXE装机,客户端从开机到进入安装界面,实际上要经历7个步骤:
- 客户端开机,网卡固件完成自检。
- 固件发出DHCPDISCOVER广播,这个广播里带有一个PXE扩展标识,告诉DHCP服务器“我是PXE客户端,请给我引导信息”。
- DHCP服务器响应,分配IP地址,同时返回“下一条服务器地址”和“引导文件名”。
- 客户端根据返回的地址,通过TFTP协议去下载引导文件,比如传统的pxelinux.0或者UEFI下的grubx64.efi。
- 引导加载器运行,去TFTP目录下找pxelinux.cfg/default配置文件,按配置显示菜单或直接加载内核。
- 客户端通过TFTP再下载vmlinuz内核和initrd内存盘文件。
- 内核启动,initrd加载磁盘驱动后,根据内核参数找到安装源和应答文件,进入真正的操作系统安装环节。
整个过程像一场接力赛:DHCP负责指路,TFTP负责运送“种子”,内核负责接手后续所有工作。理解了这个顺序,后面排错你就能按“卡在第几步”来定位。
2.2 DHCP里的“双67选项”:下一条服务器与引导文件名
DHCP在PXE流程里的作用不仅仅是分配IP,更重要的是传递PXE引导参数。这里有两个关键选项:
- option 66:next-server,也就是TFTP服务器的IP地址。
- option 67:bootfile,也就是客户端该去下载的引导文件名。
如果你用dnsmasq做实验,这两项通常合并成一行dhcp-boot=pxelinux.0,pxeserver,192.168.100.10。意思是引导文件是pxelinux.0,TFTP服务器的地址是192.168.100.10。我用过一个dnsmasq配置,客户端能拿到IP却一直卡在“尝试下载引导文件”,后来发现就是boot文件名写错了,固件一直在请求一个不存在的文件。
这里还有个容易被忽略的细节:客户端网卡发出的DHCP请求里带有60号选项,标识自己是PXE客户端,类标识符一般是“PXEClient”。dnsmasq配置里可以用dhcp-match=set:pxe,60:PXEClient来识别这类请求,从而为PXE客户端下发不同的选项。这也是后面区分BIOS和UEFI引导的基础。
2.3 传统BIOS与UEFI:两种引导文件,两条路
同一条PXE链路,老式BIOS和新式UEFI走的是完全不同的引导文件。刚开始我也以为把pxelinux.0放上去就万事大吉了,直到碰到一台只支持UEFI的服务器,PXE菜单压根出不来。
| 启动模式 | 引导文件 | 常用配套模块 | 说明 |
|---|---|---|---|
| 传统BIOS/Legacy | pxelinux.0 | ldlinux.c32、vesamenu.c32、menu.c32 | 依赖Syslinux生态,菜单界面成熟 |
| UEFI x86_64 | grubx64.efi | grub.cfg、shim.efi | 走GRUB2链路,文件结构与BIOS完全不同 |
| UEFI下的另一种选择 | ipxe.efi | 依赖iPXE构建环境 | 支持HTTP引导,功能更强但配置复杂 |
所以你在搭建PXE服务端时,必须先明确要覆盖哪些客户端。如果机房是混装的老旧机器和新型机器,保险做法是在DHCP配置里按客户端架构区分引导文件,dnsmasq中可以用dhcp-match按client-arch选项打标签,分别下发不同的bootfile。我第一次部署时图省事只做了BIOS模式,结果送过去一批新机器全军覆没,白白折腾了一下午。建议你至少在实验阶段就把两种模式都跑通。
2.4 为什么早期固件只信任TFTP而不是HTTP
很多人会问:现在HTTP下载又快又稳定,为什么PXE还要用TFTP这么古老又慢的协议?这是因为网卡固件阶段的存储空间和协议栈极有限,它只内置了最简单的UDP栈,能解析DHCP和TFTP,但跑不了完整的TCP/IP并发连接。TFTP基于UDP 69端口,足够轻量,虽然单包只有512字节,交互效率很低,但对引导文件这种几十兆以内的小文件来说完全够用。
如果你觉得TFTP太慢,现在也有iPXE方案,它用一段可替代固件的小引导程序先给自己“升级”,之后就支持HTTP甚至iSCSI引导。不过那是进阶玩法,这里不多展开。做批量装机的核心链路,仍然是DHCP+TFTP+HTTP/NFS并行,先用TFTP把内核拉起来,内核起来后再通过HTTP或NFS去拉完整的系统镜像。
3. 动手搭建PXE服务器:dnsmasq、引导文件与镜像源
3.1 服务拆解:哪些角色由谁扮演
一套迷你PXE服务端至少要有四个角色:
- DHCP服务:负责IP分配和PXE引导参数下发。
- TFTP服务:负责提供引导文件、内核、initrd。
- 文件服务:负责提供系统安装树,安装程序从这里拉取软件包。
- 应答文件服务:负责提供kickstart、preseed这类无人值守配置。
做实验时,DHCP和TFTP可以合并到dnsmasq一个进程里,文件服务直接用HTTP服务器(如nginx)提供,应答文件直接放在同一个HTTP目录下。整个服务端轻量到一台2核2G的虚拟机就能跑。
3.2 dnsmasq一键整合DHCP+TFTP的具体配置
我第一次搭建时选用dnsmasq,而不是分开配isc-dhcp-server和tftp-hpa,原因很简单:后者需要维护两个服务,配置文件又长又容易遗漏,dnsmasq一个进程搞定。下面是一份实测可用的参考配置,假设PXE服务器IP是192.168.100.10,网段是192.168.100.0/24:
port=0 interface=enp0s3 bind-interfaces dhcp-range=192.168.100.100,192.168.100.200,255.255.255.0,12h dhcp-option=3,192.168.100.1 dhcp-option=6,223.5.5.5 dhcp-match=set:pxe,60:PXEClient dhcp-boot=pxelinux.0,pxeserver,192.168.100.10 enable-tftp tftp-root=/var/lib/tftpboot tftp-blksize=1468 log-dhcp逐个说下关键参数。port=0表示不启用dnsmasq的上游DNS转发功能,你不需要它做域名解析。dhcp-range定义了客户端获取IP的池子,务必避开服务端自身IP。dhcp-boot这里的三段信息分别是引导文件名、主机名(可随意)、TFTP服务器IP。enable-tftp和tftp-root指定了TFTP服务要开启以及文件存放位置。tftp-blksize是优化项,能适当提高TFTP传输效率,实测在局域网里效果明显。
有一个很小的坑:dnsmasq默认会监听本机所有网卡,如果不做interface和bind-interfaces限制,它可能把DHCP请求发到你不想服务的网卡上,甚至和外网环境冲突。我在实验环境里吃了这个亏,所以强烈建议指定服务网卡的名称。
3.3 引导文件目录与菜单配置
dnsmasq配好之后,就要准备TFTP根目录里的文件。以CentOS系为例,你需要先安装syslinux包获取引导加载器:
yum install -y syslinux tftp-server nginx mkdir -p /var/lib/tftpboot/pxelinux.cfg cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ cp /usr/share/syslinux/{ldlinux.c32,vesamenu.c32,menu.c32,libcom32.c32,libutil.c32} /var/lib/tftpboot/然后把系统ISO镜像里的vmlinuz和initrd.img复制出来。不同发行版路径不太一样,CentOS 7在ISO的isolinux目录下,CentOS 8/9在images/pxeboot目录下,Ubuntu的netboot文件在netboot目录里。这一步我建议直接用mount命令挂载ISO后cp出来,别手动解压,省得出问题。
接下来是pxelinux.cfg/default,它是PXE菜单的核心配置:
default vesamenu.c32 prompt 0 timeout 100 menu title PXE Boot Menu label linux menu label ^Install CentOS 7 via HTTP kernel vmlinuz append initrd=initrd.img inst.repo=http://192.168.100.10/centos7 ks=http://192.168.100.10/ks/ks7.cfg ip=dhcp这里的inst.repo指定安装源在哪,ks=指定应答文件在哪。内核起来后,Anaconda安装器会根据这两条信息去拉取后续数据。p.s. 如果是Ubuntu/Debian,kernel参数体系会不同,用到时需要先查对应安装器文档,同一套参数不能跨发行版乱套。
3.4 发布安装镜像:HTTP还是NFS
内核起来之后,安装程序需要一个“安装源”,里面放着软件包仓库、安装数据等。两种主流方式:
一种是通过NFS分享镜像目录。配置直观,但多一层nfs-utils和rpcbind依赖,排错时容易多一个变量。
另一种是直接用HTTP把挂载好的ISO目录暴露出去。我推荐这种方式,原因有三:HTTP端口明确,防火墙规则好写;权限模型简单;nginx在局域网里的并发能力足够强,多台机器同时开工互相干扰很小。
我用nginx时,直接把挂载ISO的目录软链到nginx根目录下,配置里加一段location { root /srv/iso; autoindex on; }就完事。安装源地址就是http://192.168.100.10/centos7这样的路径。挂载ISO的命令也很简单:
mount -o loop /data/iso/CentOS-7-x86_64.iso /srv/iso/centos7注意挂载权限,nginx默认以nginx用户运行,如果目录和文件权限不对会出现403,我在首次部署时就因为没加chmod -R 755而卡了半小时。
3.5 冒烟验证:第一台机器能不能起来
配置完成后不要急着批量上机器,先做一次最小冒烟验证。在服务端执行:
systemctl restart dnsmasq nginx systemctl enable dnsmasq nginx firewall-cmd --add-service=dhcp --add-service=tftp --add-service=http --permanent firewall-cmd --reload然后找一台测试机,确保BIOS里开了网络引导,接在同网段的交换机上,开机后快速按F12或对应的网卡启动快捷键,选择PXE/IPv4引导。正常顺序是:机器获取IP,屏幕出现TFTP下载进度,接着出现PXE菜单,选择菜单后能看到内核加载输出,最后进入安装器界面。
如果卡在第一步,先看dnsmasq日志,journalctl -u dnsmasq能实时看到DHCP请求是否到达。日志里有客户端MAC却没有分配地址,说明DHCP池冲突;完全没有任何日志,则要先查防火墙和网卡绑定。这一步跑通,说明整条链路的基础件都正常,可以进入无人值守配置了。
4. 无人值守的关键:kickstart应答文件与安装源定制
4.1 kickstart文件解决什么问题
PXE解决的问题是“从网络引导启动系统”,而真正的核心价值是“不加人工干预地装好系统”。这个转变靠的就是应答文件。CentOS系里叫kickstart,Ubuntu系叫preseed,思想完全一致:把安装向导里每一步的选择提前写成一份答案,安装程序按答案自动操作,不再弹窗问你分区、时区、语言、软件包这些信息。
拿到一份好ks文件最快的方法是:先用光盘或U盘手工装一台Linux,不需要太认真,装完系统后去/root/anaconda-ks.cfg看看,系统自动记录了你刚才安装的全部选项,这就是现成的ks模板。我后来维护的ks基本都是从这类文件演化而来。
4.2 一份生产可用的ks核心配置长什么样
下面是精简但完整的CentOS 7 ks配置,能跑通无人值守安装:
install url --url="http://192.168.100.10/centos7" lang en_US.UTF-8 keyboard us rootpw --plaintext Pxe@2024 timezone Asia/Shanghai zerombr clearpart --all --initlabel autopart firstboot --disable selinux --enforcing firewall --enabled %packages @^minimal @core vim %end这些指令背后的逻辑:url指定安装源必须和pxelinux.cfg里的inst.repo一致;clearpart --all清空旧分区,防止上次遗留的系统干扰;autopart自动分区,适合标准服务器,特殊存储结构再手工定制;selinux --enforcing和firewall --enabled是按生产基线来,有些人喜欢先关掉再装完系统处理,具体看你们的安全要求。
需要注意rootpw这里用的是明文,实验环境图省事可以这么干,但生产环境强烈建议改成加密哈希,用grub-crypt或者openssl passwd -6生成密码哈希后放进来。我在客户现场从不用明文密码,万一ks文件被其他人看到,后果不可控。
4.3 把ks传给安装程序:内核参数与网卡信息
kS文件写好后,只要在pxelinux.cfg的append行末尾加上ks=http://192.168.100.10/ks/ks7.cfg,安转程序就会自动下载并应用。这里有个隐藏细节:ks文件所在目录如果不带执行权限或者nginx没有开放该目录的autoindex,下载会失败,但安装器只会提示“Failed to fetch ks file”,不会告诉你具体原因。遇到这类报错,先去服务端看nginx访问日志。
网卡信息也是一个容易被忽视的点。默认ks里没有网络配置时,安装器会沿用内核启动时DHCP拿到的网络,如果你希望装完系统后的IP与PXE启动IP一致,可以在ks里配置network --bootproto=dhcp。更精密的需求,比如按机房网段规划静态IP,可以用内核参数配合ip=指定,或者在ks里用%pre脚本动态生成网络配置,这在后面的进阶部分也会提到。
4.4 %post脚本:装机完成后的最后一公里
kS里最让我喜欢的是%post段,它允许你在系统安装完成后、重启之前执行任意脚本。这一步把“装机”和“交付”打通了,我通常在这里做三件事:
- 写主机名,比如根据配置的IP段自动生成node01、node02这类命名。
- 安装基础运维组件,比如vim、htop、nfs-utils等。
- 把系统加入监控和日志采集,比如注册到服务发现组件、安装agent并配置上报地址。
一个典型示例:
%post --log=/root/ks-post.log hostnamectl set-hostname node01 systemctl enable --now sshd yum -y install vim htop nfs-utils echo "ks post complete" > /root/ks_post_result.txt %end--log参数很实用,它把%post执行过程中的所有输出写到日志文件,出了问题上机器就能查,不用盲猜。我遇到过一次脚本里变量引用了未定义项导致后续命令全没执行,全靠日志发现。
5. PXE装机的实测排错:高频故障与完整排查链路
5.1 菜单出来了却下载不了引导文件:TFTP链路排查
PXE最常见的卡点发生在TFTP阶段。现象是客户端已经拿到IP,屏幕显示类似“PXE-E32: TFTP open timeout”的错误。出现这个问题,弓系不是一个点,按下面顺序排查基本能定位:
- 先确认服务端69端口的UDP监听是否正常,用
ss -lun | grep 69看。 - 检查防火墙,很多系统默认不放行UDP 69,这个最容易被忽略。我之前在CentOS 7上遇到过firewalld把tftp服务放行了但端口规则实际没生效的情况,干脆用
firewall-cmd --add-port=69/udp --permanent直接报。 - 确认客户端与DHCP返回的next-server地址路由可达。如果客户端接到的是192.168.100.10,但它自己的网段是192.168.50.0/24,那多层路由就把数据包丢了,PXE文件自然拉不下来。
- TFTP根目录下是否真的存在引导文件,文件名大小写完全一致。Linux对大小写敏感,我见过把
pxelinux.0写成PXELINUX.0的,结果客户端一直请求大写或小写文件,服务端却对不上。
5.2 选择菜单后直接重启或黑屏:c32模块丢失
这些故障我觉得是最容易让人抓狂的一类。PXE菜单出来了,选择安装项后,系统不是重启就是黑屏。这通常不是内核问题,而是引导加载器缺少配套运行时库。
pxelinux.0不是一个自包含文件,它依赖css菜单模块和基础库。常见的包括vesamenu.c32负责图形化菜单、ldlinux.c32负责基础I/O、libcom32.c32和libutil.c32提供运行库。如果只复制了pxelinux.0而忘记复制这些c32文件,启动时Syslinux会回到无菜单模式,或者直接崩溃重启。
我一开始搭建时就是只拷了pxelinux.0,折腾了好一会,后来把整个/usr/share/syslinux目录下的bios模块文件批量复制到TFTP根目录,问题立刻消失。如果你的TFTP根目录下有多个子目录放不同系统的内核,也别忘了检查对应菜单里引用的相对路径,路径不对同样会导致加载失败。
5.3 内核起来但安装源失败:repo与网络故障
当客户端成功进入Anaconda安装界面却报错说找不到安装源,就要分情况排查。
首先确认ks里的url和pxelinux.cfg里inst.repo指向的地址在客户端侧能访问。注意,这里用的是客户端视角,而不是服务端视角。命令curl http://192.168.100.10/centos7要在客户端网络环境里验。如果服务端自己访问自己正常,但客户端访问不通,大概率是服务端防火墙只放行了本机回环地址的流量,或者nginx绑定了特定网卡。
其次看nginx的autoindex on是否开启。安装器要读取目录索引来遍历软件包,没开目录列表就会出现“Failed to get repo metadata”这类错误。我在3.4节里专门提过这个配置,实操中确实有同事栽在这里。
还有一个隐蔽问题:ISO挂载后目录里包含大小写混合的目录名,比如Packages、repodata,如果你手工软链时路径拼写少了个大写字母,看起来差不多但实际打不开。所以挂载后务必执行ls /srv/iso/centos7确认目录内容正常,再去配置nginx。
5.4 UEFI机器根本不进PXE:固件与启动模式陷阱
声讨一下UEFI:同一台PXE服务器,BIOS机器一切正常,UEFI机器开机时直接跳过网络启动,这确实让很多运维头疼。原因常出在下面几个环节:
- 固件的启动模式没有开启UEFI网络栈,有的主板需要在Boot页面单独启用“IPv4 PXE Support”。
- Secure Boot没有关闭。UEFI固件默认只加载具有有效签名的引导加载器,自签名或第三方grubx64.efi可能直接被拒绝。
- DHCP下发的引导文件名还是pxelinux.0,但UEFI固件要求的引导文件是grubx64.efi或shim.efi。文件名对不上,固件就会放弃网络启动。
应对方案是在dnsmasq里按客户端架构打标签:
dhcp-match=set:efi-x86_64, option:client-arch, 7 dhcp-boot=tag:efi-x86_64,grubx64.efi,pxeserver,192.168.100.10 dhcp-boot=tag:!efi-x86_64,pxelinux.0,pxeserver,192.168.100.10注意grubx64.efi对应的GRUB配置是grub.cfg,它无法直接读取pxelinux.cfg里的菜单格式,需要你单独写一份GRUB菜单配置,与Syslinux菜单是两套体系。配置格式不花哨但细节多,我第一次转换时花了整整一个晚上才调完。
5.5 与现有DHCP冲突:生产环境PXE的整体接入思路
很多人在实验环境跑通了PXE,却在生产接入时卡住。原因很直接:生产网络里已存在一台权威DHCP服务器,你新起的dnsmasq也提供DHCP,两个服务器抢答,客户端环境一片混乱。
我的经验是,生产环境不要用dnsmasq去抢DHCP应答位置,应该让现有的DHCP基础设施承担“下发PXE引导信息”这个职责。具体分两类:
- 如果核心交换机或路由器支持DHCP relay,把PXE广播请求relay到你的PXE服务器网段,让PXE服务器作为独立DHCP池的权威。
- 如果现有DHCP就是主服务器,不需要额外引入DHCP服务,只需在主DHCP的配置里加上option 66、option 67两项,把next-server指向PXE服务器的IP,引导文件名按客户端类型填pxelinux.0或grubx64.efi。这样客户端IP分配仍由主DHCP负责,PXE服务器只提供TFTP、HTTP和ks文件,互不干扰。
这个“只做TFTP和内容服务、不碰DHCP”的模式在生产环境里最稳定。我推行的方案基本都走这条路线,也避免了业务网段因为一个装机服务被拖垮的尴尬。
6. 从装机到交付:PXE在批量场景中的进阶玩法
6.1 按MAC和网段定制配置:pxelinux.cfg的匹配规则
pxelinux.cfg目录下不只是default这一个文件,它有一套匹配优先级,能根据客户端的不同身份加载不同的配置。这就有意思了。
Syslinux会按以下顺序查找配置文件:先是带有客户端MAC地址的文件,例如01-00-0c-29-aa-bb-cc;再是按客户端IP地址十六进制形式命名的文件;最后才是default。我利用这套机制做了“不同机器进入不同安装配置”的效果:
- 某些特定型号的服务器磁盘控制器特殊,需要一个包含驱动参数的专用菜单。
- 某些机器要装旧版系统,某些要装新版,通过MAC前缀直接分流。
- 机房内部分组,A组机器自动走A分区方案,B组走B分区方案。
这样做的好处是批量交付时不用人工干预,机器只要插上网线开机,固件会根据身份自动选择正确的安装策略。它比单纯一个default菜单灵活得多,也让“不同主机不同系统”变成了一个配置文件的差异管理问题。
6.2 镜像生命周期管理:一份PXE服务端维护多个系统
PXE服务端瘫痪的时候往往是最忙的时候。为了让服务端变更可回溯、可验证,我用了一个非常朴素的办法:把所有PXE相关文件纳入一个git仓库管理,包括dnsmasq配置、pxelinux.cfg菜单、ks文件、%post脚本。每次改模板都走git commit,遇到问题也能回滚到上一个稳定版本。
同时,镜像目录按系统和版本做目录隔离:
/srv/iso/ ├── centos7/ ├── centos9/ └── ubuntu2204/pxelinux.cfg/default里通过label分别指向不同的kernel、append和inst.repo路径。这样一台PXE服务器可以同时承载多个系统版本,交付时按需选菜单。维护多个版本时特别注意:不同系统装机的内核参数格式不同,比如CentOS 7是inst.repo,早期版本可能是method=,Ubuntu则走preseed链路。如果在一个菜单里混用,必然有一类系统起不来。
我后来把菜单做了分级,进入第一级菜单选系统,第二级菜单再选安装源和ks版本。初期看起来多了一层选择,但维护起来反而更清晰。
6.3 更进一步:把PXE纳入自动化交付流水线
PXE装机能解决“系统安装”这一个环节,但真正的自动化交付需要和后续链路串起来。我目前在做的方案大致是:
- 机器上电后通过PXE自动安装,ks文件里的%post脚本把机器IP、MAC、硬件信息登记到资产管理接口。
- %post里根据CMDB的分配规则自动生成主机名并写入系统。
- 安装完成后自动下载一个初始化脚本,统一部署监控agent、日志agent、SSH安全基线。
- 服务器入运维系统的最后一步,自动触发一条工单通知,交付负责人只等收一台“即插即用”的机器。
这样做的收益不只是少熬夜,而是“装机”变成一条确定性极高的流水线:每台机器从插上网线到纳入监控,路径完全一致,结果完全一致。出现异常只需对比标准流程日志就能定位,不再需要逐台翻查。如果你刚开始接触PXE,我建议先把前文的基础链路跑通,再做这一步的自动化编排,底子打好后,后面的想象空间会很大。
最后分享一个小习惯:在正式大批量装机前,我会先准备一台验证机器,完整跑一遍“DHCP获取IP→TFTP拉取引导→进入安装器→ks自动执行→系统重启”的链路,确认每个环节日志无异常。同时把TFTP目录和ks文件放进版本管理,每次变更都记一笔。这套做法帮我省掉的无效故障排查时间,比配置本身多得多。折腾PXE最大的收获,是你会把DHCP、TFTP、内核参数、安装器这些基础服务串成一个完整的模型,以后再遇到类似网络引导问题,思路会特别清楚。