4. 校验技术概述
TFTP 这玩意儿,说实话,我用了好多年。简单、轻量,在局域网里跑 PXE 启动确实够用。但一旦你开始部署大镜像——比如超过 4GB 的 Windows ISO 或者定制 Linux 发行版——TFTP 的短板就暴露无遗了。它基于 UDP,没有拥塞控制,传输大文件时丢包率飙升,速度慢得让人抓狂。
我在一个数据中心项目里遇到过,用 TFTP 传一个 6GB 的 wim 文件,客户端反复超时重试,整个部署流程拖了将近 40 分钟。后来换成 HTTP,同样的网络环境,8 分钟搞定。所以这一章,我们就来聊聊怎么用 Nginx 或 Apache 替代 TFTP,把 PXE 引导升级到 HTTP/HTTPS 模式。
为什么非换不可?
说白了,TFTP 的设计初衷就不是为了传大文件。它只有 512 字节的固定块大小,没有窗口滑动,没有加密。而 HTTP 有 TCP 的拥塞控制、有 Keep-Alive、有断点续传,还能上 TLS 加密。你想想看,在跨网段部署或者公网部署场景下,TFTP 几乎不可用。
| 特性 | TFTP | HTTP/HTTPS |
|---|---|---|
| 传输协议 | UDP (端口 69) | TCP (端口 80/443) |
| 大文件支持 | 差(块大小 512B) | 优秀(支持分块传输) |
| 加密 | 无 | TLS (HTTPS) |
| 拥塞控制 | 无 | 有(TCP 自带) |
| 典型场景 | 局域网小文件 | 跨网段/公网大镜像 |
Nginx 配置:轻量又高效
我个人习惯用 Nginx 来做 HTTP 引导服务器。配置简单,性能好,内存占用低。下面是一个典型的配置片段,专门为 PXE 文件服务优化过。
server {
listen 80;
server_name pxe.example.com;
root /var/lib/pxe;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# 大文件传输优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
client_max_body_size 0;
# 针对 ISO/WIM 等大文件禁用压缩
location ~* \.(iso|wim|img|squashfs)$ {
gzip off;
sendfile_max_chunk 1m;
output_buffers 32 512k;
}
# 日志格式优化
access_log /var/log/nginx/pxe_access.log;
error_log /var/log/nginx/pxe_error.log;
}
这里有几个关键点。sendfile 必须开,它让内核直接搬运文件,省掉用户态拷贝。tcp_nopush 和 tcp_nodelay 配合使用,能减少小包数量,提升吞吐量。对于 ISO 这类大文件,我建议关掉 gzip 压缩——压缩大文件反而浪费 CPU,而且压缩后的数据流在 PXE 客户端可能解压失败。我曾经踩过这个坑,一个 8GB 的 ISO 开了 gzip,客户端加载到一半直接崩溃。
Apache 配置:稳定但稍重
如果你团队里 Apache 用得熟,用它也行。配置上比 Nginx 啰嗦一点,但功能一样。下面是一个参考配置。
<VirtualHost *:80>
DocumentRoot /var/www/pxe
ServerName pxe.example.com
<Directory /var/www/pxe>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
# 大文件优化
EnableSendfile On
EnableMMAP On
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# 禁用大文件压缩
SetEnvIfNoCase Request_URI \.(iso|wim|img|squashfs)$ no-gzip dont-vary
# 日志
CustomLog /var/log/apache2/pxe_access.log combined
ErrorLog /var/log/apache2/pxe_error.log
</VirtualHost>
注意 Apache 的 EnableSendfile 和 EnableMMAP 默认可能是 Off,记得手动打开。MMAP 能把文件映射到内存,对大文件读取有加速效果。但如果你内存紧张,建议关掉 MMAP,否则频繁换页反而拖慢速度。
grub.cfg 配置:从 HTTP 启动
服务器配好了,客户端怎么知道去 HTTP 拿文件?关键在 grub.cfg。传统 PXE 用 tftp 协议前缀,现在改成 http 或 https 就行。下面是一个实际可用的例子。
set net_default_server=192.168.1.100
set net_default_prefix=http://192.168.1.100/pxe
menuentry "Ubuntu 22.04 LTS HTTP Install" {
linux ${net_default_prefix}/vmlinuz root=/dev/nfs netboot=nfs nfsroot=${net_default_server}:/srv/nfs ip=dhcp
initrd ${net_default_prefix}/initrd.img
}
menuentry "Custom ISO via HTTP" {
linux ${net_default_prefix}/memdisk iso
initrd ${net_default_prefix}/custom.iso
}
这里有个坑。grub 的 http 模块默认只支持 HTTP 1.0,不支持分块传输编码。如果你的 Nginx 开了 chunked transfer encoding,grub 会直接报错。解决办法是在 Nginx 里强制关闭分块传输,或者用 proxy_buffering 把响应缓冲起来。我建议直接关掉分块:
location /pxe/ {
proxy_set_header Connection "";
proxy_http_version 1.0;
proxy_buffering off;
chunked_transfer_encoding off;
}
大文件传输优化:别让网络成为瓶颈
大文件传输优化,说白了就是三件事:减少握手、增大窗口、避免重传。我总结了一个清单,你可以照着检查。
- TCP 缓冲区调大: 在 sysctl.conf 里设置 net.core.rmem_max=16777216 和 net.core.wmem_max=16777216,然后重启网络服务。
- 启用 TCP 快速打开: net.ipv4.tcp_fastopen=3,减少三次握手的延迟。
- 关闭 Nagle 算法: 对于大文件传输,Nagle 算法反而有害。Nginx 里 tcp_nodelay on 就是干这个的。
- 使用 HTTP 范围请求: 如果客户端支持(比如 iPXE),可以分片下载,实现类似多线程加速的效果。
- CDN 或缓存代理: 跨地域部署时,用 Varnish 或 Squid 做缓存,避免回源带宽打满。
我记得有一次给一个教育城域网做批量部署,200 台教室电脑同时从一台服务器拉镜像。一开始没做优化,千兆网卡被打满,丢包率飙升到 15%。后来加了缓存代理,又调大了 TCP 缓冲区,并发量直接翻了三倍。
HTTPS 引导:安全但要注意性能
HTTPS 引导的好处很明显:防篡改、防中间人。但代价是 TLS 握手开销。对于 PXE 启动来说,每次连接都要做证书验证,如果镜像文件被拆成很多小片,握手次数会非常多。
我的建议是:只在关键环节用 HTTPS。比如 grub.cfg 本身用 HTTPS 拉取,确保引导配置不被篡改;但内核和 initrd 可以用 HTTP,因为它们的校验和已经在 grub.cfg 里用 hash 验证过了。这样既保证了安全,又避免了性能损失。
整体架构图
下面这张图展示了从 DHCP 到 HTTP 引导的完整流程。你可以看到,TFTP 只负责传一个很小的引导文件(比如 undionly.kpxe 或 bootx64.efi),剩下的所有大文件都走 HTTP。
从图上你能看到,TFTP 的角色被压缩到最小——只传一个几百 KB 的引导加载器。剩下的内核、initrd、根文件系统全部走 HTTP。这样既保留了 PXE 的兼容性,又享受了 HTTP 的高效传输。
避坑指南
最后分享几个我踩过的坑,希望能帮你少走弯路。
- 防火墙别忘了放行 80 端口: 听起来简单,但我真见过有人配了半天 Nginx,结果 iptables 把 80 端口 DROP 了。记得检查 iptables -L -n。
- grub 的 http 模块版本问题: 老版本 grub 的 http 实现有 bug,传输大文件会断。建议用 grub 2.06 以上版本。
- UEFI 安全启动: 如果开了 Secure Boot,HTTP 引导的加载器必须签名。要么用 shim 链式加载,要么在 BIOS 里关掉 Secure Boot。生产环境建议用 shim。
- 并发数估算: 一个千兆网口,理论最大吞吐 125MB/s。如果每个客户端下载速度 10MB/s,最多支持 12 台并发。超过这个数,要么加网卡绑定,要么上 CDN。