Duke Yin's Technology database

PVE虚拟机硬盘直通方法详解

在 Proxmox VE (PVE) 中将物理硬盘直接传递给虚拟机(直通)主要有三种常用方法,各有优缺点和适用场景:

三种主要方法

  1. 使用 qm set 命令映射整个物理磁盘 (Raw Device Mapping – RDM)
    • 原理: 在虚拟机配置文件中直接引用物理硬盘的设备节点 (如 /dev/sdX, /dev/disk/by-id/xxxx),绕过 PVE 存储层,虚拟机几乎直接访问物理磁盘。
    • 优点:
      • 性能最佳(接近原生)。
      • 配置相对简单。
      • 适用于任何文件系统(包括 NTFS, ZFS, VMFS 等),甚至未格式化的磁盘。
    • 缺点:
      • 不支持虚拟机快照。
      • 不支持在线迁移 (Live Migration)。
      • 磁盘在 PVE 主机上无法直接使用(被虚拟机独占)。
      • 迁移虚拟机时,需要手动处理该磁盘。
      • 使用 /dev/sdX 可能不稳定(磁盘顺序可能变),强烈推荐使用 /dev/disk/by-id/
    • 操作步骤:
      1. 找到磁盘的持久化 ID: 在 PVE Shell 执行:
        bash ls -l /dev/disk/by-id/
        找到你要直通的硬盘,通常你会看到类似
        ata-Samsung_SSD_860_EVO_1TB_S3Z8NB0K123456scsi-3600508b1001c1a2a3b4c5d6e7f8g9h0
        的链接。选择 scsi-wwn-ata- 开头的、不**带 -partN 后缀的条目,它代表整个磁盘。例如:scsi-0Google_PersistentDisk_pve-boot-disk
      2. 编辑虚拟机配置: 假设虚拟机 ID 是 100,磁盘的 by-id 是 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk
        bash qm set 100 -scsi1 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk
        • -scsi1: 指定使用 VirtIO SCSI 控制器(推荐,性能好,支持更多特性)。也可以用 -sata1, -ide1, -virtio1,但 SCSI 通常是最佳选择。
        • 后面的参数就是磁盘的完整 by-id 路径。
      3. 确认添加: 命令执行后,检查虚拟机硬件配置 (qm config 100) 或 Web 界面,应该能看到新添加的硬盘,类型显示为 scsi (或你指定的类型),路径就是那个 by-id。
      4. 在虚拟机中操作: 启动虚拟机,在虚拟机操作系统(如 Windows 磁盘管理、Linux 的 fdisk -llsblk)中,你应该能看到这块新磁盘。
        ⚠️ 注意: 如果磁盘之前有数据,小心不要误格式化。如果是一块新盘,需要在虚拟机内分区并格式化后才能使用。
  2. 将物理硬盘分区直通给虚拟机
    • 原理: 与方法 1 类似,但不是传递整个磁盘,而是传递磁盘上的某个特定分区 (如 /dev/sda1, /dev/disk/by-id/xxxx-part1)。
    • 优点:
      • 可以在 PVE 主机和其他虚拟机之间共享一块物理硬盘的不同分区(但强烈不推荐,极易导致数据损坏)。
      • 允许 PVE 主机使用同一块硬盘上的其他分区。
    • 缺点:
      • 继承了方法 1 的所有缺点(无快照、无在线迁移)。
      • 风险更高: 虚拟机如果误操作(如错误的分区工具),可能破坏同一物理磁盘上的其他分区数据。
      • 性能略低于直通整个磁盘(但通常可忽略)。
      • 配置更繁琐,需要精确指定分区。
    • 操作步骤: 与方法 1 几乎相同,只是在 qm set 命令中使用分区的 by-id 路径(带 -partN 后缀)。
      1. 找到分区的持久化 ID:
        bash ls -l /dev/disk/by-id/
        找到目标分区,例如 scsi-0Google_PersistentDisk_pve-boot-disk-part1
      2. 编辑虚拟机配置:
        bash qm set 100 -scsi2 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk-part1
      3. 确认添加: 同方法 1。
      4. 在虚拟机中操作: 同方法 1。虚拟机看到的是单个分区/块设备,而不是整个磁盘。
  3. 使用 passthrough 模式的 VirtIO-SCSI 控制器
    • 原理: 将整个物理硬盘作为一个 SCSI 设备,通过专门配置的 VirtIO-SCSI 控制器传递给虚拟机。这是方法 1 在 SCSI 控制器下的更正式实现。
    • 优点:
      • 性能优异(与方法 1 的 SCSI 方式相当)。
      • 支持 SCSI 设备的更多高级特性(如 TRIM/Discard 对于 SSD,SCSI 预留等)。
      • 配置语义更清晰(明确使用 SCSI 控制器)。
    • 缺点:
      • 继承方法 1 的主要缺点(无快照、无在线迁移)。
      • 配置稍微复杂一点(需要确保控制器类型正确)。
    • 操作步骤:
      1. 找到磁盘的持久化 ID: 同方法 1 步骤 1。
      2. 确保虚拟机使用 VirtIO SCSI 控制器:
        • 在虚拟机 硬件 设置中,查看是否有 SCSI控制器,类型是 VirtIO SCSI。如果没有,需要添加一个:
          • 点击 添加 -> SCSI控制器
          • 类型选择 VirtIO SCSI
      3. 使用 scsihwscsiX 添加磁盘: 假设虚拟机 ID 是 100,磁盘 by-id 是 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk
        • 方法 A (推荐 – 一步到位):bash qm set 100 -scsi1 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk,backup=0,discard=on
          • -scsi1: 指定连接到 VirtIO SCSI 控制器上的第一个 SCSI 设备。
          • ,backup=0: 重要! 防止 PVE 备份工具尝试备份这个直通磁盘(通常很大且可能包含不支持快照的文件系统)。
          • ,discard=on: 如果直通的是 SSD,启用此选项以支持 TRIM/Discard 指令,有助于 SSD 维护性能和寿命。
        • 方法 B (分两步 – 确保控制器存在):
          • 先添加控制器(如果还没有):
            bash qm set 100 -scsihw virtio-scsi-single # 或 virtio-scsi-pci
            (virtio-scsi-single 是常见选择)。
          • 再添加磁盘:
            bash qm set 100 -scsi1 /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk,backup=0,discard=on
      4. 确认添加: 检查 qm config 100,应该能看到类似:
        scsihw: virtio-scsi-single scsi1: /dev/disk/by-id/scsi-0Google_PersistentDisk_pve-boot-disk,discard=on,backup=0,size=976762584K
      5. 在虚拟机中操作: 同方法 1。虚拟机将其视为一个 SCSI 磁盘。

方法对比总结

特性方法 1: qm set (整个磁盘)方法 2: qm set (分区)方法 3: VirtIO-SCSI Passthrough
性能⭐⭐⭐ 最佳 (接近原生)⭐⭐⭐ 最佳 (接近原生)⭐⭐⭐ 最佳 (接近原生)
配置复杂度⭐⭐ 简单⭐⭐ 简单⭐⭐⭐ 稍复杂
支持快照❌ 不支持❌ 不支持❌ 不支持
支持在线迁移❌ 不支持❌ 不支持❌ 不支持
PVE 主机可用性❌ 独占⚠️ 可共享 (不推荐!)❌ 独占
传递对象整个物理磁盘物理磁盘的单个分区整个物理磁盘 (作为 SCSI 设备)
高级特性支持取决于总线类型取决于总线类型✅ 良好 (TRIM, 预留等)
数据安全风险低 (独占磁盘)高! (易损坏同盘分区)低 (独占磁盘)
推荐程度⭐⭐⭐ (特定边缘场景)⭐⭐⭐ (首选方法)

选择建议

  1. 首选方法 3 (VirtIO-SCSI Passthrough): 在需要将整个物理磁盘以最佳性能和功能直通给虚拟机时,这是最推荐的方式。务必加上 backup=0
  2. 方法 1 作为备选: 如果不想显式配置 VirtIO-SCSI 控制器,方法 1 使用 -scsiX 参数本质上也能达到类似效果(底层会自动处理控制器),但方法 3 的语义更明确。
  3. 尽量避免方法 2 (分区直通): 除非你有非常特殊且明确的需求,并且完全理解共享物理磁盘带来的极高数据损坏风险,否则强烈不建议使用分区直通。将整个磁盘分配给一个虚拟机或使用网络存储 (NFS, Ceph, iSCSI) 是更安全可靠的数据共享方式。
  4. 💡 考虑 PCIe 直通 (HBA 卡): 如果你需要将整个磁盘控制器(例如一个 SATA 或 SAS HBA 卡)及其连接的所有磁盘一起直通给一个虚拟机(常用于 FreeNAS/TrueNAS, ZFS 文件服务器等),可以使用 PCI(e) Passthrough。这需要在 PVE 主机启用 IOMMU (VT-d/AMD-Vi),并在虚拟机配置中直接传递 PCI 设备。这种方式虚拟机获得对控制器和磁盘的完全控制,性能最佳,也支持控制器级操作。但这超出了单个硬盘直通的范围。

⚠ 重要注意事项

  • /dev/disk/by-id/ 是关键: 永远使用 /dev/disk/by-id/ 下的持久化 ID 来引用磁盘或分区。使用 /dev/sdX/dev/nvmeXnY 等路径会导致配置在重启后失效(磁盘顺序可能改变)。
  • backup=0 参数: 对于直通磁盘,强烈建议添加 backup=0 参数(在 Web 界面添加磁盘时勾选 No backup 选项)。否则 PVE 的备份任务会尝试备份这块可能非常巨大的磁盘,导致备份失败、超时或占用大量空间,且备份出来的镜像通常也无法直接用于恢复直通场景。
  • discard=on 参数: 如果直通的是 SSD,添加 discard=on 参数(Web 界面勾选 Discard)以启用 TRIM/Discard 支持,这对 SSD 长期性能和寿命很重要。虚拟机内的文件系统也需要支持并启用 TRIM(如 Windows 优化驱动器、Linux 的 fstrim 服务或 discard mount 选项)。
  • 数据安全: 直通意味着虚拟机对物理磁盘有完全控制权。虚拟机内的误操作(如错误格式化)会直接损坏物理磁盘上的数据。确保虚拟机操作系统稳定可靠,并做好备份。
  • 独占访问: 被直通的磁盘在 PVE 主机上将无法直接访问(对于整个磁盘直通)或访问受限(对于分区直通,但极其危险)。确保 PVE 主机本身不需要访问该磁盘。
  • 快照与迁移: 所有直通方法均不支持虚拟机快照和在线迁移。这是追求原生性能的主要代价。
  • Windows 驱动程序: 如果直通给 Windows 虚拟机并使用 virtioscsi (VirtIO) 模式,必须在 Windows 中安装 VirtIO 驱动程序,否则磁盘无法识别。可以从 Fedora VirtIO-Win 项目 下载 ISO 并挂载给虚拟机安装。

方法1 操作步骤:

找到硬盘ID

ls /dev/disk/by-id

将想要直通的硬盘id记录下来 例如 ata-ST16000NM001G-2KK103_ZL2FNMM6

将硬盘直通给对应ID的虚拟机:

qm set 100 -scsi1 /dev/disk/by-id/ata-ST16000NM001G-2KK103_ZL2FNMM6,backup=0,discard=on

-sata1 数字不能和已有同类硬盘重复,比如已经有sata0,就使用sata1,最高能到5

100 是虚拟机的ID 根据实际情况修改

最后是第一部查到的硬盘id,不要带分区。

SATA和SCSI

即便使用SATA接口的HDD,也建议使用VirtIO SCSI方式直通虚拟化硬盘,性能比起SATA更好一点。

如果已经通过SATA直通过硬盘,如果修改为SCSI?

# 备份虚拟机配置 (PVE主机执行)
cp /etc/pve/qemu-server/100.conf /root/vm100_backup.conf
# 备份硬盘数据 (可选但推荐)
dd if=/dev/disk/by-id/ata-YOUR_DISK_ID of=/mnt/backup/disk.img bs=1M status=progress
# 1. 关闭虚拟机 (强制关机可能损坏数据!)
qm stop 100

# 2. 删除旧 SATA 设备 (注意:只删映射,不动数据!)
qm set 100 --delete sata0

# 3. 添加 VirtIO SCSI 控制器 (如果不存在)
qm set 100 --scsihw virtio-scsi-single

# 4. 以 SCSI 模式重新挂载同一物理硬盘
qm set 100 --scsi0 /dev/disk/by-id/ata-YOUR_DISK_ID,backup=0

# 5. 启动虚拟机并验证
qm start 100

验证操作成功的标志

  1. 虚拟机内部:
    • Windows:设备管理器 → 存储控制器中看到 “Red Hat VirtIO SCSI controller”
    • Linux:执行 lsscsi 应显示类似:
      [0:0:0:0] disk RedHat VirtIO SCSI disk /dev/sda
    • 检查磁盘数据完整性 (e.g., fsck/chkdsk)
  2. PVE 层:
qm config 100 | grep scsi0
# 正确输出:scsi0: /dev/disk/by-id/ata-XXXX,backup=0,size=XXXG

关键注意事项

  1. 驱动顺序不可逆!
    • 一旦切换到 VirtIO SCSI,不可直接改回 -sata0!否则虚拟机因无驱动将无法启动。
    • 回退方案:临时添加IDE/CDROM启动 → 安装SATA驱动 → 切回SATA模式。
  2. HDD性能提升有限但稳定性增强
    • 顺序读写速度变化不大 (受限于机械盘物理特性)
    • 随机访问提升约10-30%,尤其在高并发场景 (VirtIO减少CPU开销)
    • 更大的价值在于:热插拔支持、更好的错误恢复、未来兼容性
  3. 配置文件陷阱
    不要手动编辑 .conf 文件!务必用 qm set 命令,避免语法错误导致虚拟机启动失败。

总结

选择哪种方法取决于你的具体需求(性能、功能、安全性、管理性)。对于大多数需要将整个物理磁盘专用于单个虚拟机的场景,使用 VirtIO-SCSI Passthrough (方法 3) 并配置 backup=0discard=on (SSD) 是最佳实践。💪

#

发布评论

评论

标注 * 的为必填项。