前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >KVM虚拟化之设备透传

KVM虚拟化之设备透传

作者头像
没有故事的陈师傅
发布2024-12-27 17:20:02
发布2024-12-27 17:20:02
8800
代码可运行
举报
文章被收录于专栏:运维开发故事
运行总次数:0
代码可运行

显卡透传

查看显卡PCI地址

代码语言:javascript
代码运行次数:0
复制
lspci | grep -i nvidia

会看到类似下面的输出,其中包含显卡的 PCI 地址,例如 0000:03:00.0:

代码语言:javascript
代码运行次数:0
复制
03:00.0 VGA compatible controller: NVIDIA Corporation Device 1eb8 (rev a1)
03:00.1 Audio device: NVIDIA Corporation Device 10f7 (rev a1)

确认 IOMMU 支持

确保主机启用了 IOMMU 支持。在 GRUB 配置中添加以下参数:

  • 对于 Intel CPU,在 /etc/default/grub 文件中的 GRUB_CMDLINE_LINUX 添加 intel_iommu=on:
代码语言:javascript
代码运行次数:0
复制
GRUB_CMDLINE_LINUX="... intel_iommu=on"
  • 对于 AMD CPU,添加 amd_iommu=on:
代码语言:javascript
代码运行次数:0
复制
GRUB_CMDLINE_LINUX="... amd_iommu=on"

然后更新 GRUB 配置:

代码语言:javascript
代码运行次数:0
复制
update-grub

确认 IOMMU 组

确认显卡在单独的 IOMMU 组中:

代码语言:javascript
代码运行次数:0
复制
dmesg | grep -e DMAR -e IOMMU

这里有一个脚本可以查看

代码语言:javascript
代码运行次数:0
复制
#!/bin/bash
for d in /sys/kernel/iommu_groups/*; do
    if [ -d "$d" ]; then
        echo "IOMMU Group ${d##*/}:"
        for f in $(ls $d/devices/); do
            echo -e "\t$(lspci -nns $f)"
        done;
    fi;
done;

绑定设备到 VFIO 驱动

查找设备 ID

使用 lspci -nn | grep -i nvidia找到显卡设备 ID,例如 10de:1eb8 和 10de:10f7。

创建 VFIO 配置文件

在 /etc/modprobe.d/vfio.conf 文件中添加以下内容,将设备 ID 替换为找到的设备 ID:

代码语言:javascript
代码运行次数:0
复制
options vfio-pci ids=10de:1eb8,10de:10f7

更新 initramfs 并重启系统

更新 initramfs 以应用新的 VFIO 配置,并重启系统:

代码语言:javascript
代码运行次数:0
复制
update-initramfs -u
reboot

编辑虚拟机xml文件

在部分添加显卡设备配置,使用上面找到的 PCI 地址:

通常情况下,显卡的audio可以不用透传,只需要添加一个hostdev的块就可以了

代码语言:javascript
代码运行次数:0
复制
<devices>
  ...
  <hostdev mode='subsystem' type='pci' managed='yes'>
    <source>
      <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </source>
    <rom bar='off'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
  </hostdev>
  <hostdev mode='subsystem' type='pci' managed='yes'>
    <source>
      <address domain='0x0000' bus='0x03' slot='0x00' function='0x1'/>
    </source>
    <rom bar='off'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
  </hostdev>
  ...
</devices>

之后启动虚拟机

网卡透传

检查宿主机是否支持 IOMMU

要进行网卡透传,宿主机需要支持 IOMMU,并且BIOS中要开启Intel vt-d

代码语言:javascript
代码运行次数:0
复制
grep -E "svm|vmx" /proc/cpuinfo
  • AMD CPU 支持 svm
  • Intel CPU 支持 vmx

启用 IOMMU

在宿主机中启用 IOMMU 功能:

修改 GRUB 配置:

编辑 /etc/default/grub 文件:

GRUB_CMDLINE_LINUX 中添加以下参数:

  • 对于 Intel CPU:
代码语言:javascript
代码运行次数:0
复制
intel_iommu=on iommu=pt
  • 对于 AMD CPU:
代码语言:javascript
代码运行次数:0
复制
amd_iommu=on iommu=pt

更新 GRUB 并重启:

代码语言:javascript
代码运行次数:0
复制
sudo update-grub
sudo reboot

检查 IOMMU 是否启用

在宿主机重启后,运行以下命令确认 IOMMU 是否启用:

代码语言:javascript
代码运行次数:0
复制
dmesg | grep -e DMAR -e IOMMU

如果输出中显示类似 IOMMU enabled,说明配置正确。

获取网卡的 PCI ID

使用以下命令找到要透传的网卡设备:

代码语言:javascript
代码运行次数:0
复制
lspci -nn | grep -i network

示例输出:

代码语言:javascript
代码运行次数:0
复制
03:00.0 Ethernet controller [0200]: Intel Corporation Ethernet Controller X710 [8086:1572]
  • 03:00.0 是网卡的 PCI 地址。
  • [8086:1572] 是设备的厂商和设备 ID。

将网卡分配给虚拟机

libvirt 的虚拟机配置文件(XML)中,添加透传的网卡:

获取网卡的 PCI 地址:

代码语言:javascript
代码运行次数:0
复制
lehw -C network -businfo

编辑虚拟机的 XML 配置文件:

代码语言:javascript
代码运行次数:0
复制
virsh edit <VM-NAME>

添加以下内容到 <devices> 节点中:

代码语言:javascript
代码运行次数:0
复制
<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
  </source>
</hostdev>

重启虚拟机:

代码语言:javascript
代码运行次数:0
复制
virsh shutdown <VM-NAME>
virsh start <VM-NAME>

验证网卡透传

在虚拟机中运行以下命令,查看网卡是否被识别:

代码语言:javascript
代码运行次数:0
复制
lspci | grep -i ethernet

USB透传

常要用于透传usb存储设备和加密狗设备给虚拟机

确认宿主机可以识别 USB 设备

查看所有连接的 USB 设备:

代码语言:javascript
代码运行次数:0
复制
lsusb

示例输出:

代码语言:javascript
代码运行次数:0
复制
Bus 002 Device 005: ID 0781:5581 SanDisk Corp. Ultra
Bus 001 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
  • Bus 002 Device 005 表示设备的总线号和设备号。
  • 0781:5581 是厂商和设备 ID。

将 USB 设备分配给虚拟机

使用 virsh 修改虚拟机配置:

编辑虚拟机的 XML 配置:

代码语言:javascript
代码运行次数:0
复制
virsh edit <VM-NAME>

<devices> 节点中添加以下内容:

代码语言:javascript
代码运行次数:0
复制
<hostdev mode='subsystem' type='usb' managed='yes'>
  <source>
    <vendor id='0x0781'/>
    <product id='0x5581'/>
  </source>
</hostdev>

参数说明:

  • vendor id='0x0781':设备的厂商 ID。
  • product id='0x5581':设备的产品 ID。

保存后退出。

重启虚拟机

将 USB 设备透传给虚拟机后,重启虚拟机:

代码语言:javascript
代码运行次数:0
复制
virsh shutdown <VM-NAME>
virsh start <VM-NAME>

在虚拟机中验证设备

登录到虚拟机后,使用以下命令查看 USB 设备是否可用:

代码语言:javascript
代码运行次数:0
复制
lsusb

应该可以看到之前透传的 USB 设备。

USB 设备热插拔配置

在虚拟机运行时,可以使用以下命令将 USB 设备添加到虚拟机或者在虚拟机动态移除:

添加 USB 设备:
代码语言:javascript
代码运行次数:0
复制
virsh attach-device <VM-NAME> --file usb.xml --live

其中 usb.xml 是描述 USB 设备的 XML 配置文件。

动态移除 USB 设备

如果需要从虚拟机中移除 USB 设备,使用以下命令:

代码语言:javascript
代码运行次数:0
复制
virsh detach-device <VM-NAME> --file usb.xml --live
创建 USB 设备 XML:

创建一个名为 usb.xml 的文件,内容如下:

代码语言:javascript
代码运行次数:0
复制
<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x0781'/>
    <product id='0x5581'/>
  </source>
</hostdev>
  • **vendor id**** 和 ****product id**:使用 lsusbvirsh nodedev-dumpxml 提取的厂商和产品 ID。

HBA卡透传到虚拟机

HBA卡用于FC-SAN存储,可能原来服务器使用了FS-SCN存储,当服务器迁移到超融合或者私有云上后,仍希望继续使用FC-SAN存储,可采购HBA卡插到超融合或者私有云服务器上,并将其透传到对应的虚拟机上继续使用

检查宿主机支持 PCI 直通

HBA 卡透传需要宿主机支持 IOMMU 功能。

检查 CPU 是否支持虚拟化和 IOMMU:

代码语言:javascript
代码运行次数:0
复制
grep -E "svm|vmx" /proc/cpuinfo

检查是否启用 IOMMU:

代码语言:javascript
代码运行次数:0
复制
dmesg | grep -e DMAR -e IOMMU

如果未启用,请参考以下步骤配置 IOMMU。


启用 IOMMU

修改 GRUB 配置:

编辑 /etc/default/grub 文件:

代码语言:javascript
代码运行次数:0
复制
vim /etc/default/grub

添加以下参数到 GRUB_CMDLINE_LINUX

  • 对于 Intel CPU:
代码语言:javascript
代码运行次数:0
复制
intel_iommu=on iommu=pt
  • 对于 AMD CPU:
代码语言:javascript
代码运行次数:0
复制
amd_iommu=on iommu=pt

保存文件后更新 GRUB 配置并重启系统:

代码语言:javascript
代码运行次数:0
复制
sudo update-grub
sudo reboot

确认 HBA 卡信息

使用以下命令列出宿主机的所有 PCI 设备:

代码语言:javascript
代码运行次数:0
复制
lspci -nn

找到 HBA 卡对应的设备。例如:

代码语言:javascript
代码运行次数:0
复制
04:00.0 Fibre Channel [0c04]: QLogic Corp. QLE2562 8Gb Fibre Channel Adapter [1077:2532] (rev 02)

记录设备的 PCI 地址,例如 04:00.0

将 HBA 卡分配给虚拟机

编辑虚拟机 XML 配置:

  1. 打开虚拟机的 XML 配置:
代码语言:javascript
代码运行次数:0
复制
virsh edit <VM-NAME>
  1. <devices> 节点中添加以下内容:
代码语言:javascript
代码运行次数:0
复制

<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
  </source>
</hostdev>
  1. 保存并退出。

启动虚拟机并验证

启动虚拟机:

代码语言:javascript
代码运行次数:0
复制
virsh start <VM-NAME>

在虚拟机中验证 HBA 卡:

登录虚拟机后,运行以下命令检查是否识别到 HBA 卡:

代码语言:javascript
代码运行次数:0
复制
lspci -nn | grep Fibre

如果一切正常,虚拟机应该能看到并使用透传的 HBA 卡。

公众号:运维开发故事

github:https://github.com/orgs/sunsharing-note/dashboard

博客:https://www.devopstory.cn

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维开发故事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 显卡透传
    • 查看显卡PCI地址
    • 确认 IOMMU 支持
    • 确认 IOMMU 组
    • 绑定设备到 VFIO 驱动
    • 编辑虚拟机xml文件
  • 网卡透传
    • 检查宿主机是否支持 IOMMU
    • 启用 IOMMU
    • 检查 IOMMU 是否启用
    • 获取网卡的 PCI ID
    • 将网卡分配给虚拟机
    • 验证网卡透传
  • USB透传
    • 确认宿主机可以识别 USB 设备
    • 将 USB 设备分配给虚拟机
    • 重启虚拟机
    • 在虚拟机中验证设备
    • USB 设备热插拔配置
      • 添加 USB 设备:
      • 动态移除 USB 设备
      • 创建 USB 设备 XML:
  • HBA卡透传到虚拟机
    • 检查宿主机支持 PCI 直通
    • 启用 IOMMU
    • 确认 HBA 卡信息
    • 将 HBA 卡分配给虚拟机
    • 启动虚拟机并验证
    • 在虚拟机中验证 HBA 卡:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档