干了这么多年运维,我最怕的就是批量装系统。以前给机房几十台机器做系统,抱着一堆U盘挨个插、挨个进BIOS、挨个选PE镜像,一天下来腰都直不起来。后来换过传统的PXE方案,结果又被DHCP、TFTP、pxelinux.0、menuboot这类配置文件折磨得够呛。直到我用Docker把iVentoy跑起来,才真正体会到什么叫"网络装机平台就该这么干"。这篇就来聊聊我怎么用Docker部署iVentoy,把PXE装机这件事彻底简化,以及实际使用中那些文档里根本不会写的坑。
iVentoy这个工具,熟悉Ventoy的人应该能猜到它是干什么的——Ventoy是让你把多个ISO塞进U盘、开机从U盘启动后自己选镜像来装系统;iVentoy则是把这一套逻辑搬到了网络上,聊天机器网卡PXE启动后,直接从一个Web管理页面里维护的ISO列表中选择镜像,系统就走网络引导开始安装了。配合Docker部署,整个平台可以做得非常干净,宿主机不用装一堆乱七八糟的依赖,升级迁移也都省心。
这篇文章不是给纯新手的保姆级教学,但也尽量做到说人话。如果你是运维、网管、经常折腾装机工具的技术爱好者,或者正在为公司机房找一个简单可靠的多系统批量装机方案,这篇应该能给你省下不少时间。
1. 为什么我要把PXE装机工具换成iVentoy
1.1 传统PXE方案劝退我的那些点
传统的PXE网络装机,说白了就是组合一套"老四样":DHCP负责给客户端发IP、指向引导服务器;TFTP负责把引导文件发给客户端;NFS/HTTP/FTP负责共享ISO或系统文件;最后还要手工维护一个启动菜单,告诉客户端该加载哪个内核和initrd。也就是说,你得在一台Linux服务器上把dhcpd、tftpd-hpa、syslinux、nfs-kernel-server这些服务全部配置好,环环相扣,一个地方写错客户端就起不来。
最让我头大的是维护成本。装一个系统版本的时候还好,如果你要维护Windows 10、Windows 11、Ubuntu Server、CentOS、还有几个国产发行版的镜像,每个都要在菜单文件里增加一段引导配置,Windows的还得处理Samba共享和PE的wim路径,动一次就是一次踩坑循环。再加上UEFI和Legacy BIOS的引导文件还不一样,grub菜单和pxelinux菜单两套配置要分别维护。我当年第一次搭好传统PXE用了将近一天,第二个月要加一个新镜像,又折腾了半天。
1.2 iVentoy把PXE复杂逻辑变成了一个Web页面
iVentoy的做法完全不一样。它把DHCP、TFTP、HTTP、引导菜单生成这几件事全部打包成了内置能力。你要做的事情只有三件:把ISO文件放到指定目录、在Web管理页面里勾选启用、然后让客户端从网卡启动。客户端启动后会自动从iVentoy获取IP、下载引导程序,并弹出一个图形化的系统镜像选择菜单,所有ISO都在列表里,用键盘上下选择就行,跟Ventoy U盘的体验几乎一样。
它等于把"网络装机"这个原本需要专业Linux服务器知识才能搞定的事情,降维成了一个"维护一个镜像库、开一个服务"的操作。这种设计对于我这种经常需要在不同厂商的服务器、不同架构的机器上装机的人来说,吸引力是致命的。
1.3 用Docker再套一层的理由
既然iVentoy已经把PXE的复杂性收拢了,为什么我还要用Docker跑?
第一是环境隔离。iVentoy内置了DHCP和TFTP服务,这类服务跟宿主机系统本身的网络配置耦合很深,手动安装很容易和已有服务打架。放到容器里后,宿主机本身非常干净,出了问题删掉容器重建就行,不会把宿主机搞坏。
第二是可迁移性和升级方便。数据目录单独挂载出来,以后想换台机器跑,直接把挂载目录拷过去、重新跑个容器就能无缝衔接。升级工具版本时也不用担心残留旧配置,拉新镜像、换掉容器就完事。
第三是我个人习惯。Docker部署的资源占用非常低,而带来的管理收益是实打实的,尤其适合放到一台常年开机的NAS或者小主机上,让整个装机平台作为一个常驻服务存在,而不是"用时才开机的临时服务器"。
2. 搭建前的网络规划:哪些端口该开、哪些情况会冲突
2.1 部署环境选型与网络拓扑
先明确一个前提:PXE启动依赖客户端的网卡以广播形式发送DHCP请求,然后根据回应包里的服务器地址去下载引导文件。所以iVentoy所在的机器必须和待装机的客户端处于同一个二层网络里。这个"同一二层网络"的意思就是:不要跨路由转发DHCP广播流量(除非你后面配置了DHCP Relay,这个我第六节再说),最省事的做法是把iVentoy直接接在客户端同一台交换机上。
机器本身没有太高要求,2核CPU、2GB内存就够跑了。真正吃资源的是你放ISO的存储空间和网络带宽:几百GB的镜像库,跑在机械盘上也行,但客户端加载大ISO时IO会成为瓶颈,如果是SSD或者NAS上的万兆链路,体验会好很多。我用一台飞牛NAS做了演示环境,Docker跑在NAS的容器服务里,镜像放在挂载出来的数据目录上,整套平台平时一直开机待命。
2.2 端口规划:26080、26081、67、69分别干什么
iVentoy用到的端口不算多,但每个都不能漏。我整理了一张表方便对照:
| 端口号 | 协议 | 用途 | 说明 |
|---|---|---|---|
| 26080 | TCP | Web管理界面 | 浏览器访问 http://服务器IP:26080 管理ISO、查看日志 |
| 26081 | TCP | 客户端数据服务 | 客户端下载ISO、获取菜单配置时用到的HTTP服务 |
| 67 | UDP | DHCP服务 | 给客户端分配IP、下发引导服务器地址,就是DHCP正式端口 |
| 69 | UDP | TFTP服务 | 客户端下载PXE引导文件使用,就是TFTP正式端口 |
如果你用-p做端口映射,就得把上面这四个端口全部映射进去,少了哪个客户端都起不来。不过这里有个更稳妥的方案,下面单独说。
2.3 现有DHCP/路由器环境的冲突风险
这是部署iVentoy最容易翻车的地方。iVentoy自带DHCP服务,它默认会接管67端口,但你家网络里的路由器、其他网关设备很可能也开着DHCP。一旦两者同时回应客户端,客户端拿到哪个IP、哪个引导地址完全不可控,表现就是一部分机器能正常启动、一部分机器卡在获取IP阶段。
解决思路一般有两种。第一种:关闭路由器或其他设备的DHCP,让iVentoy成为网络中唯一的DHCP服务器,这适合专用装机网络。第二种:保留现有DHCP,但关闭iVentoy的内置DHCP,只使用它的TFTP和菜单功能,然后在现有DHCP服务器上配置"next-server"和"bootfile"参数,指向iVentoy所在机器的IP和引导文件名。第二种方法对网络环境无侵入,但前提是你得会改路由器或DHCP服务器的配置。实际情况中,如果你只是临时给一个台式机装系统,我更推荐用直连网线的方式,把iVentoy机器和待装机机器单独组成一个小网络,避开办公网络里的DHCP冲突。
3. Docker部署iVentoy的完整操作
3.1 获取Docker镜像的两种方式
iVentoy的官方仓库在GitHub上,项目名是ventoy/PXE,作者提供了Dockerfile。所以获取镜像有两种方式:一是看官方是否在Docker Hub发布了对应镜像,如果有,直接docker pull后运行;二是把仓库clone下来本地构建。我实际部署时因为网络原因选择了本地构建,虽然多花一两分钟,但版本完全可控。
# 方式一:拉取官方镜像(以官方文档发布为准) docker pull ventoy/iventoy:latest # 方式二:从源码构建 git clone https://github.com/ventoy/PXE.git /opt/iventoy-src cd /opt/iventoy-src docker build -t iventoy-local .本地构建有个好处,Dockerfile里可以看到作者对运行目录、端口、软件包依赖的全部定义,方便你理解这个容器里到底是怎么组织的,出了问题也好排查。我建议还是以官方Release页面标注的镜像名为准,版本号和架构都有说明,比我自己猜要靠谱。
3.2 准备数据目录并启动容器
启动之前,先准备一个数据目录,用来存放ISO和iVentoy的配置、日志。因为以后这个目录是核心资产,升级容器的时候全靠它。
mkdir -p /data/iventoy/iso然后启动容器。这里我必须强调一个关键选择:网络模式推荐使用host模式,而不是默认的bridge端口映射。
原因很简单:iVentoy的核心是DHCP服务,DHCP请求是广播包。Docker的bridge模式加-p 67:67/udp这类端口映射,对广播包的转发处理有时会非常诡异,表现就是客户端发出去的DHCP Discover收不到应答。而host模式让容器直接共享宿主机网络栈,DHCP广播能直接被iVentoy监听到,省去所有NAT和端口映射的中间层。实测下来,host模式几乎不会遇到"客户端获取不到IP"这类问题。
docker run -d --name iventoy --restart=always \ --network host \ -v /data/iventoy:/app/data \ iventoy-local注意,如果你用的是Windows或macOS上的Docker Desktop,host网络模式支持得并不好,因为那本质上是跑在一个虚拟机里的。所以iVentoy的Docker方案更推荐在Linux宿主机、或者支持容器功能的NAS系统(比如飞牛OS、群晖、威联通这些基于Linux的NAS)上运行。在Windows上实在要跑,就用WSL2的Docker环境,并且把网络模式确认清楚。
启动完成后,看下容器状态:
docker ps | grep iventoy docker logs -f iventoy日志里会出现iVentoy初始化DHCP/TFTP服务和Web服务的信息,看到监听成功就可以进行下一步了。
3.3 防火墙放行与Web界面验证
容器跑起来了不代表客户端能访问到,防火墙这道坎必须过。如果你宿主机开了firewalld或ufw,需要放行这几个端口:
# firewalld firewall-cmd --permanent --add-port=26080/tcp firewall-cmd --permanent --add-port=26081/tcp firewall-cmd --permanent --add-port=67/udp firewall-cmd --permanent --add-port=69/udp firewall-cmd --reload # ufw ufw allow 26080/tcp ufw allow 26081/tcp ufw allow 67/udp ufw allow 69/udp验证Web界面很简单:浏览器访问http://你的服务器IP:26080,正常会看到iVentoy的管理页面。第一次进去可能没有默认密码或要求你设置一个管理密码,按提示操作即可。页面上能看到网络状态、DHCP开关、ISO列表这些核心功能模块。到这一步,平台本身已经算部署完成了。
提示:在管理界面的设置里,如果网络中已有其他DHCP服务器,务必先在这里把内置DHCP功能关掉,避免广播风暴式的冲突。如果这个网络是专用的装机子网,再选择开启DHCP。
4. 从客户端开机到系统安装:PXE引导链路拆解
4.1 一次完整PXE引导的过程
很多人部署好了iVentoy,但客户端一开机就报"PXE-E51: No DHCP or proxyDHCP offers were received"这类错误,根本不理解引导链路为什么失败。这里我把一次完整的PXE引导流程拆开,每个环节对照iVentoy做了什么,排障时思路就清晰了:
- 客户端网卡通电,PXE ROM主动发出DHCP Discover广播包,它在问"网络里有没有人能给我一个IP,同时告诉我引导服务器在哪"。
- iVentoy的内置DHCP收到广播后回应:分配一个IP,并携带next-server(引导服务器地址,就是iVentoy宿主机IP)和filename(引导文件名,Legacy BIOS通常是pxelinux.0,UEFI通常是bootx64.efi)。
- 客户端拿到IP后,通过TFTP协议去下载引导文件。TFTP的69端口在这里就派上用场。
- 引导文件被加载后,它再从iVentoy获取启动菜单配置,常见的是grub2的配置格式。这就是你在客户端屏幕上看到的镜像列表。
- 用户选择某个ISO后,iVentoy动态生成对应的引导项:Linux镜像会指定内核和initrd并通过HTTP挂载ISO文件;Windows镜像会通过wimboot方式加载boot.wim等文件。
- 引导流程接管后进入安装程序,开始正式的装系统流程。
这套链路里,DHCP负责"定位"、TFTP负责"给引导程序"、HTTP负责"给镜像",三者缺一不可。理解了这一点,后面所有排障都会变得有迹可循。
4.2 添加ISO并让客户端进入启动菜单
在管理页面里,添加ISO就是想象中那么简单:把ISO文件扔进/data/iventoy/iso目录,然后回到Web界面刷新一下,文件就出现在列表里了。不需要任何额外的引导配置,不需要写menuentry,也不需要手动指定内核参数。
客户端那边,开机后按提示进入启动设备选择菜单(联想的机器是F12,戴尔是F12,惠普是F9,不同品牌略有差异),选择带有UEFI或Legacy字样的网卡选项,回车。稍等十几秒,就能看到iVentoy的引导菜单,上下键选好镜像回车,系统安装程序就开始加载了。
我在同一台交换机上同时维护了Windows Server 2022、Ubuntu 22.04、Debian 12三个ISO,实测切换镜像装系统,全程不需要再碰服务器端做任何配置。这也是iVentoy对运维最有吸引力的地方:镜像库的管理成本和传统PXE完全不在一个量级。
4.3 Windows和Linux镜像的加载差异
这里有一个值得展开的细节:虽然你在菜单里看到的都是"选一个ISO",但底层的加载方式完全不同。
Linux发行版(Ubuntu、Debian、CentOS等)的ISO结构相对标准,iVentoy可以直接解析ISO里的vmlinuz和initrd,然后通过HTTP把ISO作为安装源挂载给安装程序,安装完基本不会出现莫名其妙的兼容性问题。
Windows的ISO则不一样,Windows安装程序依赖PE环境,iVentoy会用wimboot方式把ISO里的boot.wim等关键文件提取出来、通过TFTP/HTTP加载到客户端内存中,再引导进入Windows安装界面。这个过程对网卡驱动、磁盘控制器驱动比较敏感,少数情况下会卡在加载阶段。遇到这种情况,可以优先试试Windows原版ISO而不是精简版、Ghost版,因为原版ISO里的驱动相对完整。
5. 实战排障:我踩过的坑和完整排查思路
5.1 客户端反复重启、一直获取不到IP
这个问题我遇到得最多,而且绝大多数情况下不是iVentoy本身坏了,而是网络环境有干扰。完整的排查链路我建议这样走:
第一步,看容器有没有起来。docker ps确认容器状态是Up,如果退出了,docker logs看一下有没有报错,比如端口被占用、配置文件写不进去等。
第二步,在客户端上看错误提示。PXE-E51表示没收到DHCP应答,PXE-E53表示拿到了IP但TFTP下载失败。如果是E51,先查网络中是否有其他DHCP服务器跟iVentoy抢答。最简单的验证方法是:在客户端机器上用静态IP接进来,拨掉其他网络设备,只保留iVentoy宿主机和客户端直连,再试一次。如果直连能启动,那就是DHCP冲突,按前面第二节的方式把其他DHCP关掉,或者关闭iVentoy的内置DHCP、在现有DHCP里做next-server指向。
第三步,确认端口映射或防火墙。如果你用的是bridge模式,检查67/69 UDP是否真的映射成功、防火墙规则是否生效。我在一台CentOS 7上遇到过firewalld放行了端口但Docker服务重启后iptables规则被重刷的问题,表现为之前能用,某天突然不能用了,排查到最后是firewalld和Docker的iptables管理互相干扰,换成host网络模式后彻底消失。
5.2 引导菜单能出来但ISO加载失败
这个坑的特点是:DHCP和TFTP都正常,菜单列表也能看到,但选择某个ISO后进度条走一半,客户端报错或者直接重启。
先替换法:换个ISO试试,排除镜像文件本身损坏或者格式不兼容。iVentoy对原创ISO支持最好,一些魔改过的精简版、装机版ISO可能因为引导结构被改动而加载失败。
再检查存储路径:如果你把ISO放在NAS的远程挂载目录或者Samba共享里,还要确认容器对这个目录有完整读写权限,以及底层网络IO是否稳定。大ISO(Windows镜像动辄5~6GB)在弱网环境加载时,HTTP连接超时会卡在"Loading files..."之类的位置。
还有一点容易忽略:磁盘剩余空间。iVentoy在引导过程中可能会产生临时文件(比如Windows的wimboot需要临时解包),宿主机空间不够会导致内存盘写入失败。我当时排查了一个类似问题,最后发现是/var/lib/docker所在分区只剩几百MB,清理完空间后一切正常。
5.3 Secure Boot导致的UEFI引导失败
这个问题只在UEFI模式、且BIOS里开启了Secure Boot时出现。现象是客户端能进入iVentoy的菜单,但选择镜像后出现"Verification failed: (0x1A) Security Violation"之类的提示,然后机器自动重启。
原因是iVentoy动态生成的引导程序并没有通过微软的Secure Boot签名认证,安全启动会拦截。解决方法很直接:进BIOS设置,把Secure Boot改成Disabled,或者在Boot Security里允许执行未签名引导程序。有些品牌的商务机BIOS里Secure Boot还分"Standard"和"Custom"模式,切到Custom再关闭执行验证也行。
这个坑之所以值得单独记录,是因为它不影响DHCP和TFTP,菜单也出得来,很多人会误以为是iVentoy的问题,绕一大圈才发现是BIOS安全策略。
5.4 Docker升级和重启后的自启动问题
其实--restart=always已经解决了大部分重启自启动问题,容器在宿主机重启后会跟着起来。但我在实际操作中发现,如果容器的数据目录权限不对,或者挂载的目录在容器启动时还没挂好(比如NAS的存储池还没就绪),容器会反复"启动即崩溃",看起来就是服务怎么都不在。
排查方法还是docker logs,如果看到权限相关报错,直接在宿主机上对数据目录做一次chown -R,保证容器内进程可以读写。iVentoy容器内通常以非root用户或root运行,具体看镜像定义,但通用做法是把数据目录的所有者改成和镜像内声明的UID一致,或者在宿主机上chmod -R 777先救急(不推荐长时间这么干)。
升级容器时我的流程是:先docker stop iventoy,再docker rename iventoy iventoy-backup(保留旧容器以便回滚),然后重新build或pull新镜像、跑一个新的iventoy容器。数据目录不动,升级完配置和ISO都在。跑一段时间确认没问题再删掉旧容器。
6. 进阶玩法:把iVentoy玩得更顺手
6.1 多镜像分组与默认菜单
当你的镜像库越来越大,ISO列表一长串时,靠Web页面里一个个文件平铺就不够用了。iVentoy支持在管理界面创建目录分类,把不同类别的镜像(Windows系列、Linux系列、工具类PE)放到不同目录里。客户端菜单会按照目录层级展示,找镜像的速度会快很多。
我习惯在/data/iventoy/iso下建几个子目录,比如iso/windows、iso/linux、iso/tools,然后把ISO文件分别放进去,Web界面里刷新就能看到分组效果。如果你经常要给同一批机器装同一个系统,可以研究一下配置项的默认选项,减少操作员的选择成本。
6.2 接入Windows无人值守安装
iVentoy本身解决的是"引导镜像"这个环节,一旦客户端进入了Windows安装程序,剩下的交互还是得人工点。如果你连"分区、输用户名、输序列号"这些也想省掉,可以配合Windows的autounattend.xml应答文件使用。
做法是在Windows ISO里插入应答文件,或者把应答文件放到可被客户端访问的路径并在引导参数里指定。iVentoy官方文档提到过Windows免交互安装的一些支持方式,升级到合适版本后可以做到"选中镜像、回车、等待系统装完"的效果。我实际跑通的流程是:用Windows原版ISO,在管理平台里配置了应答文件指向,客户端从网卡启动后约15到20分钟,一台全新的Windows系统就装好了,中间不需要人工干预。
6.3 多网段部署:DHCP Relay/ip helper
如果你的机房里有多个VLAN,客户端不在iVentoy所在的那个网段,PXE广播默认是过不去的。这时候就需要在交换机或路由器上配置DHCP Relay(思科叫ip helper-address),把客户端的DHCP广播转发到iVentoy这台机器所在网段。
配置好Relay之后,iVentoy收得到DHCP Discover,但它分配出去的IP和引导服务器地址必须是客户端可达的。这意味着iVentoy宿主机上的路由要通、相应网段的DHCP作用域要对,且客户端能访问iVentoy的26081端口来下载ISO。多网段比单网段复杂得多,如果不是必须,我的建议还是让装机流量在同一个专用VLAN里跑,装完系统再让机器切换到业务VLAN,把装机网络和业务网络分开,既清晰又安全。
我在实际使用中发现,最舒服的形态是:iVentoy跑在一台长期开机的Linux小主机或NAS上,单独接一个装机电口,待装机器直接插同一个交换机。要装系统时开个机,平时服务关不关都无所谓,占用的资源极小。把镜像库的权限管理好,整个团队就都能用浏览器自行装机,不用再排队拿U盘了。如果你手头正好有闲置小主机,或者你的NAS支持Docker容器,非常推荐按上面的步骤搭一套,让网络装机这件事真正变成"开箱即用"的基础设施。