外观
资源映射(Resource Mapping)
前面几篇直接把 PCI 地址(比如 01:00.0)或 USB 端口路径写进虚拟机配置。这种"裸设备 (Raw Device)"写法在单机上没问题,一旦进了集群,换个节点、换个插槽就会失效。资源映射解决的正是这个问题。
为什么需要它
- 地址会漂移:同一张显卡插在不同节点、甚至同一节点换个插槽,PCI 地址都可能不一样,硬编码进虚拟机配置就得跟着改。
- 迁移需要知道设备在哪些节点上有效:配合 HA 使用直通设备时,PVE 需要知道这个逻辑设备在集群的哪些节点上有对应的物理硬件。
- 权限最小化:不想把整台宿主机的管理权限都给某个用户,只想让他能给自己的虚拟机挂一个映射好的 USB 加密狗,映射本身可以单独授权。
开始之前
单机环境也能用资源映射,只是价值没有集群环境明显。它不会凭空生成硬件——每个节点上必须真的插着对应的物理设备,映射只是记录"这个逻辑名字,在这个节点上对应哪个物理地址"。
操作步骤
1. 创建 PCI 设备映射
Web UI:数据中心 → 资源映射 (Resource Mappings) → 添加 → PCI 设备:
| 字段 | 说明 |
|---|---|
| Name | 之后虚拟机引用它的逻辑名,比如 gpu-transcode |
| 各节点的物理地址 | 集群里每个装了对应硬件的节点,分别填它在那个节点上的 PCI 地址,插槽不同也没关系 |
| Live Migration Capable | 实验性选项,见下方提示 |
Live Migration Capable 不是普遍可用的能力
这个勾选项依赖硬件和驱动同时支持设备状态迁移,绝大多数消费级显卡和网卡都不支持。不要指望勾上它就能带着直通设备在线迁移——大多数场景下,直通设备依然遵循"这台虚拟机只能在有对应硬件的节点上启动,且不能在线迁移"的基本限制。
2. 创建 USB 设备映射
Web UI:数据中心 → 资源映射 → 添加 → USB 设备,思路一样:给一个逻辑名(比如 license-dongle),为每个可能插着这个设备的节点分别填厂商:产品 ID 或者物理端口路径。
3. 在虚拟机里引用映射
给虚拟机加设备时,来源选 Mapped Device(而不是 Raw Device),选择上面创建好的逻辑名。配置文件里会变成:
text
hostpci0: mapping=gpu-transcode,pcie=1或者:
text
usb0: mapping=license-dongle4. 按需给非 root 用户单独授权
数据中心 → 权限,可以只把某个映射的使用权限授权给指定用户或角色,不需要给他整个宿主机的管理权限。
检查结果
- 把虚拟机迁移到另一个已经在映射里配置了对应物理地址的节点,虚拟机能正常启动并找到设备,不用改配置。
- 用命令行确认映射内容:
sh
# 宿主机 shell
pvesh get /cluster/mapping/pci
pvesh get /cluster/mapping/usb- 如果某个节点上映射解析不到实际存在的设备,虚拟机在那个节点上会启动失败并给出明确报错,而不是静默忽略直通配置——这也是判断"映射配置是否覆盖了当前节点"的方法。
常见问题
虚拟机在某个节点上起不来,报找不到映射的设备。 检查这个节点的映射条目有没有配置、地址是否和 lspci/lsusb 实际看到的一致。
还能不能用以前裸地址(Raw Device)的写法? 能,两种方式共存,只是集群环境下推荐用映射,减少迁移时改配置的麻烦。
用了资源映射,还需要检查 IOMMU 分组吗? 需要。映射解决的是"地址会变"的问题,不解决"这个设备能不能被干净地单独直通"的问题,后者仍然取决于读懂 IOMMU 分组里说的硬件拓扑。
参考资料
- PCI(e) Passthrough - Proxmox VE Wiki("Resource Mapping" 相关说明)
- USB Physical Port Mapping - Proxmox VE Wiki