资讯动态

PXE+Kickstart无人值守批量装机实战:从原理到配置

发布时间:2026/10/16 2:03:52 来源:尧图企业网站定制
1. 为什么还要折腾 PXE从一次机房装机的真实困境说起如果你管理过超过十台服务器的机房大概率经历过这样的场景一台一台插 U 盘、进 BIOS 改启动顺序、手动分区、选软件包、设密码装完一台再换下一台。十台机器能耗掉一整天而且每台机器的配置还可能因为手抖而不一致。更麻烦的是有些机器根本没有光驱U 盘插上去还挑盘BIOS 里改来改去容易改错别的参数。PXEPreboot Execution Environment就是冲着这个痛点来的。它让机器在网卡层面就能从网络引导配合 TFTP 传内核、HTTP 或 FTP 传安装源再叠加 Kickstart 自动应答文件最终实现开机即装、装完即用的无人值守批量部署。整套方案的核心价值在于把重复劳动变成一次性配置把人工操作变成自动化流程。这篇文章面向的是有一定 Linux 基础、需要批量部署物理机的运维人员或实验室管理员。我会从 PXE 的工作链路讲起把 DHCP、TFTP、HTTP、Kickstart 四个环节的配置逻辑拆开揉碎再给出可直接复现的配置步骤和我自己踩过的坑。整套方案在局域网内运行不涉及任何外部网络依赖适合内网机房、实验室、教学环境等场景。需要提前说明的是PXE 本身只是一个引导规范真正干活的是它背后的一整套服务组合。很多人第一次配 PXE 失败不是因为 PXE 难而是因为没搞清楚谁在什么时候把什么文件交给谁。所以下面我先讲清楚这条链路再动手配。2. PXE 引导链路拆解数据包到底在机器之间怎么跑2.1 从网卡通电到内核启动的完整时序一台裸机按下电源后网卡固件PXE Client会先发一个 DHCP Discover 广播包包里带着自己的 MAC 地址和一个特殊标识告诉网络我需要网络引导。DHCP 服务器收到后除了分配 IP还要通过next-server字段告诉客户端 TFTP 服务器的地址通过filename字段告诉客户端去下载哪个引导文件。客户端拿到这些信息后通过 TFTP 去下载filename指定的文件。传统 BIOS 环境下这个文件通常是pxelinux.0UEFI 环境下则是grubx64.efi或shimx64.efi。这个引导文件本身很小它的作用是加载一个配置文件如pxelinux.cfg/default配置文件里写着内核路径、initrd 路径和启动参数。接着客户端再通过 TFTP 下载内核vmlinuz和初始内存盘initrd.img把内核加载起来。内核启动后安装程序Anaconda会去inst.repo参数指定的地址拉取完整的安装源这个地址通常走 HTTP 或 FTP因为安装源动辄几个 GB用 TFTP 传会慢到怀疑人生。最后安装程序读取 Kickstart 文件ks.cfg按照里面定义的分区方案、软件包列表、网络配置、root 密码等自动完成安装装完自动重启一台机器就交付了。2.2 为什么 TFTP 只传引导文件安装源必须换协议这是新手最容易困惑的点。TFTP 基于 UDP协议极简没有认证、没有目录列表、块大小默认只有 512 字节传输大文件时效率极低。但它胜在实现简单网卡固件里就能内置一个精简的 TFTP 客户端不需要完整操作系统支持。所以 TFTP 只适合传几百 KB 到几 MB 的引导文件。安装源动辄 4-10 GB用 TFTP 传会慢到无法接受而且 TFTP 对丢包的处理很粗糙。HTTP 或 FTP 基于 TCP有重传机制、支持大文件、还能配合 Web 服务器做并发所以安装源走 HTTP/FTP 是标准做法。理解这一点你就明白为什么 PXE 服务器上通常要同时跑 DHCP、TFTP、HTTP 三个服务。2.3 BIOS 与 UEFI 两条引导路径的差异现在机房里的机器新旧混杂BIOS 和 UEFI 两种固件都可能遇到它们的引导文件完全不同固件类型引导文件配置文件路径说明Legacy BIOSpxelinux.0pxelinux.cfg/default由 syslinux 提供UEFIgrubx64.efi / shimx64.efigrub.cfg由 grub2 提供如果只配了 BIOS 的引导文件UEFI 机器会卡在 PXE 阶段反复重试反之亦然。稳妥的做法是两套都配好让 DHCP 根据客户端架构Client System Architecture返回不同的filename。这个细节后面在 DHCP 配置里会具体展开。3. 服务端环境搭建DHCP、TFTP、HTTP 三件套的配置逻辑3.1 基础环境与软件包准备我习惯用一台配置中等的机器做 PXE 服务器2 核 4G、100G 磁盘起步因为要存放安装源。系统用主流的服务器发行版即可。先把三个核心服务装上# 以常见的 RPM 系发行版为例 dnf install -y dhcp-server tftp-server httpd syslinux grub2-efi-x64 shim-x64这里解释一下每个包的作用。dhcp-server负责分配 IP 和引导信息tftp-server提供引导文件下载httpd提供安装源syslinux提供 BIOS 环境下的pxelinux.0及其模块grub2-efi-x64和shim-x64提供 UEFI 环境下的引导文件。少装任何一个对应环节就会断。防火墙和 SELinux 是绕不开的坎。测试阶段我建议先把防火墙放行相关端口SELinux 设为 permissive 观察确认链路通了再收紧策略。生产环境则要精确放行 DHCP 的 67/68 端口、TFTP 的 69 端口、HTTP 的 80 端口。3.2 DHCP 配置next-server 与 filename 的配合DHCP 配置是整个 PXE 的指路牌写错了后面全白搭。核心配置片段如下# /etc/dhcp/dhcpd.conf subnet 192.168.100.0 netmask 255.255.255.0 { range 192.168.100.100 192.168.100.200; option routers 192.168.100.1; option domain-name-servers 192.168.100.1; next-server 192.168.100.10; # TFTP 服务器地址 filename pxelinux.0; # 默认引导文件 } # 针对 UEFI 客户端返回不同的引导文件 class pxeclients { match if substring (option vendor-class-identifier, 0, 9) PXEClient; if option arch 00:07 { filename grubx64.efi; # UEFI x64 } elsif option arch 00:00 { filename pxelinux.0; # BIOS } }next-server告诉客户端 TFTP 服务器在哪filename告诉它下载哪个文件。option arch是 DHCP 的一个选项客户端会在请求里带上自己的架构类型00:07代表 UEFI x6400:00代表 Legacy BIOS。用这个判断就能让同一台 DHCP 服务器同时服务两种固件的机器。注意next-server必须写 TFTP 服务器的 IP不能写主机名因为此时客户端还没有 DNS 解析能力。这个坑我见过不止一个人踩。3.3 TFTP 根目录的目录结构规划TFTP 的根目录通常在/var/lib/tftpboot所有引导相关文件都放在这里。我建议按下面的结构组织清晰且不易乱/var/lib/tftpboot/ ├── pxelinux.0 # BIOS 引导文件 ├── ldlinux.c32 # syslinux 模块 ├── menu.c32 # 菜单模块 ├── grubx64.efi # UEFI 引导文件 ├── shimx64.efi # UEFI 安全启动用 ├── pxelinux.cfg/ │ └── default # BIOS 引导菜单配置 ├── grub.cfg # UEFI 引导菜单配置 └── images/ ├── vmlinuz # 内核 └── initrd.img # 初始内存盘把内核和 initrd 统一放在images目录下引导菜单里引用相对路径即可。这样以后换发行版或升级内核只改images目录里的文件菜单配置基本不用动。3.4 引导菜单配置让装机的人能选BIOS 环境下编辑pxelinux.cfg/defaultdefault menu.c32 prompt 0 timeout 60 label auto-install menu label ^Auto Install (Kickstart) kernel images/vmlinuz append initrdimages/initrd.img inst.repohttp://192.168.100.10/iso kshttp://192.168.100.10/ks/ks.cfg label manual-install menu label ^Manual Install kernel images/vmlinuz append initrdimages/initrd.img inst.repohttp://192.168.100.10/isoinst.repo指向 HTTP 上的安装源ks指向 Kickstart 应答文件。timeout 60表示 60 秒无操作自动选默认项配合prompt 0就能实现完全无人值守——机器开机后什么都不用按自动进入自动安装。UEFI 环境下编辑grub.cfg逻辑类似只是语法换成 grub 的写法set timeout60 set default0 menuentry Auto Install (Kickstart) { linuxefi images/vmlinuz inst.repohttp://192.168.100.10/iso kshttp://192.168.100.10/ks/ks.cfg initrdefi images/initrd.img }3.5 HTTP 服务安装源与 Kickstart 文件的托管把发行版 ISO 挂载后内容复制到 HTTP 根目录下的某个路径比如/var/www/html/iso。Kickstart 文件放在/var/www/html/ks/ks.cfg。这样inst.repo和ks两个地址都能通过 HTTP 访问到。mount -o loop /path/to/distro.iso /mnt cp -r /mnt/* /var/www/html/iso/ chmod -R 755 /var/www/html/iso复制完记得检查repodata目录是否存在这是安装程序识别安装源的关键。有些精简版 ISO 不带完整 repodata需要自己用createrepo生成否则安装程序会报无法读取安装源。4. Kickstart 应答文件无人值守的真正核心4.1 ks.cfg 的生成方式与结构Kickstart 文件决定了机器装成什么样。最省事的生成方式是先用图形界面装一台样板机安装程序会自动把这次安装的选择记录到/root/anaconda-ks.cfg把它拷出来改改就能用。但更可控的方式是手写因为自动生成的往往带一堆你不需要的东西。一个精简的 ks.cfg 结构大致分几块命令段系统配置、软件包段装什么、脚本段装完做什么。下面给一个可直接改用的模板#versionDEVEL # 系统语言与时区 lang en_US.UTF-8 keyboard us timezone Asia/Shanghai --utc # 网络配置用 DHCP 或静态都行 network --bootprotodhcp --devicelink --activate # 静态写法示例 # network --bootprotostatic --ip192.168.100.50 --netmask255.255.255.0 --gateway192.168.100.1 --nameserver192.168.100.1 # root 密码这里用加密串 rootpw --iscrypted $6$xxxxxxxxxxxxxxxx$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 分区方案 zerombr clearpart --all --initlabel part /boot --fstypexfs --size1024 part / --fstypexfs --size20480 part swap --size4096 part /data --fstypexfs --size1 --grow # 关闭防火墙和 SELinux按需 firewall --disabled selinux --disabled # 安装完成后重启 reboot %packages ^minimal-environment vim net-tools %end %post echo Provisioned at $(date) /etc/motd %end4.2 分区策略为什么 clearpart 和 zerombr 必须写zerombr的作用是清除磁盘上的无效分区表clearpart --all --initlabel则是清空所有分区并重新初始化磁盘标签。这两条在批量装机里几乎是必写的因为待装的机器可能残留着旧系统的分区表不清理干净安装程序会报错或装到一半失败。分区大小要根据实际用途定。上面模板里/给 20G/data用--grow吃掉剩余空间这是比较通用的做法。如果是数据库机器/data可能要单独规划如果是纯计算节点/给大一点也无妨。关键是--grow只能有一个分区用否则安装程序不知道该把剩余空间给谁。4.3 root 密码的加密处理ks.cfg 里明文写密码是大忌因为文件放在 HTTP 上谁都能访问。正确做法是用openssl passwd -6生成 SHA-512 加密串openssl passwd -6 YourPassword把输出的加密串填到rootpw --iscrypted后面。这样即使 ks.cfg 被看到也拿不到明文密码。更进一步的做法是安装后通过%post脚本从内部配置管理系统拉取密码或注入 SSH 公钥彻底避免密码出现在应答文件里。4.4 %post 脚本装完机器后自动做的那些事%post段是 Kickstart 最灵活的部分它在系统装完、首次重启前执行可以用来做各种初始化。常见的用法包括注册到监控系统、配置内部软件源、注入 SSH 公钥、设置主机名、拉取配置管理 Agent。%post --log/root/ks-post.log # 注入 SSH 公钥 mkdir -p /root/.ssh cat /root/.ssh/authorized_keys EOF ssh-rsa AAAA... your-key-here EOF chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys # 配置内部软件源 cat /etc/yum.repos.d/internal.repo EOF [internal] nameInternal Repo baseurlhttp://192.168.100.10/repo enabled1 gpgcheck0 EOF %end注意%post默认在 chroot 环境下执行如果要访问网络或操作宿主机层面的事情需要加--nochroot。这个区别很多人第一次会搞混导致脚本里网络请求失败。5. 联调与排错链路不通时按这个顺序查5.1 从 DHCP 抓包开始定位断点PXE 出问题第一步永远是抓包。在服务器上跑tcpdump -i eth0 -n port 67 or port 68 or port 69如果连 DHCP Discover 都看不到说明客户端根本没发起 PXE 请求问题在客户端 BIOS 设置或网线。如果看到了 Discover 但服务器没回应检查 DHCP 服务是否监听在正确的网卡上、地址池是否耗尽。如果 DHCP 回应了但客户端没去下 TFTP 文件检查next-server和filename字段是否正确。5.2 TFTP 下载失败的常见原因TFTP 报错通常很隐晦客户端只显示一个超时或file not found。排查时先在服务器本地自测tftp 192.168.100.10 tftp get pxelinux.0如果本地都下不下来问题在 TFTP 服务配置或文件权限。常见原因有三个一是 TFTP 根目录权限不对需要确保目录和文件对tftp用户可读二是 SELinux 拦截用ausearch -m avc查三是防火墙没放行 69 端口。这三个原因我几乎每次配新环境都会遇到其中一个。5.3 安装源读取失败的排查如果内核起来了、安装程序也启动了但卡在读取安装源或报repo相关错误问题多半在 HTTP 服务或inst.repo路径。先在浏览器或curl里访问inst.repo那个地址确认能列出目录。如果 403是权限问题如果 404是路径写错如果能访问但安装程序还报错检查repodata目录是否完整。5.4 Kickstart 文件解析错误的定位Kickstart 语法错误会导致安装中断错误信息会显示在安装界面上同时记录在/tmp/anaconda.log和/tmp/ks-script-*.log里。常见的语法错误包括分区大小写成负数、%packages段里包名拼错、%post段缺少%end。建议先用ksvalidator工具校验一遍ksvalidator /var/www/html/ks/ks.cfg这个工具能提前发现大部分语法问题省得装到一半才发现。6. 几个让我印象深刻的坑与对应的经验6.1 网卡多口导致 DHCP 拿错地址有些服务器有四个网口PXE 引导时可能从错误的网口发起请求拿到一个不通的网段地址。解决办法是在 BIOS 里明确指定 PXE 使用的网口或者在 DHCP 配置里按 MAC 地址做绑定。我遇到过一台机器四个口都插了网线结果 PXE 从管理口发起怎么都装不上最后在 BIOS 里把 PXE 网口锁定才解决。6.2 UEFI 安全启动拦截未签名引导文件开了 Secure Boot 的机器会拒绝加载未签名的grubx64.efi。这时候要么在 BIOS 里关掉 Secure Boot要么用签过名的shimx64.efi配合grubx64.efi。后者是更规范的做法shim作为第一级引导验证通过后再加载 grub。配置时filename要指向shimx64.efigrub 的配置文件路径也要对应调整。6.3 安装源路径里的软链接陷阱有次我把 ISO 内容复制到 HTTP 目录为了省事用了软链接指向挂载点。结果安装程序通过 HTTP 访问时Web 服务器默认不跟随软链接直接 403。后来改成实际复制文件或者给 Web 服务器开FollowSymLinks才解决。这个坑的教训是PXE 链路上任何一环的小聪明都可能变成大麻烦老老实实复制文件最稳。6.4 大批量并发装机时的性能瓶颈一次给几十台机器同时装机HTTP 服务和 TFTP 服务都可能成为瓶颈。TFTP 是单线程的并发下载引导文件时会排队HTTP 虽然能并发但磁盘 IO 和网络带宽是硬限制。我的经验是引导文件阶段用 TFTP 问题不大因为文件小安装源阶段如果并发超过 20 台最好把安装源放到独立的存储或做多副本避免所有机器挤一个磁盘。7. 把这套方案用顺之后的几点体会整套 PXE Kickstart 方案配通之后批量装机的效率提升是数量级的。以前装十台机器要一整天现在开机、等着、装完中间该干嘛干嘛。但我想强调的是这套方案的价值不只是快更在于一致——每台机器装出来的分区、软件包、配置完全相同消除了人工操作带来的差异这对后续的批量运维太重要了。我在实际使用中最大的体会是Kickstart 文件要当成代码来管理。把它放进版本控制每次改动都有记录出问题能回滚。同时给不同用途的机器准备不同的 ks 文件比如计算节点、存储节点、管理节点各一份引导菜单里让装机的人选或者干脆按 MAC 地址自动匹配。这样一套 PXE 服务器就能服务整个机房的多种机型。最后分享一个小技巧在%post脚本里加一行把装机时间和机器序列号写到一个中央日志服务器。这样你随时能知道哪台机器什么时候装的、装的哪个版本排查问题时特别有用。这个习惯我坚持了好几年省了无数次翻记录的时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑