virsh attach-disk
命令将其作为新磁盘设备附加到目标虚拟机,最后在虚拟机内分区格式化即可使用。好的,这是一篇针对网站访客,详细讲解如何将物理硬盘直通(Passthrough)给 KVM 虚拟机的文章,遵循内容价值和 E-A-T 原则:
将物理硬盘直接挂载给 KVM 虚拟机(也称为硬盘直通或 Passthrough)是一种将物理存储设备近乎完全地、排他性地交给虚拟机使用的技术,与使用虚拟磁盘文件(如 qcow2)相比,它能带来显著的性能提升(尤其是对于 I/O 密集型应用如数据库、媒体编辑),并允许虚拟机直接访问硬盘的原始特性和容量,以下是在 Linux KVM 环境下实现物理硬盘直通的详细步骤和重要注意事项。
核心优势:
- 极致性能: 绕过宿主机的文件系统和虚拟化层,虚拟机直接与硬件交互,大幅降低 I/O 延迟,提升吞吐量(特别是对 SSD/NVMe)。
- 访问底层功能: 虚拟机可以直接使用硬盘的特定功能(如 TRIM、高级格式化)。
- 充分利用容量: 直接使用物理硬盘的原始容量,避免了虚拟磁盘格式的额外开销。
- 简化迁移: 如果整个物理机迁移,物理硬盘上的数据也随之迁移。
适用场景:
- 运行高 I/O 负载的数据库(MySQL, PostgreSQL)。
- 视频编辑、渲染工作站。
- 需要直接访问磁盘 SMART 信息的监控系统。
- 运行需要直接硬盘访问的特定软件或操作系统。
重要警告与前提条件:
- 数据丢失风险: 此操作涉及底层硬件访问。极其重要:操作前务必对目标物理硬盘上的任何重要数据进行完整备份! 错误的配置可能导致数据丢失、文件系统损坏,甚至影响宿主机稳定性。
- 独占访问: 一旦直通给虚拟机,该物理硬盘不应再被宿主机或其他虚拟机直接读写(挂载),宿主机只能通过管理工具(如
virsh
)控制它作为虚拟机的一个设备。 - 设备识别: 你需要明确知道目标物理硬盘在宿主机上的设备标识符(如
/dev/sdb
,/dev/sdc
或更推荐使用持久化标识如/dev/disk/by-id/...
或/dev/disk/by-path/...
)。切勿混淆设备标识符! - KVM/libvirt 安装: 确保宿主机已正确安装并运行 KVM/libvirt 环境 (
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virtinst bridge-utils
或对应发行版命令)。 - 虚拟机状态: 目标虚拟机需要关机状态才能进行设备添加操作。
- 硬件兼容性: 绝大多数 SATA/SAS/NVMe 硬盘都支持直通,确保硬盘控制器工作正常。
详细操作步骤:
步骤 1:识别目标物理硬盘
-
在宿主机上打开终端。
-
使用命令列出所有磁盘设备:
lsblk -o NAME,SIZE,MODEL,MOUNTPOINT
或获取更详细的信息:
sudo fdisk -l
仔细查看输出,找到你想要直通的那个物理硬盘,注意它的设备名称(如
/dev/sdb
,/dev/nvme0n1
)。特别留意 SIZE(大小)和 MODEL(型号)来确认。 -
(强烈推荐) 获取持久化设备标识符: 设备名(如
/dev/sdb
)可能在重启或硬件变动后改变,导致配置失效,使用持久化标识符(基于 ID 或 Path)更可靠。- 基于 ID:
ls -l /dev/disk/by-id/
查找以
ata-
,nvme-
,wwn-
或scsi-
开头的链接,它们指向你的物理硬盘设备(如/dev/sdb
),选择ata-
或nvme-
开头的(不包含-partN
的链接),ata-SAMSUNG_SSD_860_EVO_1TB_S3Z8NB0KA12345
指向/dev/sdb
。 - 基于 Path (物理路径):
ls -l /dev/disk/by-path/
查找能唯一标识控制器和端口位置的链接(如
pci-0000:00:17.0-ata-1
指向/dev/sda
),选择指向整个磁盘的链接。
记下你选择的持久化标识符完整路径(/dev/disk/by-id/ata-SAMSUNG_SSD_860_EVO_1TB_S3Z8NB0KA12345
),这将用于后续配置。 这比使用/dev/sdb
安全得多。
- 基于 ID:
步骤 2:确保硬盘未被挂载
- 检查目标硬盘及其分区是否在宿主机上被挂载:
lsblk -o NAME,MOUNTPOINT /dev/sdX # 将 /dev/sdX 替换为你的实际设备名
MOUNTPOINT
列下有挂载点(如/mnt/data
),必须将其卸载:sudo umount /dev/sdX # 或卸载具体的分区 /dev/sdX1, /dev/sdX2 等
重要: 如果该硬盘是宿主机系统盘或包含重要数据,绝对不要卸载系统分区! 再次确认你操作的是正确的、非系统的目标硬盘。
步骤 3:编辑虚拟机 XML 配置文件
我们将通过修改虚拟机的 XML 定义文件来添加物理硬盘设备。
-
确保目标虚拟机已关机:
virsh list --all # 查看所有虚拟机状态 virsh shutdown <vm-name> # 如果还在运行,关闭它 virsh shutdown win10 # 示例,关闭名为 'win10' 的虚拟机
-
备份虚拟机 XML 配置(强烈推荐):
virsh dumpxml <vm-name> > <vm-name>-backup.xml
-
编辑虚拟机的 XML 配置:
virsh edit <vm-name>
这会用默认文本编辑器(通常是
vi
或nano
)打开 XML 文件。 -
在 XML 文件中,找到
<devices>
标签块,这个块内包含了虚拟机的所有设备(磁盘、网卡、显卡等)。 -
在
<devices>
块内,添加一个新的<disk>
设备配置。使用你在步骤 1 中获取的持久化标识符!<disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none' io='native'/> <!-- 重要: cache='none' 和 io='native' 通常能提供最佳直通性能 --> <source dev='/dev/disk/by-id/ata-SAMSUNG_SSD_860_EVO_1TB_S3Z8NB0KA12345'/> <!-- 替换成你的持久化标识符路径 --> <target dev='vdx' bus='virtio'/> <!-- 'x' 替换为下一个可用字母 (如 vdb, vdc...) --> <address type='pci' domain='0x0000' bus='0x00' slot='0x0X' function='0x0'/> <!-- 通常可以删除此行,让libvirt自动分配PCI地址 --> </disk>
配置详解:
<disk type='block' device='disk'>
:type='block'
表示使用块设备(物理硬盘),device='disk'
表示作为硬盘呈现给虚拟机。<driver ...>
:name='qemu'
: 使用 QEMU 驱动。type='raw'
: 直接访问原始块设备,没有额外的格式层。cache='none'
: 关键性能选项。 指示 QEMU 不进行任何缓存,让虚拟机直接管理缓存(推荐),如果虚拟机是 Windows 且可能非正常关机导致硬盘问题,可考虑cache='writeback'
(但性能稍差)。io='native'
: 使用 Linux 原生的 AIO(异步 I/O)接口,进一步提升性能。
<source dev='...'/>
: 这是最关键的地方! 务必填入你在步骤 1 中确认并记录的持久化设备标识符完整路径。<target dev='vdx' bus='virtio'/>
: 指定设备在虚拟机内部的标识符。dev='vdx'
:vd
表示 VirtIO 磁盘,x
是一个字母(a, b, c,…),检查 XML 中已存在的磁盘(通常是vda
系统盘),选择下一个未使用的字母(如第一个添加的可能是vdb
)。bus='virtio'
: 强烈推荐使用 VirtIO 总线。 这需要虚拟机安装 VirtIO 驱动(Linux 内核通常自带,Windows 需要额外安装),它能提供最优的 I/O 性能,如果虚拟机不支持 VirtIO,可使用bus='sata'
或bus='scsi'
(性能较差)。
<address .../>
: 这行通常可以安全删除,libvirt 在启动时会自动为设备分配一个合适的 PCI 地址,保留它可能导致冲突。
-
仔细检查添加的
<disk>
块,特别是<source dev='...'>
路径是否正确无误,确认<target dev='...'>
使用了可用的字母。 -
保存并退出编辑器(在
vi
中是:wq
,在nano
中是Ctrl+O
Enter
保存,Ctrl+X
退出)。
步骤 4:启动虚拟机并配置
-
启动虚拟机:
virsh start <vm-name>
-
连接到虚拟机的控制台(使用
virt-manager
图形界面最方便)或通过 SSH/RDP 登录虚拟机。 -
在虚拟机操作系统中:
- Linux 虚拟机:
- 打开终端。
- 检查新磁盘是否被识别(通常不需要重启):
lsblk # 或 `fdisk -l`
你应该能看到一个新的块设备(如
/dev/vdb
,对应你 XML 中设置的vdb
)。 - 分区(如果需要): 如果硬盘是全新的或需要重新分区:
sudo fdisk /dev/vdb # 或使用 `gdisk` 处理 GPT, `parted`
按照提示创建新分区(如
/dev/vdb1
)。 - 格式化文件系统:
sudo mkfs.ext4 /dev/vdb1 # 格式化为 ext4 (示例,根据需要选择) # 或 sudo mkfs.ntfs /dev/vdb1 # 如果需要 NTFS (Windows 兼容)
- 挂载使用:
- 创建挂载点:
sudo mkdir /mnt/myrawdisk
- 临时挂载:
sudo mount /dev/vdb1 /mnt/myrawdisk
- 永久挂载(编辑
/etc/fstab
):添加类似行/dev/vdb1 /mnt/myrawdisk ext4 defaults 0 0
(强烈建议使用 UUID 替换/dev/vdb1
,通过sudo blkid /dev/vdb1
获取)。
- 创建挂载点:
- Windows 虚拟机:
- 登录 Windows。
- 如果使用
bus='virtio'
且是第一次添加 VirtIO 磁盘,可能需要安装 VirtIO 驱动(可以从 Fedora 或 Red Hat 官网下载 VirtIO ISO 镜像并挂载安装)。 - 打开 “磁盘管理” (右键“此电脑” -> “管理” -> “磁盘管理”)。
- 通常会自动弹出 “初始化磁盘” 窗口,选择分区风格(MBR 或 GPT)。
- 在下方找到新添加的磁盘(显示为 “未分配”)。
- 右键点击未分配空间 -> “新建简单卷…” -> 按照向导进行分区和格式化(NTFS 通常是 Windows 的选择)。
- 分配驱动器号并完成,新盘符(如 E:)即可使用。
- Linux 虚拟机:
故障排除:
- 虚拟机启动失败: 仔细检查 XML 中的
<source dev='...'>
路径是否正确且存在,检查<target dev='...'>
字母是否冲突,查看/var/log/libvirt/qemu/<vm-name>.log
中的详细错误信息,尝试移除<address>
行让 libvirt 自动分配。 - 虚拟机内看不到磁盘:
- 确认虚拟机是否支持 VirtIO(Linux 一般支持,Windows 需安装驱动)。
- 在虚拟机 XML 配置中检查
<target bus='...'>
设置是否正确(VirtIO/SATA/SCSI)。 - 检查虚拟机操作系统日志(Linux 的
dmesg | grep virtio
,Windows 的设备管理器)。 - 确认硬盘在宿主机上确实没有被挂载 (
lsblk
)。
- 性能不佳: 检查 XML 中的
<driver>
设置,确保cache='none'
和io='native'
,在虚拟机内使用fio
等工具进行基准测试,确认虚拟机有足够的 CPU 资源处理 I/O。 - 权限问题: 确保
qemu
用户(通常是libvirt-qemu
)有权限读取/dev/disk/by-id/...
文件,可能需要调整udev
规则或文件权限:ls -l /dev/disk/by-id/ata-... # 检查权限 sudo chown root:libvirt /dev/sdX # 临时更改设备所属组 (替换 /dev/sdX) sudo chmod 660 /dev/sdX
更持久的解决方案是创建
udev
规则(高级操作)。
关键注意事项(E-A-T 原则核心体现):
- 数据安全第一: 这是最重要的 E-A-T(专业性和可信度)体现。反复强调:操作前备份!仔细核对设备标识符! 错误的设备路径可能导致宿主机系统盘或重要数据盘被覆盖销毁,仅当完全理解风险并做好备份后才操作。
- 持久化标识符: 使用
/dev/disk/by-id/
或/dev/disk/by-path/
是专业实践,避免了设备名变化带来的配置失效问题,体现了操作的专业性(Expertise)。 - 性能调优: 正确设置
<driver>
参数 (cache='none'
,io='native'
,bus='virtio'
) 展示了深入优化的知识(Expertise)。 - 独占访问原则: 强调硬盘直通后不可被宿主机同时读写,这是避免数据损坏的关键规则(Trustworthiness)。
- 适用场景明确: 清晰地说明直通的优势和适用场景(如高性能数据库、视频编辑),帮助用户判断是否真正需要此技术(Trustworthiness)。
- 驱动兼容性: 明确指出 Windows 虚拟机需要 VirtIO 驱动,并指导获取途径,体现了方案的完整性(Trustworthiness)。
- 权限与日志: 提及潜在的权限问题和日志查看方法,提供了解决问题的路径(Expertise, Trustworthiness)。
- 替代方案: 如果用户追求灵活性而非极致性能,可以提及使用 LVM 卷或 ZFS 数据集作为虚拟磁盘后端也是不错的选择。
将物理硬盘直通给 KVM 虚拟机是一种强大的技术,能为特定工作负载带来显著的性能优势,它需要管理员具备清晰的硬件知识和谨慎的操作态度,尤其是对数据安全风险有充分认知,严格遵循上述步骤,特别是使用持久化设备标识符和性能优化参数,并始终牢记备份为先的原则,你就能安全有效地利用这项技术提升虚拟机的存储性能,如果你不确定操作细节或潜在风险,建议先在测试环境中练习。
引用与参考说明:
- libvirt 文档 – 存储管理 (
<disk>
元素): https://libvirt.org/formatdomain.html#hard-drives-floppy-disks-cdroms (权威来源) - QEMU 文档 – 设备模拟: https://www.qemu.org/docs/master/system/devices/ (权威来源)
- Linux
udev
文档 (关于持久化命名): 通常包含在发行版udev
包中或查阅在线手册 (man udev
). (权威来源) - Linux Kernel 文档 – Block Layer: https://www.kernel.org/doc/html/latest/block/index.html (权威来源)
- Windows VirtIO 驱动下载: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/ (可信来源)
(本文综合了开源虚拟化社区的最佳实践和官方文档指南。)
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/33883.html