PXE+Kickstart无人值守安装:服务器批量交付实战与避坑指南 深夜机房还有七台配置完全一样的服务器等着装系统。按老办法一台台来每台都得盯着屏幕选语言、划分区、设密码平均一台三十分钟七台就是小半天人还寸步不能离。后来我花了点时间把PXE加Kickstart这套无人值守安装流程在CentOS 6.4环境下彻底跑通从那以后交付服务器变成了“开机、等、完事”三个步骤。这篇就把整个环境的搭建过程、配置细节和我在实测中踩过的一堆坑完整记录下来。对于还在用CentOS 6.x维护老环境的朋友或者刚接触网络安装、想理解PXE和Kickstart配合原理的运维新人这篇文章可以直接照着操作。即便你现在的生产环境已经换到7、8或者衍生版这套架构思路也依然成立只是个别软件包名和内核参数略有差异。1. 为什么服务器批量交付必须靠PXEKickstart先聊聊这套方案到底解决了什么问题。手动安装的最大痛点不是“慢”而是“人不能离开”。每台机器在安装过程中都有几个必须人工干预的节点选择安装界面语言、确认磁盘布局、设置root密码、选择软件包组。一旦中间某个节点没人点一下安装进程就卡在那直到超时或报错。更难受的是这些操作完全重复没有任何技术含量但又不能交给不懂的人去点因为误操作会直接导致分区错误甚至数据丢失。PXE的技术本质并不复杂。它是Intel定义的一套网络引导标准在网卡固件层面实现了“从网络启动”的能力。机器开机后网卡主动发送广播请求从网络中的DHCP服务器获取IP地址同时拿到引导文件的位置再从TFTP服务器下载引导程序最终加载内核和初始化内存盘进入系统安装流程。Kickstart则是Anaconda安装器的应答机制。它本质上是一个文本文件预先把安装过程中所有需要人工回答的问题都写好磁盘怎么分区、时区选哪个、root密码是什么、要装哪些软件包、装完后执行什么脚本。Anaconda启动后检测到ks文件就不再询问任何问题全程按脚本自动执行。PXE和Kickstart的关系可以这样理解PXE解决的是“怎么把安装程序拉起来”的问题Kickstart解决的是“安装程序起来之后每一步干什么”的问题。一个管引导一个管执行两者串起来就是完整的无人值守链路。这套方案适合的场景很明确同配置机器批量交付、测试环境需要反复重建系统、机房新到一批服务器需要统一初始化。另外还有一个容易被忽略的价值——一致性。手动安装靠人点不同的人点出来的系统可能有细微差别比如分区大小手一抖差个几G而Kickstart让每一台机器的系统完全一致后续运维省掉不少差异化排查的功夫。2. 整体架构与前置准备谁在管什么在动手配置之前先花两分钟把架构理清楚。这一步跳过后面配置的时候会到处“差一根线”。整套环境需要三类网络服务可以全部装在同一台部署服务器上也可以拆开。我建议前期实验阶段全装在一台机器上减少变量。它们的分工如下DHCP服务给客户端分配IP地址同时通过next-server和filename两个字段告诉客户端“你去这个IP找TFTP服务器取这个引导文件”。这是整个链路的第一步也是很多人配置出错的地方。TFTP服务一个极简的文件传输协议只负责传小文件。它传的就是引导程序pxelinux.0、内核vmlinuz和初始化内存盘initrd.img。不要拿它传安装源会慢到怀疑人生。HTTP服务负责传大头——Kickstart应答文件和系统安装源。选择HTTP而不是FTP或NFS原因就一个配置最简单穿透防火墙最省事而且支持大文件并发传输。生产环境里HTTP也是主流。客户端的启动流程是这样的开机后网卡发DHCP广播拿到IP和引导信息接着从TFTP下载pxelinux.0这个引导程序读取TFTP上pxelinux.cfg/default配置文件根据配置下载vmlinuz和initrd.img并附带内核启动参数内核启动Anaconda后通过参数里的ks地址从HTTP拉取Kickstart文件最后按Kickstart的配置从HTTP安装源拉取软件包完成安装。pre-arch从准备清单来看建议准备以下环境一台部署服务器物理机或虚拟机都可以内存不低于2G磁盘剩余空间不低于20G若干台待安装的客户端一台傻瓜交换机。所有机器放在同一个二层广播域内部署服务器配置固定IP。操作系统镜像使用CentOS 6.4的DVD ISO这个镜像里已经包含了你需要的全套服务端软件和引导文件。还有两个前置条件必须确认。第一客户端网卡要支持PXE引导2010年以后的主流服务器和虚拟机默认都支持但有些机器需要在BIOS里把网卡启动选项打开或者在启动时按快捷键选择从网络启动。第二客户端引导模式必须是传统BIOS而非UEFIpxelinux.0这套方案只适用于传统BIOS引导。如果是纯UEFI环境需要换用grub2-efi或ipxe方案那是另一套配置思路这里不展开。3. 三个核心服务的安装与配置细节下面进入实际操作阶段。部署服务器用CentOS 6.4最小化安装配好固定IP后先把三个服务逐个装起来。3.1 DHCP服务客户端的第一个“向导”DHCP在这里的角色不只是分配IP更重要的是它在分配IP的同时把引导信息“塞”给了客户端。安装和配置过程如下yum install -y dhcp默认安装完成后主配置文件/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; filename pxelinux.0; }这里有几个字段必须解释清楚。next-server后面跟的是TFTP服务器的IP地址。客户端拿到这个地址之后就知道该去向谁要引导文件。filename指定的是要下载的引导文件名这里写pxelinux.0这是Syslinux提供的PXE引导程序。option routers和option domain-name-servers可以根据实际网络填如果客户端在安装过程中需要访问外网比如从外网镜像拉包这里的网关和DNS就必须正确。如果纯内网安装填一个内网地址即可但字段不能删否则客户端在安装早期阶段可能因为网络初始化失败而卡住。配置完成后启动服务并设为开机自启service dhcpd start chkconfig dhcpd on同时确认防火墙放行了UDP 67端口iptables -I INPUT -p udp --dport 67 -j ACCEPT service iptables save注意DHCP服务对配置文件的语法极其敏感任何一个分号、括号写错都会导致服务启动失败。写完配置后可以用dhcpd -t命令测试语法这个习惯我一直保留着。3.2 TFTP服务轻量引导文件的搬运工TFTP服务的安装方式在CentOS 6.x上比较特殊它由xinetd超级守护进程托管。yum install -y tftp-server xinetd安装后需要修改/etc/xinetd.d/tftp文件核心是把disable从yes改为noservice tftp { socket_type dgram protocol udp wait yes user root server /usr/sbin/in.tftpd server_args -s /var/lib/tftpboot disable no per_source 11 cps 100 2 flags IPv4 }server_args里的-s /var/lib/tftpboot指定了TFTP服务的根目录为/var/lib/tftpboot。客户端下载文件时路径都是相对于这个根目录的。如果你把引导文件放在其他目录记得同步修改这里否则客户端会一直报“TFTP open timeout”。启动服务service xinetd start chkconfig xinetd on放行UDP 69端口iptables -I INPUT -p udp --dport 69 -j ACCEPT service iptables saveTFTP本身极简没有用户认证、没有目录列表但也正因如此它的定位就是“传完即走”。如果传输过程中出现超时、卡顿优先检查防火墙和SELinux后面我会专门讲排查过程。3.3 HTTP服务安装源与应答文件的宿主机HTTP服务负责两件事一是提供Kickstart应答文件的访问二是提供整个安装源repodata目录、软件包等。安装和配置非常简单yum install -y httpd service httpd start chkconfig httpd on然后把CentOS 6.4 DVD镜像挂载到HTTP服务的根目录下。我习惯建一个专门目录mkdir -p /var/www/html/centos6 mount -o loop /path/to/CentOS-6.4-x86_64-bin-DVD1.iso /var/www/html/centos6为了让重启之后挂载不丢把挂载信息写入/etc/fstab/path/to/CentOS-6.4-x86_64-bin-DVD1.iso /var/www/html/centos6 iso9660 loop,defaults 0 0放行TCP 80端口iptables -I INPUT -p tcp --dport 80 -j ACCEPT service iptables save到这里三个服务已经就绪。建议你现在就做一次联通性验证不要急着往下配置。在浏览器里访问http://部署服务器IP/centos6/能看到目录列表就说明HTTP正常。用下面的命令测试TFTPtftp 部署服务器IP -c get pxelinux.0这条命令虽然现在pxelinux.0还没放到TFTP目录下会提示文件不存在但只要连接没有被拒绝就说明TFTP服务和防火墙状态是正常的。先把这条链路确认通后面排查问题就能少一半的变量。4. Kickstart应答文件从模板到一份能上生产的配置Kickstart文件是整个无人值守流程里最有含金量的部分。它决定的不是“能不能装上”而是“装出来的系统什么样”。生成Kickstart文件有三种路径你可以根据习惯选择生成方式优点缺点手写完全可控熟悉每条指令有语法风险调试成本高图形工具system-config-kickstart可视化适合新手入门生成的配置较保守部分高级功能不支持界面配置基于参考机anaconda-ks.cfg修改最贴合实际需求参考机怎么分区、装了什么一目了然需要先手动装好一台“完美样板机”我最常用的是第三种手动装一台机器装的过程中记录所有选择装完后去/root/anaconda-ks.cfg拿成品再按需修改。这份文件是Anaconda在整个安装过程中实际使用的应答记录真实可靠。下面给出一份可供参考的Kickstart文件我逐段说明关键点# 全新安装 install # 安装源地址 url --urlhttp://192.168.100.10/centos6 # 语言、键盘与时区 lang en_US.UTF-8 keyboard us timezone Asia/Shanghai # root密码这里用到的是加密后的hash rootpw --iscrypted $6$k3AJf3mR$9yEU2qvoO6G9gY0Zfya9lC # 网络配置DHCP获取 network --bootprotodhcp --deviceeth0 --onbootyes # 认证方式 authconfig --enableshadow --passalgosha512 # 关闭防火墙和SELinux实验环境优先保证安装成功率 firewall --disabled selinux --disabled # 引导程序配置写进MBR bootloader --locationmbr # 磁盘分区清空磁盘并创建自定义分区布局 zerombr clearpart --all --initlabel part /boot --fstypeext4 --size500 part / --fstypeext4 --size20480 part /data --fstypeext4 --size1 --grow # 软件包选择最小化常用工具 %packages base development vim lrzsz %end # 安装后脚本系统初始化操作 %post # 删除网卡持久化规则避免克隆后eth0变eth1 rm -f /etc/udev/rules.d/70-persistent-net.rules # 清空SSH主机密钥保证每台机器密钥唯一 rm -f /etc/ssh/ssh_host_* # 设置默认运行级别为命令行 sed -i s/id:5:initdefault:/id:3:initdefault:/ /etc/inittab # 将本机主机名写入配置 sed -i s/HOSTNAME.*/HOSTNAMEnode01.example.com/ /etc/sysconfig/network %end逐段解读几个容易踩坑的细节。url --urlhttp://192.168.100.10/centos6这行指定了安装源。注意这里必须指向镜像解压后包含repodata目录的那一层不是挂载点的上级目录。如果这个地址写错安装过程会在“设置软件仓库”阶段报错界面直接卡死或者退出。rootpw这行特别强调一下生产环境一定要用--iscrypted参数加上加密后的密码千万不要直接写明文rootpw 123456。明文密码会留在pxelinux配置和网络传输中。生成加密串的命令是grub-crypt --sha-512分区策略上我习惯给/留足20G以上/data分区用--grow参数吃掉剩余空间。如果你的部署场景对分区有严格要求可以去图形工具里对着划原则是服务器通用场景下尽量简化分区层级减少后续运维的理解成本。%post段是整个文件的精华。直接复用参考机的系统会有两个隐蔽问题一是网卡持久化规则文件记录了原机器的MAC地址克隆之后新机器网卡无法正确识别为eth0二是SSH主机密钥如果全部一样后续用SSH连接时会引发密钥冲突告警存在安全风险。所以在%post里删除这些文件、让系统首次启动时自动重新生成是批量交付中必须处理的细节。Kickstart文件写好后放到HTTP服务的目录下确保能通过浏览器访问cp kickstart/ks.cfg /var/www/html/ks/验证一下URL可以访问http://192.168.100.10/ks/ks.cfg。这一步千万不能省我见过太多人写完ks文件直接去装机器结果在分区步骤前卡住回头一查是ks文件的URL拼错了。5. PXE引导配置把整个安装流程串起来服务端三个服务和Kickstart文件都就绪后最后一步是把PXE引导程序的目录结构搭起来。首先从CentOS 6.4安装镜像里准备三个关键文件。DVD镜像的isolinux目录下就能找到vmlinuz和initrd.img这两个分别是安装内核和初始化内存盘。pxelinux.0这个引导程序通常在/usr/share/syslinux/下但如果部署服务器是最小化安装没有装Syslinux包可以直接从镜像的isolinux目录里找CentOS 6.x的镜像内自带一份。把它们都拷贝到TFTP根目录cp /mnt/isolinux/vmlinuz /var/lib/tftpboot/ cp /mnt/isolinux/initrd.img /var/lib/tftpboot/ cp /mnt/isolinux/pxelinux.0 /var/lib/tftpboot/接着创建pxelinux.cfg目录并写入默认引导配置mkdir /var/lib/tftpboot/pxelinux.cfg/var/lib/tftpboot/pxelinux.cfg/default文件内容如下default menu prompt 0 timeout 60 label linux menu label ^Install CentOS 6.4 x86_64 kernel vmlinuz append initrdinitrd.img kshttp://192.168.100.10/ks/ks.cfg逐一解释配置项的作用。prompt 0表示开机后不询问用户直接执行默认label对应的操作。如果是实验环境想看到引导菜单再做选择把prompt改为1或者给它一个超时时间让用户有操作窗口。label linux是引导条目名称menu label是显示在菜单上的文字。^符号表示快捷键图上会有一个下划线修饰的字符比如这里按L键即可选中此条。最关键的是append这一行。initrdinitrd.img指定初始化内存盘kshttp://192.168.100.10/ks/ks.cfg指定Kickstart文件的网络地址。这一行就是整个PXE引导和Kickstart自动应答之间的桥梁。如果这条参数缺失或写错Anaconda启动后会进入图形交互式安装界面无人值守就变成有人值守了。你还可以在同一个default文件里配置多个label对应不同的安装场景。比如一个label走最小化安装的ks另一个label走带图形桌面环境的ks再配一个label用于内存检测。菜单选择的功能让同一套PXE环境同时服务多种装机需求label minimal menu label ^Minimal Install kernel vmlinuz append initrdinitrd.img kshttp://192.168.100.10/ks/ks_minimal.cfg label desktop menu label ^Desktop Install kernel vmlinuz append initrdinitrd.img kshttp://192.168.100.10/ks/ks_desktop.cfg到这一步整套PXEHTTPTFTPDHCP环境就已经全部串起来了。把客户端的启动顺序调整为“网络启动优先”开机后你应该会看到引导菜单选择对应条目后自动进入Kickstart安装流程。6. 实测中踩过的坑完整排查链路理论配置全部完成不代表能一次性跑通。我在这个环境上做过多次重复安装测试下面这五个坑是出现频率最高、也最让人抓狂的每个都附上我从现象反推根因的完整排查链路。6.1 坑一客户端拿到了“别人家”的IP地址现象客户端开机进入PXE引导后在DHCP阶段卡了很久然后跳出了奇怪的IP信息后续无法从TFTP下载引导文件。排查过程我先在部署服务器上确认dhcpd服务运行正常然后去客户端捕获的PXE日志里看到它拿到的IP根本不是部署服务器分配的192.168.100.x网段。回头检查虚拟化平台的网络配置发现问题出在虚拟机的默认NAT网络自带了DHCP服务这个服务在同一个广播域里“抢答”了客户端的DHCP请求。修复方式把部署服务器和待安装客户端放进VMware Workstation的“仅主机模式”网络里并在虚拟网络编辑器中关闭该网络的DHCP服务只保留一个静态子网。物理机环境则要确认交换机上只有部署服务器这一台DHCP服务器不存在多个DHCP服务互相抢答的情况。经验PXE环境里的DHCP必须唯一。当客户端广播请求时如果网络中存在第二个DHCP服务谁能更快响应就会抢到这个机会PXE引导信息也只能从响应的那台DHCP服务返回。这不是配置错误是网络环境层面的“插队”。6.2 坑二PXE引导成功了但安装进入图形界面而不是自动执行现象客户端成功从TFTP下载了引导文件并启动内核但进入的是Anaconda图形安装界面和手动安装没有任何区别无人值守直接失效。排查过程这个现象说明引导链路是通的问题集中在Kickstart地址没传对。我去TFTP根目录检查了pxelinux.cfg/default文件发现里面有kshttp://192.168.100.10/ks/ks.cfg这个参数但仔细一看IP末尾多了个斜杠拼写错误。客户端在加载内核时没有收到合法的ks地址Anaconda只能退回交互模式。修复方式修正default文件里的ks参数确保URL从部署服务器上可以完整访问。以后每次改完default文件我都会在浏览器里先试一遍Kickstart地址确认能打开文件内容再去做装机测试。这个习惯帮我节省了至少十次重启客户端的时间。6.3 坑三TFTP下载文件极慢卡在加载initrd阶段现象客户端能拿到引导程序pxelinux.0但在下载initrd.img时速度极慢左等右等最后超时失败。排查过程TFTP传输很慢的典型原因有三个网络链路问题、文件过大、UDP被限速。我在部署服务器上用tftp命令手动下载同一个文件发现也慢。用tcpdump抓包看TFTP流量确认UDP 69端口数据往返正常服务端每次ACK都及时唯一的问题是客户端在TFTP默认的块大小下反复等待确认应答传输效率极低。这是TFTP协议本身的特性每个数据块都要等待ACK确认延迟高时效率下降明显。修复方式首先确认防火墙没有限制UDP端口的传输速率再检查是否多个客户端同时从一台TFTP下载导致拥堵。对于大文件我更建议在TFTP配置里显式调大块大小参数把server_args加上--blocksize 1468CentOS 6.x的tftp-server支持这个选项能从根上缓解慢的问题。6.4 坑四安装到一半提示找不到网卡现象Anaconda启动后进入安装流程但到网络配置阶段报错提示找不到可用的网络设备安装无法继续。排查过程这个问题发生在较新的网卡硬件上比如Intel I219-V这类型号。CentOS 6.4的发行内核较早驱动列表里没有包含这些新硬件的驱动模块。PXE引导本身没有问题vmlinuz能加载但内核缺少对应的网卡驱动自然无法初始化网络。修复方式两个方向。一是加载驱动程序初始化盘将厂商提供的驱动做成dd镜像挂进initrd里在append后面追加ddhttp://192.168.100.10/drivers/。二是把内核和驱动同步升级到较新的维护版比如CentOS 6.10的内核驱动覆盖面远好于6.4。作为经验正式环境批量交付前先用一台待交付型号做测试机可以提前发现这类硬件兼容性问题。6.5 坑五系统装完了但IP地址没有生效现象Kickstart安装全程顺利重启后进入系统但ifconfig显示网卡没有IP网络不通。排查过程我在%post脚本里执行了删除网卡持久化规则的操作理论上重启后系统会重新生成规则并匹配当前MAC地址。但实测发现虚拟化平台上的网卡MAC会在多次克隆后变化而network服务在启动时读取了旧的/etc/sysconfig/network-scripts/ifcfg-eth0配置设备名对不上网络自然起不来。修复方式在Kickstart文件里把网络配置改为network --bootprotodhcp --deviceethX --onbootyes并在%post里用脚本动态修正接口名与配置文件名的对应关系。更稳妥的做法是让%post直接重写/etc/udev/rules.d/下的持久化规则并确保配置文件里的DEVICE与当前接口名一致。这五个坑基本覆盖了PXEKickstart环境的绝大多数故障类型。核心排查思路是逐层断开先确认DHCP通不通再确认TFTP通不通再确认HTTP通不通最后才去检查Kickstart文件内容本身。每次出问题都从链路最前端重新拉起不要跳着猜。7. 从能用到好用批量交付场景的进阶扩展当整套PXEKickstart环境跑通之后你已经解决了“能不能自动装”的问题。接下来就是锦上添花的优化了这些配置不影响核心功能但会让日常维护舒服很多。针对不同硬件的多个分组你可以为每个分组配置不同的Kickstart文件。比如数据库服务器和Web服务器的分区策略、软件包组合完全不同。PXE引导菜单天然支持多label你要做的只是维护好多个ks文件在菜单条目上分别指向它们。这样同一套PXE环境就能一次性交付不同规格的服务器。对于需要固定IP的交付场景DHCP支持基于MAC地址的静态绑定host node01 { hardware ethernet 00:0C:29:XX:XX:01; fixed-address 192.168.100.21; next-server 192.168.100.10; filename pxelinux.0; }配上绑定之后这台机器无论什么时候重装拿到的都是同一个IP。这个功能在管理严格的生产机房非常实用。Kickstart文件里的%packages段只控制了安装阶段能装什么。系统装完了后续还要装中间件、调配置怎么办我习惯在%post里直接把内网Yum仓库源配置好一次性解决后续所有软件安装依赖内网源的问题cat /etc/yum.repos.d/internal.repo EOF [internal] nameInternal Repository baseurlhttp://192.168.100.10/yum/ enabled1 gpgcheck0 EOF这样装出来的系统从第一天起就自带可用的软件源不用浪费人工去一台台配。最后提一个方向性的建议如果你管理的机器数量上了规模纯手工维护PXE加一堆ks文件会开始变得痛苦。这时候可以了解下Cobbler这类PXE包装管理工具它在底层还是同样的一套PXE和Kickstart逻辑但把dhcp配置、tftp文件组织、ks模板管理、镜像导入统一成了一体化管理界面。理解了原生PXE的原理之后再去用那些工具会顺理成章得多。第一次跑通无人值守装机的时候看着屏幕上安装进度条自己走完、系统自动重启、然后弹出登录提示符那种感觉确实很爽。后来每次给一批新机器做初始化我都觉得当初花在折腾这套环境上的时间是这几年最值得的一笔投入。如果你现在正好有实验环境在手不要只看不练拿两台机器反复装几次把这些坑都趟一遍比看十篇文档都有用。