4. HTTP 服务器搭建:让 PXE 客户端能“下载”到文件
上一章我们聊了 DHCP 和 TFTP,它们解决了“找服务器”和“下载小文件”的问题。但 PXE 真正要加载的内核、initrd 文件系统,甚至整个 ISO 镜像,动辄几百兆。TFTP 那点传输效率,说实话,慢得让人抓狂。
这时候,HTTP 就该登场了。说白了,HTTP 在 PXE 里的角色就是一个“高效文件搬运工”。它速度快、支持大文件、还能做并发传输。我个人习惯,只要不是古董级网络环境,一律优先用 HTTP 替代 TFTP 来传内核和根文件系统。
4.1 为什么 PXE 需要 HTTP?
你想想看,传统 PXE 只用 TFTP,但 TFTP 是基于 UDP 的,没有窗口滑动机制,每次只能传 512 字节,还要等确认。传一个 5MB 的内核还行,要是传一个 200MB 的 initrd,那等待时间简直让人崩溃。
我在项目中遇到过最极端的情况:一个教育城域网批量部署 500 台终端,用 TFTP 传 300MB 的镜像,平均每台要等 8 分钟。换成 HTTP 后,同样的文件,1 分半钟就搞定了。这就是差距。
HTTP 在 PXE 中的优势非常明显:
- 传输效率高: 基于 TCP,有拥塞控制和窗口滑动,大文件传输速度远超 TFTP。
- 支持断点续传: 虽然 PXE 客户端本身不常用这个特性,但 HTTP 协议本身支持。
- 并发能力强: 一台 HTTP 服务器可以同时服务上百个 PXE 客户端,而 TFTP 的并发能力很弱。
- 配置灵活: 可以通过虚拟主机、目录映射等方式,轻松管理不同版本的启动文件。
4.2 安装与配置 Nginx 作为 PXE 的 HTTP 服务器
Nginx 是我个人最推荐的 PXE HTTP 服务器。为什么?因为它轻量、高并发、配置简单。你不需要装一堆模块,一个核心配置就能跑起来。
下面我以 CentOS/RHEL 7/8 为例,带你走一遍完整的安装配置流程。
4.2.1 安装 Nginx
# 安装 EPEL 源(如果还没装)
yum install -y epel-release
# 安装 Nginx
yum install -y nginx
# 启动并设置开机自启
systemctl start nginx
systemctl enable nginx
# 检查状态
systemctl status nginx
安装完成后,默认的网站根目录在 /usr/share/nginx/html。但我们要做 PXE 服务,一般会单独建一个目录来存放启动文件。
4.2.2 配置 PXE 专用的虚拟主机
我个人习惯为 PXE 服务单独建一个虚拟主机配置,这样方便管理和隔离。
# 创建 PXE 文件存放目录
mkdir -p /data/pxe/centos7
mkdir -p /data/pxe/centos8
# 创建 Nginx 配置文件
vim /etc/nginx/conf.d/pxe.conf
写入以下配置:
server {
listen 80;
server_name pxe.example.com; # 换成你的实际域名或 IP
# 关闭 access_log 可以减轻磁盘 IO 压力,生产环境建议开启
access_log /var/log/nginx/pxe_access.log main;
error_log /var/log/nginx/pxe_error.log;
# 根目录指向 PXE 文件总目录
root /data/pxe;
# 开启目录列表,方便调试时查看文件
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# 针对特定文件类型的优化
location ~* \.(iso|img|vmlinuz|initrd|squashfs)$ {
# 大文件优化:启用 sendfile 和 tcp_nopush
sendfile on;
tcp_nopush on;
# 设置缓存过期时间,避免浏览器缓存(PXE 客户端一般不会缓存)
expires off;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
}
autoindex on 在调试阶段非常有用。我曾经有一次排查问题,发现客户端报 404,打开目录列表一看,原来是文件名大小写写错了。这个开关能帮你快速定位文件路径问题。但生产环境建议关闭,避免暴露目录结构。
配置完成后,检查语法并重载:
nginx -t
systemctl reload nginx
4.2.3 目录映射与文件放置
现在我们把 PXE 启动文件放到对应目录下。假设我们要部署 CentOS 7 和 CentOS 8:
# 挂载 ISO 镜像并复制内核和 initrd
mount -o loop /path/to/CentOS-7-x86_64-Minimal-2009.iso /mnt
cp /mnt/images/pxeboot/vmlinuz /data/pxe/centos7/
cp /mnt/images/pxeboot/initrd.img /data/pxe/centos7/
# 同样处理 CentOS 8
mount -o loop /path/to/CentOS-8.5.2111-x86_64-dvd1.iso /mnt
cp /mnt/images/pxeboot/vmlinuz /data/pxe/centos8/
cp /mnt/images/pxeboot/initrd.img /data/pxe/centos8/
# 别忘了复制整个 ISO 或者 squashfs 文件系统(如果需要网络安装)
cp /path/to/CentOS-7-x86_64-Minimal-2009.iso /data/pxe/centos7/
最终目录结构应该是这样的:
/data/pxe/
├── centos7/
│ ├── vmlinuz
│ ├── initrd.img
│ └── CentOS-7-x86_64-Minimal-2009.iso
└── centos8/
├── vmlinuz
├── initrd.img
└── CentOS-8.5.2111-x86_64-dvd1.iso
4.3 安装与配置 Apache(备选方案)
虽然我推荐 Nginx,但有些老系统或者特定场景下,Apache 可能更合适。比如你需要在同一个服务器上同时跑 PHP 应用和 PXE 服务,Apache 的模块生态更丰富。
配置 Apache 也很简单:
# 安装 Apache
yum install -y httpd
# 创建 PXE 目录
mkdir -p /var/www/html/pxe
# 配置虚拟主机(在 /etc/httpd/conf.d/pxe.conf)
<VirtualHost *:80>
ServerName pxe.example.com
DocumentRoot /var/www/html/pxe
<Directory /var/www/html/pxe>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
# 启动服务
systemctl start httpd
systemctl enable httpd
Apache 和 Nginx 的核心区别在于:
| 对比项 | Nginx | Apache |
|---|---|---|
| 并发模型 | 事件驱动,异步非阻塞 | 进程/线程模型,每个连接一个进程 |
| 静态文件性能 | 极高,尤其适合大文件 | 良好,但高并发下资源消耗更大 |
| 配置复杂度 | 简洁,学习曲线平缓 | 较复杂,.htaccess 机制灵活但影响性能 |
| 内存占用 | 低,适合嵌入式或低配服务器 | 相对较高 |
| 动态内容支持 | 需配合 FastCGI | 原生支持模块加载 |
4.4 静态资源访问测试
服务器配好了,文件也放上去了。怎么验证能不能正常访问?我一般分三步走。
4.4.1 本地 curl 测试
在服务器本机先测一下:
# 测试根目录是否可访问
curl -I http://localhost/
# 测试具体文件是否可访问
curl -I http://localhost/centos7/vmlinuz
# 查看返回的 HTTP 头,重点关注 200 OK 和 Content-Length
HTTP/1.1 200 OK
Server: nginx/1.20.1
Content-Type: application/octet-stream
Content-Length: 6520832
Last-Modified: Tue, 15 Dec 2020 08:30:00 GMT
如果返回 200,说明文件可以正常访问。如果返回 403,检查目录权限;如果返回 404,检查文件路径是否正确。
4.4.2 远程客户端测试
在另一台机器上,用 wget 或 curl 测试:
# 从客户端下载测试
wget http://192.168.1.100/centos7/vmlinuz
# 或者用 curl 测试
curl -O http://192.168.1.100/centos7/initrd.img
这里要注意防火墙。我曾经在客户现场排查了半天,最后发现是 firewalld 没放行 80 端口:
# 放行 HTTP 服务
firewall-cmd --permanent --add-service=http
firewall-cmd --reload
4.4.3 结合 PXE 配置文件验证
最后一步,修改 PXE 的默认配置文件,把内核和 initrd 的路径改成 HTTP 协议:
# 在 pxelinux.cfg/default 中
LABEL linux
MENU LABEL Install CentOS 7 via HTTP
KERNEL http://192.168.1.100/centos7/vmlinuz
APPEND initrd=http://192.168.1.100/centos7/initrd.img inst.repo=http://192.168.1.100/centos7/
然后启动一台 PXE 客户端,观察启动过程。如果能看到内核加载、initrd 解压,并且进入安装界面,说明 HTTP 服务器配置成功了。
4.5 本章知识体系总览
下面这张图,帮你把 HTTP 服务器在 PXE 中的位置和配置要点串起来:
这张图清晰地展示了:DHCP 和 TFTP 负责“引导”阶段,而 HTTP 负责“加载”阶段。配置 HTTP 服务器的核心就是安装、建目录、配虚拟主机、放文件、开防火墙,五步走完。