2. 网络启动基础

DHCP 服务器,说白了就是给网络里的设备自动发「身份证」和「地图」的。在 PXE 网络启动里,它不光要发 IP,还得告诉客户端:「你的系统镜像在哪个服务器上,文件名叫什么」。这就是 option 66 和 67 的活儿。

我最早搭 PXE 环境时,觉得 DHCP 嘛,配个地址池就完了。结果客户端死活拿不到启动文件,抓包一看,option 66 根本没发出去。嗯,从那以后我再也不敢小看这一步了。

2.1 安装与基础配置

Debian/Ubuntu 系用 isc-dhcp-server,CentOS/RHEL 系用 dhcp。我个人习惯用 Ubuntu,包名直接就是 isc-dhcp-server。

# Ubuntu / Debian
sudo apt update
sudo apt install isc-dhcp-server -y

# CentOS / RHEL
sudo yum install dhcp -y

装完之后,核心配置文件在 /etc/dhcp/dhcpd.conf。默认内容基本是空的,你得自己写。

注意:装完别急着启动。先确认网卡接口对不对。Ubuntu 上要改 /etc/default/isc-dhcp-server 里的 INTERFACESv4,指定你 DHCP 要监听的网卡,比如 eth0 或 ens33。我见过有人忘了配这个,服务死活起不来。

2.2 IP地址池规划

地址池规划,听起来简单,但坑不少。你想想看,PXE 启动时客户端会先拿一个临时 IP,等装完系统再拿正式 IP。这两个阶段如果地址池重叠,就会冲突。

我的做法是:

  • PXE 启动池:单独划一个子网或一段范围,比如 192.168.100.100 - 192.168.100.200,租期设短一点,5 分钟就够。
  • 正式业务池:等系统装完,由安装后的系统重新请求 IP,走正常的 DHCP 池,租期可以设 24 小时以上。

为什么要分开?因为 PXE 阶段客户端可能很多,如果租期太长,IP 会被占着不放。我曾经在生产环境遇到过,200 台机器同时装机,地址池直接爆了,后面的机器拿不到 IP,装机失败。从那以后,我坚持 PXE 池和业务池隔离。

池类型 IP 范围 租期 用途
PXE 启动池 192.168.100.100 - 192.168.100.200 5 分钟 临时获取启动文件
业务池 192.168.100.201 - 192.168.100.254 24 小时 系统安装后使用

2.3 option 66 与 option 67 设置

这是 PXE 启动的关键。option 66 告诉客户端 TFTP 服务器的 IP 地址,option 67 告诉客户端要下载的启动文件名。

配置示例:

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 subnet-mask 255.255.255.0;
  option domain-name-servers 8.8.8.8;

  # PXE 启动相关
  next-server 192.168.100.10;        # option 66:TFTP 服务器 IP
  filename "pxelinux.0";             # option 67:启动文件名

  # 租期设置
  default-lease-time 300;
  max-lease-time 600;
}

这里 next-server 就是 option 66,filename 就是 option 67。注意,文件名要跟 TFTP 服务器上的实际路径一致。我遇到过有人把文件名写成了 /pxelinux.0,多了个斜杠,结果客户端找不到文件。

小技巧:如果你用 UEFI 启动,文件名通常是 bootx64.efi 或 grubx64.efi。传统 BIOS 用 pxelinux.0。不确定的话,可以在 DHCP 里同时配两个,用条件判断区分架构。

2.4 多子网与多启动文件支持

实际项目中,网络环境往往不止一个子网。比如我有办公网、生产网、管理网,每个网段都要能 PXE 启动。这时候就要配多个 subnet 块。

# 管理网段
subnet 10.0.0.0 netmask 255.255.255.0 {
  range 10.0.0.100 10.0.0.200;
  next-server 10.0.0.10;
  filename "pxelinux.0";
}

# 生产网段
subnet 172.16.0.0 netmask 255.255.255.0 {
  range 172.16.0.100 172.16.0.200;
  next-server 172.16.0.10;
  filename "pxelinux.0";
}

如果不同网段用不同的启动文件,比如管理网用 pxelinux.0,生产网用 grubx64.efi,直接在各自的 subnet 里改 filename 就行。

2.5 启动与验证

配置写完后,先检查语法:

sudo dhcpd -t -cf /etc/dhcp/dhcpd.conf

没有报错的话,重启服务:

sudo systemctl restart isc-dhcp-server
sudo systemctl enable isc-dhcp-server

验证方法:找一台客户端,设为网络启动,看能不能拿到 IP 并开始下载启动文件。或者直接在 DHCP 服务器上看日志:

sudo tail -f /var/log/syslog | grep dhcpd

你会看到类似这样的输出:

DHCPDISCOVER from xx:xx:xx:xx:xx:xx via eth0
DHCPOFFER on 192.168.100.100 to xx:xx:xx:xx:xx:xx via eth0
DHCPREQUEST for 192.168.100.100 from xx:xx:xx:xx:xx:xx via eth0
DHCPACK on 192.168.100.100 to xx:xx:xx:xx:xx:xx via eth0

如果只看到 DISCOVER 和 OFFER,没有 REQUEST 和 ACK,说明客户端没接受你的 IP。原因可能是地址池满了,或者 option 66/67 没配对。

核心要点:
  • 地址池要隔离,PXE 池租期短,业务池租期长。
  • option 66(next-server)指向 TFTP 服务器 IP。
  • option 67(filename)指向启动文件名,路径要准确。
  • 多子网就配多个 subnet 块,各自独立。
  • 启动前一定要用 dhcpd -t 检查语法。

2.6 整体流程示意图

下面这张图展示了 DHCP 在 PXE 启动中的位置和作用。你可以看到客户端从 DHCP 拿到 IP 和 TFTP 信息后,再去下载启动文件,整个过程环环相扣。

DHCP 在 PXE 启动中的流程 DHCP 在 PXE 启动中的流程 PXE 客户端 DHCP 服务器 TFTP 服务器 ① DHCP DISCOVER ② DHCP OFFER (IP + option 66/67) ③ DHCP REQUEST ④ DHCP ACK ⑤ 根据 option 66/67 下载启动文件 关键说明 • option 66(next-server):指定 TFTP 服务器 IP • option 67(filename):指定启动文件名(如 pxelinux.0) • 地址池规划:PXE 池租期短(5分钟),业务池租期长(24小时) • 多子网环境:每个 subnet 独立配置 option 66/67

从图上可以清楚看到,DHCP 服务器是整个启动流程的「交通指挥」。它给了客户端 IP,还指了路——TFTP 服务器在哪、要拿什么文件。没有它,客户端就是个瞎子。

避坑指南:我曾经遇到一个案例,DHCP 配置完全正确,但客户端就是拿不到文件。最后发现是防火墙把 TFTP 的端口(69/UDP)给拦了。所以,配完 DHCP 别忘了检查防火墙。另外,如果 DHCP 服务器和 TFTP 服务器不在同一台机器上,确保网络路由是通的。