简介:一份针对VMware ESXi平台的网络直通(PCI Passthrough)配置实操指南,面向虚拟化运维工程师、系统管理员及希望提升虚拟机网络性能的技术人员。资源内容围绕在ESXi环境下将物理网络接口卡直接分配给虚拟机这一场景,完整覆盖前置检查(硬件是否支持直通、是否开启64位寻址)、BIOS设置、虚拟机添加PCI设备,以及hypervisor.cpuid.v0、pciPassthru.use64bitMMIO、pciPassthru.64bitMMIOSizeGB三个关键参数的配置方法与含义,同时梳理了直通带来的兼容性与安全性风险。资源为1个docx文档,压缩包大小343KB,内容结构清晰,适合按步操作。已有1945人学习,可供初次配置网络直通或排查相关问题的读者参考。
1. 网络直通为什么让人愿意折腾:ESXi 下 PCI 设备与虚拟机之间的专线
ESXi 下的 PCI 设备直通,绝大多数人第一个目标就是网络直通:把一块物理网卡从 vSphere 的虚拟交换层里摘出来,整块 PCIe 设备交给某一台虚拟机独占。ESXi 把它叫 DirectPath I/O,效果等同于给这台虚拟机拉了一根物理专线,DMA 直接落进网卡,不再经过 vSwitch 的软件转发和 vmxnet3 的队列复制。适合跑软路由、DPDK 抓包、以及想拿掉虚拟交换机 overhead 的低时延业务。这篇不聊虚拟机资源调优,只讲一块网卡如何从 vSwitch 摘下来、挂给 VM、以及配置过程中最容易翻车的几个地方。
2. ESXi 下配置 PCI 网卡直通的准备:硬件识别、VT-d 与最小命令集
2.1 先识别哪些 PCI 设备值得直通:网卡模型与 IOMMU 门槛
直通不是把 vSwitch 里的“网络适配器”换成别的类型,而是把整块 PCIe 网卡直接从宿主机的 PCI 枚举里拿掉,再整个交给虚拟机。所以第一步不是打开 ESXi 界面,而是确认主板和 CPU 支持 VT-d,也就是 IOMMU。BIOS 里找不到 VT-d 的话,vSphere Client 的设备列表里“Passthru”按钮永远是灰的,命令行执行esxcli hardware pci pcidevice set -e true也会提示设备不支持。这个门槛卡住了相当一批人。
我一般会先去 BIOS 的 Advanced 菜单里找 “Intel VT-d” 或者 AMD 平台的 “IOMMU”,开启后保存重启,再进 ESXi。很多服务器默认是关的,尤其是一些二手板子,刷过魔改 BIOS 后 VT-d 选项被藏得很深,得先恢复默认设置再找。这一步不做,后面所有 esxcli 操作都是白搭。顺带说一句:如果你是因为“ESXi 增加网卡驱动”才搜到这篇文章,那得先确认这块网卡已经被 ESXi 识别,驱动都加载不出来时,直通无从谈起,那是另一个问题。
网卡选型上,Intel 82599(X520)、X710/XL710 系列、Mellanox ConnectX-4/5、Broadcom 57412 这些带成熟 PF 驱动的卡直通后表现最稳,VM 内驱动齐全,多队列和中断都能正常用。板载的 Realtek RTL8111 这类消费级网卡我不是很推荐直通,固件中断处理不行,VM 里跑 DPDK 会莫名其妙的丢包,而且这类网卡本身吞吐就不高,留在虚拟交换机里当管理口更合适。下面是我在选型时会参考的对比表:
| 网卡类型 | 典型型号 | 队列/中断能力 | 直通适配度 | 备注 |
|---|---|---|---|---|
| Intel 万兆 | X520/X710 | 多队列完整 | 高 | 驱动最成熟,DPDK 首选 |
| Mellanox | ConnectX-4/5 | 多队列完整 | 高 | 对 RDMA 直通也友好 |
| Broadcom | 57412/57416 | 多队列完整 | 高 | 注意固件版本 |
| Intel 千兆 | I350 | 队列一般 | 中 | 直通后管理网口不够用时才用 |
| 板载消费级 | RTL8111 | 单队列 | 低 | 不建议直通,留作管理口 |
2.2 在 ESXi 8.0 里查询 PCI 网卡并打开直通:三条 esxcli 命令
在 ESXi Shell 里,查询所有 PCI 设备最简单的方式是直接按 PCI 类别过滤。网络控制器的 PCI 类码是 0x02,所以用-c 0x02可以把网卡和存储卡、显卡区分开,避免 grep 出来一堆没用的设备。
esxcli hardware pci pcidevice list -c 0x02执行后你会看到类似 0000:03:00.0 的设备地址,后面跟着厂商 ID、设备 ID、以及当前是否被 vmkernel 占用。如果这一串输出里什么都没有,说明这块网卡压根没被 ESXi 识别,得回到驱动层解决。如果输出了但命令行操作报错,先回 2.1 查 VT-d。
确定设备地址后,启用直通:
esxcli hardware pci pcidevice set -d "0000:03:00.0" -e true参数里-d是 PCI 设备地址,-e true表示开启 passthru。注意这个操作必须重启后才真正生效,ESXi 需要重新枚举 PCI 设备,让 vmkernel 放弃对该设备的驱动绑定。直接重启:
esxcli system shutdown reboot -r now重启后再查询一次,如果看到该设备状态变成 Passthru enabled,并且原来的 vmnic 编号已经不再出现在 ESXi 的物理网卡列表里,说明放权成功。这里的逻辑是:直通后 ESXi 已经看不到这块“物理网卡”,它变成了一个裸 PCI 设备,不能再被 vSwitch 使用。
2.3 直通前把物理网卡从 vSwitch 摘下来:先迁管理口再直通
很多人直接对正在跑管理网络的 vmnic 执行直通,重启后 ESXi 管理 IP 就丢了。原因很简单:vmk0 是挂在 vSwitch0 上的,而 vSwitch0 的物理出口就是这块网卡,直通等于把出口拆了,管理平面直接失联。这条血泪经验我每次都要强调:先把管理网络挪走,再直通。
常见做法是往现有 vSwitch 里加一块备用网卡,让管理网络先走新出口:
esxcli network vswitch standard uplink add -v vSwitch0 -u vmnic2 esxcli network vswitch standard uplink remove -v vSwitch0 -u vmnic0 esxcli network ip interface list第一条命令把 vmnic2 加进 vSwitch0 作为新的物理出口,第二条把要直通的 vmnic0 从 vSwitch 摘掉。第三条用来确认 vmk0 仍然存在,并且连接状态正常。执行顺序不能反,否则中间会断一下管理网络。如果机器有带外管理口(IPMI/iDRAC)倒也能救回来,但没有带外口的话,只能去物理机接键盘显示器进 DCUI 恢复,相当狼狈。
如果这台 ESXi 只有一块物理网卡,我建议直接放弃整体直通,改用 SR-IOV 或者加一块 PCIe 网卡再做。因为没有第二块网卡时,直通唯一的管理口等于给自己挖坑,后面所有操作都没有后悔药。
3. 把直通网卡挂给虚拟机:vmx 参数、内存预留与 MMIO 黑洞
3.1 在虚拟机里添加 PCI 设备:界面操作与 vmx 参数
直通使能并重启后,回到 vSphere Client,找到目标虚拟机,编辑设置,添加其他设备,选择 PCI 设备,下拉列表里就会出现刚才启用的 0000:03:00.0。选中、确定、开机,这是最基本的路径。但直接这样启动经常会失败,尤其是大内存的虚拟机,报错信息里会出现关于 MMIO 或 DMA 的字样。
添加成功后,虚拟机的 vmx 配置文件里会多出几行,内容大致如下:
pciPassthru0.present = "TRUE" pciPassthru0.id = "0000:03:00.0" pciPassthru0.vendorId = "0x8086" pciPassthru0.deviceId = "0x10fb"这里vendorId和deviceId是 PCI 厂商号和设备号,0x8086 是 Intel,0x10fb 是 82599ES 万兆网卡,都会按物理设备自动填好,不需要手工改。你真正需要关心的是pciPassthru0.id,它对应的是宿主机上的 PCI 地址,ESXi 重启后偶尔会因为 PCI 枚举顺序变化导致地址漂移,所以记录原地址是排查问题的关键。
3.2 三个必调参数:预留全内存、64 位 MMIO、设备复位
直通网卡跑起来之后,VM 内网卡驱动会通过 DMA 直接读写物理内存,这就要求虚拟机所有内存页面必须固定在物理内存里,不能被 ESXi 回收或者迁移。所以 Edit Settings 里 Memory 部分必须勾选 Reserve all guest memory,相当于把这条虚拟机钉死在这台宿主机上。如果不预留,虚拟机可能能开机,但运行一段时间后出现内核 DMA 报错,甚至直接死机。
另外两个参数需要手动加到 vmx 文件里。在 vSphere Client 中可以用“编辑配置”功能添加,或者直接 SSH 到 ESXi 改 vmx 后重新注册虚拟机:
pciPassthru.use64bitMMIO = "TRUE" pciPassthru.allowDeviceReset = "TRUE"use64bitMMIO是让直通设备使用 64 位 MMIO 地址空间。现在很多万兆网卡和 NVMe 控制器的 BAR 空间都超过了 4GB,如果 ESXi 没有把 MMIO 空间映射到 64 位地址段,虚拟机开机时会直接报设备资源不足。部分主板还需要在 BIOS 里开启 Above 4G Decoding,否则即使 vmx 里写了这个参数,宿主机也分配不出合适的地址窗口。
allowDeviceReset允许虚拟机开机时对物理设备做一次复位,避免上一次虚拟机异常关机后设备还停在异常状态。这两个参数加完之后,务必确认虚拟机已关机再编辑,否则不会生效。
3.3 直通设备上的“非直通”保留项:为什么不能同时挂 vSwitch
这块直通网卡不能再出现在任何 vSwitch 的 uplink 列表里,也不能被 vmkernel 网口绑定。道理很简单,设备已经被整体交给了某台 VM,ESXi 驱动已经卸载,再把它挂到 vSwitch 上等于同时被两个所有者驱动。
实际操作中常见的翻车场景是:直通前忘了摘 uplink,直通后 ESXi 仍然把 vmnic0 挂在 vSwitch0 配置里,但系统里已经找不到 vmnic0 了。这时候虚拟交换机会报 uplink 缺失,VM 网络倒是能通,但 ESXi 自身管理平面可能已经断了。解决办法就是回到 2.3 的命令,确认直通前已经执行过 uplink remove。
4. 在虚拟机内部验证直通效果:队列、驱动与吞吐对比
4.1 在 Ubuntu 里用 lspci 和 ethtool 确认物理网卡已直通
虚拟机开机进入 Ubuntu 之后,第一件事不是跑 iperf3,而是确认系统看到的到底是不是物理网卡。如果还是 VMXNET3,说明直通根本没生效,只是虚拟网卡在走 vSwitch。
lspci -nnk | grep -A 3 -i ethernet ethtool eth0 ethtool -l eth0lspci 输出里如果出现 Intel 82599ES 或 Mellanox ConnectX 字样,说明物理网卡已经呈现在虚拟机里;如果出现 VMware VMXNET3,则要回去查 PCI 设备是否真的处于 Passthru 状态。ethtool eth0 能显示网卡速率、驱动名和固件版本,驱动名应该是 ixgbe、i40e、mlx5_core 这类原生驱动,而不是 vmw_net。ethtool -l 查看队列数量,万兆网卡在直通模式下通常能看到多个 Combined 队列,如果只有 1,说明驱动没有正确启用多队列。
4.2 用 iperf3 做一次可复现的吞吐对比:直通和 vmxnet3 的差距
验证直通到底有没有价值,我会在同一台 VM 上先跑虚拟网卡,再跑直通网卡,用固定参数做对比。注意不能同一时间两个网卡一起跑,否则流量会互相干扰,结论不干净。
iperf3 -c 192.168.100.10 -t 60 -P 8参数里-c是服务端地址,-t 60表示跑 60 秒,-P 8开 8 个并发流。看两个指标:总带宽和传输结束时的 CPU 占用。vmxnet3 在大量小包场景下会吃掉大量 CPU,而直通网卡把中断直接送到 VM 内,宿主机不用参与每包复制,CPU 占用通常能下降 20% 到 30%。带宽在小包场景下的提升比 TCP 大包明显得多,这正是软路由和 DPDK 场景愿意折腾直通的原因。
如果对比结果发现直通后带宽反而更低,大概率是中断绑定问题。多数服务器网卡有多个队列,但默认中断可能全部落在 CPU 0 上,换一张网卡不一定能自动改善。这时候要回到物理网卡的 ethtool -L 和 Affinity 设置,把队列分散到不同核上,才能发挥多队列优势。
4.3 直通不生效时先查这三处:passthru 状态、VT-d、内存预留
虚拟机内看不到物理网卡时,按顺序排查。第一,回到 ESXi Shell,执行esxcli hardware pci pcidevice list -c 0x02,确认目标设备状态是 Passthru enabled,如果显示 Passthru disabled,说明设备没被正确放权。第二,去 BIOS 确认 VT-d 和 Above 4G Decoding 都没关,很多主板更新 BIOS 后会恢复默认关闭。第三,确认虚拟机的所有内存已经预留,没预留时虚拟机开机阶段就可能报错。
还有一种情况是被 vmkernel 抢先绑定。ESXi 重启后部分设备会在一瞬间被原驱动认领,导致直通状态还在但实际无法分配给虚拟机。处理方式是把设备先设为 disable passthru,再 enable 一次,再重启。这是直通里最典型的玄学问题,没有更聪明的办法,就是重新 toggle 一下。
5. 直通配置避坑指南:管理口断连、设备消失与快照失效
5.1 现象:开启直通并重启后,ESXi 管理 IP 直接 ping 不通
原因:直通的网卡本身就是管理口所在 uplink,vmkernel 把网卡放权后,vSwitch 失去了物理出口,整个管理网络随之断开。
解决:如果还能通过带外管理口进 ESXi,先把管理用的 vmnics 重新调整,再用esxcli hardware pci pcidevice set -d "0000:03:00.0" -e false关闭直通,重启后先去加备用 uplink,再重新直通。没有带外口的只能在物理机上接显示器进 DCUI,按 F2 配置网络,把 vSwitch 的 uplink 改到其他物理网卡上。这个坑我在 2.3 里已经反复强调,直通前必须保证管理口有冗余路径。
5.2 现象:虚拟机开机能亮系统,但网卡接口 link down,虚拟机内 ethtool 无链路
原因:硬件直通成功,但 VM 内网卡驱动没能正确初始化 PHY,常见于固件状态异常或上一次使用未正常关机。部分 Intel 卡还和主板 PCIe ASPM 节能策略有关。
解决:先在 VM 内执行ethtool -s eth0 autoneg off speed 10000 duplex full强制设定一次速度和双工,看链路能否起来。起不来的话,关机后在 ESXi 里对该 PCI 设备执行一次复位操作,也就是把直通关闭再开启。要是设备有独立的管理固件,比如 Mellanox,用厂商工具刷新固件后再试。
5.3 现象:直通配置保留着,但 ESXi 重启后 PCI 设备列表中找不到该网卡
原因:设备被 vmkernel 重新加载了原生驱动,或者 IOMMU 编组把设备分到了多个 PCIe 组,直通只启用了其中一个 function。多网口网卡尤其容易出现这种问题,每个网口都是一个独立 function,只直通其中一个时,ESXi 可能仍需要整个 PCIe 组都处于 passthru 状态。
解决:先执行esxcli hardware pci pcidevice list -c 0x02,确认所有相关 function 的地址。如果是多 function 网卡,把同属一个 PCIe 组的几个 function 全部 enable,再重启。ESXi 界面里也能看到设备是否能被分组,通常组内任意一个 function 被占用,整个组都不能再给其他 VM 用。
5.4 现象:直通网卡的虚拟机无法做快照、克隆,vMotion 也报错
原因:DirectPath I/O 是物理设备直写内存,快照和迁移需要冻结和重放设备状态,ESXi 做不到对硬件 DMA 状态的快照,所以这些功能在直通后默认不可用。
解决:直通前就要想清楚这台虚拟机是否需要 HA 和 DRS。如果确实需要 vMotion 或有快照需求,就别用整体直通,退回到 SR-IOV,把 VF 分配给虚拟机,这样保留了迁移能力,代价是性能和隔离性略低于整体直通。
5.5 现象:直通设备地址变了,原来配置的 VM 找不到设备
原因:ESXi 重启或更换 PCIe 插槽后,BIOS 枚举顺序可能变化,直通设备地址从 0000:03:00.0 变成 0000:02:00.0。
解决:此时需要修改虚拟机的 vmx 文件,更新 pciPassthru0.id,然后重新注册虚拟机。为了避免频繁变地址,我会把所有 PCIe 网卡插到固定的槽位,并在 BIOS 里关闭不必要的 PCIe slot 枚举。这个坑常见于双路主板,第二颗 CPU 的 PCIe 枚举顺序在 BIOS 更新后变化更明显。
6. 用 esxcli 把直通配置固定成可复现脚本:验证与排错收尾
直通配置最怕每次重启后来回检查,我习惯把关键命令写成一个简单的 shell 脚本,放到 ESXi 的数据存储里,需要时直接执行,快速导出当前状态:
# 导出全部 PCI 网络设备及直通状态 esxcli hardware pci pcidevice list -c 0x02 > /tmp/pci_net_status.txt grep -B 4 "Passthru: true" /tmp/pci_net_status.txt第一条命令把所有网络控制器的 PCI 地址和状态写进文件,第二条命令过滤出已经开启直通设备的上下文,一眼看出哪些网卡已经放权、哪些还留在 vmkernel。执行完这个脚本后,我会对比 grep 结果里有没有原 vmnic 对应的地址,如果没有,说明确实已经不在虚拟交换层。
验证直通是否彻底生效,还有一个更直接的习惯:在 ESXi Shell 里看设备的 vmkernel 占用情况。命令行输出里,直通成功的设备不会有 “VMkernel Name: vmxnet3” 之类的字段,而是以 PCI 地址形式独立存在。配合虚拟机的 lspci,能确认宿主机和虚拟机两侧看到的 PCI 设备是同一个地址,整个链路才算闭环。
如果你之后要把这套 ESXi 下的直通方案搬到 PVE 上,注意 PCI 地址在 /etc/pve/qemu-server/ 里的虚拟机配置文件中要重新写,ESXi 和 Linux 的 PCI 枚举规则本质上一致,但直通编排完全不同,ESXi 的 vmnic 概念在 PVE 里不存在,对应的是 hostpci0 参数。迁移前先把所有直通设备从虚拟机里摘掉,迁移完成后再重新绑定,直接带着直通配置迁移,通常会因为固件状态残留导致新平台开机不稳定。
这几年配直通卡,我养成了一个习惯:任何一次操作之前,先在 DCUI 里确认默认管理口有第二条物理出口,再动 passthru。带外口不是每一台机器都有,但网卡插槽和 PCI 地址是确定的,提前把拓扑记下来,比出了问题再查命令高效得多。希望帮到你。
本文还有配套的精品资源,点击获取