4090 8卡裸金属虚拟8个单卡方案

Ubuntu 24.04 + KVM/QEMU + Libvirt + GPU Passthrough


KVM/QEMU:Linux 原生虚拟化引擎,性能接近裸机

libvirt + virt-manager:管理虚拟机

VFIO PCI Passthrough:实现每个 VM 独占 1 张 4090 显卡

🧱 宿主机前提条件检查(Ubuntu 24.04)
	1.	CPU 支持虚拟化 + IOMMU
lscpu | grep Virtualization

	2.	开启 IOMMU(AMD-Vi)

编辑 /etc/default/grub:  GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"
sudo update-grub
sudo reboot

	3.	检查 IOMMU 是否生效
dmesg | grep -i iommu            应包含:AMD-Vi: IOMMU enabled

🧰 安装虚拟化工具(KVM + Libvirt + Virt-Manager)


sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system virt-manager bridge-utils ovmf
sudo systemctl enable libvirtd
sudo systemctl start libvirtd

验证是否支持 KVM:kvm-ok


🧠 查看并绑定 GPU 设备

1. 列出所有 GPU: lspci -nn | grep -i nvidia
输出类似:0b:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD102 [GeForce RTX 4090] [10de:2684]
0b:00.1 Audio device [0403]: NVIDIA Corporation [10de:228b]
记录所有 GPU 的 [10de:2684] [10de:228b]

2. 使用 vfio-pci 绑定设备 根据自己的修改

编辑 /etc/modprobe.d/vfio.conf:options vfio-pci ids=10de:2684,10de:228b


禁用宿主机加载 NVIDIA 驱动:echo -e "blacklist nouveau\nblacklist nvidia\nblacklist nvidiafb\nblacklist rivafb" | sudo tee /etc/modprobe.d/blacklist-nvidia.conf

更新 initramfs:sudo update-initramfs -u
sudo reboot


🔁 重启后验证设备是否绑定 VFIO:lspci -nnk | grep -A 3 NVIDIA
应该显示:Kernel driver in use: vfio-pci
🧱 创建虚拟机并配置 GPU Passthrough

使用 virt-manager 创建虚拟机(GUI 工具)或命令行:

使用 GUI
	1.	打开:virt-manager

	2.	创建新虚拟机 → 使用 ISO 安装(Ubuntu/CentOS)
	3.	分配:
	•	CPU 核心数(自行配置)
	•	内存(自行配置)
	•	磁盘(独立 qcow2 文件)
	4.	在「添加硬件」中:
	•	添加 GPU PCI 设备(选择你绑定的某一张 4090)


💡 QEMU 配置文件修改(高级)

VM 的配置文件位置:/etc/libvirt/qemu/<vm-name>.xml

在 <devices> 内添加 GPU 显卡 passthrough 设备: 
<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x0b' slot='0x00' function='0x0'/>
  </source>
</hostdev>

如果你也要直通 GPU 的音频子设备,则添加第二块:
<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x0b' slot='0x00' function='0x1'/>
  </source>
</hostdev>


重载并启动虚拟机:
virsh define /etc/libvirt/qemu/<vm-name>.xml
virsh start <vm-name>

🎯 虚拟机内部部署 GPU 驱动 + CUDA
	1.	登录 VM 后安装 NVIDIA 驱动
	2.	确认 GPU 可用:nvidia-smi


如果要每台 VM 独立联网,可用 bridge-utils 配置桥接 vmbr0:
# /etc/netplan/01-netcfg.yaml 示例
network:
  version: 2
  renderer: networkd
  ethernets:
    eno1:
      dhcp4: no
  bridges:
    br0:
      interfaces: [eno1]
      dhcp4: yes

然后用 virsh 或 virt-manager 把虚拟机网络绑定到 br0。
gpu-vm-setup/
├── 00-init-dependencies.sh          # 安装依赖并启用 KVM + VFIO
├── 01-bind-gpus-vfio.sh             # 识别并绑定 8 张 4090 到 vfio-pci
├── 02-create-vm-template.sh         # 创建 base 虚拟机模板(带 GPU 驱动)
├── 03-create-vms.sh                 # 从模板批量创建 8 个 GPU VM
├── ubuntu-22.04.iso                 # 虚拟机系统镜像(或 cloud-init)
└── vm-disk/                         # 每个 VM 的磁盘存储目录
#00-init-dependencies.sh

#!/bin/bash
set -e

echo "[*] 安装 KVM/Libvirt 等虚拟化工具..."
sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system virt-manager bridge-utils ovmf

echo "[*] 启用 IOMMU 支持..."
sudo sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="amd_iommu=on iommu=pt /' /etc/default/grub
sudo update-grub

echo "[*] 加载 VFIO 模块..."
cat <<EOF | sudo tee /etc/modules-load.d/vfio.conf
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
EOF

echo "[*] 黑名单 NVIDIA 驱动..."
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-nvidia.conf
blacklist nouveau
blacklist nvidia
blacklist nvidiafb
blacklist rivafb
EOF

echo "[*] 设置完成,请重启后执行下一步:01-bind-gpus-vfio.sh"
📜 01-bind-gpus-vfio.sh

#!/bin/bash
set -e

echo "[*] 识别所有 RTX 4090 设备..."
lspci -nn | grep -i 'NVIDIA.*4090' > /tmp/gpu.list
DEVICE_IDS=$(lspci -nn | grep -i 'NVIDIA.*4090' | awk -F '[' '{print $3}' | cut -d ']' -f1 | sort -u | paste -sd,)

echo "[*] 绑定 GPU IDs 到 vfio-pci: $DEVICE_IDS"
echo "options vfio-pci ids=$DEVICE_IDS" | sudo tee /etc/modprobe.d/vfio-pci.conf

echo "[*] 更新 initramfs..."
sudo update-initramfs -u

echo "[*] 完成绑定。请重启并验证 lspci 是否显示 vfio-pci 绑定。"
📜 02-create-vm-template.sh

手动安装一台虚拟机(例如 Ubuntu 22.04),安装 NVIDIA 驱动和 CUDA 工具链。然后使用如下命令导出模板:

#!/bin/bash
# 手动安装完成 base-4090-vm 后执行
virsh shutdown base-4090-vm
sleep 10
virsh snapshot-create-as --domain base-4090-vm --name clean --description "Clean base image"
📜 03-create-vms.sh(批量创建)

#!/bin/bash
set -e

VM_PREFIX="gpuvm"
BASE_DISK="/var/lib/libvirt/images/base-4090.qcow2"
BRIDGE_IF="br0"

# GPU PCI地址列表(需提前根据 lspci 获取)
GPU_IDS=(
  "0000:0b:00.0" # GPU 0
  "0000:13:00.0" # GPU 1
  "0000:1b:00.0" # ...
  "0000:23:00.0"
  "0000:2b:00.0"
  "0000:33:00.0"
  "0000:3b:00.0"
  "0000:43:00.0"
)

for i in $(seq 0 7); do
  VM_NAME="${VM_PREFIX}${i}"
  VM_DISK="/var/lib/libvirt/images/${VM_NAME}.qcow2"

  echo "[*] 创建磁盘镜像: $VM_DISK"
  cp "$BASE_DISK" "$VM_DISK"

  echo "[*] 定义虚拟机: $VM_NAME"
  virt-install \
    --name "$VM_NAME" \
    --ram 65536 \
    --vcpus 12 \
    --cpu host \
    --os-variant ubuntu22.04 \
    --hvm \
    --virt-type kvm \
    --graphics none \
    --disk path="$VM_DISK",format=qcow2 \
    --network bridge=$BRIDGE_IF,model=virtio \
    --import \
    --noautoconsole \
    --boot uefi \
    --host-device ${GPU_IDS[$i]}
done

发表评论