Manjaro部署kvm虚拟机
Manjaro部署kvm虚拟机
检测是否支持kvm
CPU是否支持虚拟化
kvm需要宿主机cpu支持虚拟化(inter cpu的VT-x
技术、AMD cpu的AMD-v
技术)
grep -E "(vmx|svm)" --color=always /proc/cpuinfo
如果输出中有vmx
或者svm
就说明支持虚拟化;如果没有任何的输出,说明未开启CPU虚拟化(需到BIOS中开启,不同品牌的开启方式都有所不同,网上都会有教程)或CPU不支持虚拟化(无缘虚拟机)
内核是否支持
- KVM模块
zgrep KVM /proc/config.gz
模块设定是y或m,则该模块可用
- VirtIO模块
zgrep VIRTIO /proc/config.gz
准/半虚拟化是在全虚拟化的基础上,把客户操作系统进行了修改,增加了一个专门的API,这个API可以将客户操作系统发出的指令进行最优化。
KVM提供Virtio作为hypervisor和来宾之间的一层API。所有的Virtio有两部分组成:主机设备和客户驱动程序
模块设定是y或m,则该模块可用
- 内核模块是否装载
lsmod | grep kvm
lsmod | grep virtio
若没有返回任何信息,说明没有装载,需要自行装载,控制内核模块装载、卸载的命令由kmod
软件包提供
- 手动装/卸载
sudo modprobe virtio # 装载内核模块virtio
sudo modprobe -r / rmmod virtio #卸载内核模块virtio
- 开机装载
开机时systemd 读取 /etc/modules-load.d/ 中的配置加载额外的内核模块。配置文件名称通常为/etc/modules-load.d/ <-program-> .conf
,配置内容为:一行一个要读取的模块名,而空行以及第一个非空格字符为#或;的行会被忽略
sudo vim /etc/modules-load.d/virtio-mod.conf
添加需要的配置
# Load virtio-net.ko at boot
virtio #所有virtio设备
#virtio-net #网络设备
#virtio-blk #块设备
#virtio-scsi #控制器设备
#virtio-serial #串行设备
- virtio 驱动安装
- 下载页面--->
Direct downloads
--->Stable(稳定版)
- 下载页面--->
将镜像挂载到虚拟机对未识别设备进行驱动安装即可
安装
KVM在系统内核中,无需安装
安装qemu
Qemu是一个广泛使用的开源计算机仿真器和虚拟机,当作为仿真器时,可以在一种架构(如PC机)下运行另一种架构(如ARM)下的操作系统和程序。通过动态转化,可以获得很高的运行效率。当 QEME 作为虚拟机时,可以使用 xen 或 kvm 访问 CPU 的扩展功能(HVM),在主机 CPU 上直接执行虚拟客户端的代码,获得接近于真机的性能表现。
sudo pacman -S qemu
安装libvirt
libvirt是Linux上实现虚拟化功能的库,是长期稳定的C语言API,支持KVM/QEMU、Xen、LXC等主流虚拟化方案
sudo pacman -S libvirt virt-manager #virt-manager为图形前端
安装网络组件
sudo pacman -S ebtables dnsmasq bridge-utils openbsd-netcat
-
ebtables 桥接网络管理,用于 default NAT 网络
-
dnsmasq DHCP DNS 服务,用于 default NAT 网络
-
bridge-utils 桥接网络管理,用于桥接网络
-
openbsd-netcat 用于通过 SSH 管理
其他可选包
- qemu-arch-extra 其它架构支持
- qemu-block-gluster glusterfs block 支持
- qemu-block-iscsi iSCSI block 支持
- qemu-block-rbd RBD block 支持
- samba - SMB/CIFS 服务器支持
配置
启动守护进程
sudo systemctl start libvirtd #启动libvirtd进程
sudo systemctl enable libvirtd #开机自起
启动 default NAT网络
sudo virsh net-start default
#出现错误可列出网络检查
sudo virsh net-list --all
#若没有任何网络,可手动定义网络;或有网络但ifconfig中没有,且启动错误也可手动添加
sudo virsh net-define /etc/libvirt/qemu/networks/default.xml
#标记为自动启动
sudo virsh net-autostart default
将用户添加到kvm用户组
systemctl start libvirtd #启动libvirtd进程
systemctl enable libvirtd #开机自起
将用户添加到kvm用户组
sudo usermod -a -G kvm user_name
安装UEFI功能
安装UEFI固件
sudo pacman -S ovmf
配置
配置libvirtd
启用UEFI
,libvirt
需要知道UEFI
—>NVRAM
中的配置文件映射
sudo vim /etc/libvirt/qemu.conf
找到nvram = [ ]
去掉注释,默认的配置文件中NVRAM配置的是ovmf_code.fd
文件的路径
查看/usr/share/ovmf/x64/
目录下的内容对其进行配置
nvram = [
"/usr/share/ovmf/x64/OVMF_CODE.fd:/usr/share/ovmf/x64/OVMF_CODE.fd",
]
重启libvirtd
sudo systemctl restart libvirtd
显卡直通 (未成功,待研究)
可能踩坑:安装了显卡闭源驱动
通过OVMF实现PCI直通
启用IOMMU
sudo vim /etc/default/grub
#修改GRUB_CMDLINE_LINUX=""
#Intel CPU(VT-d),使用 intel_iommu=on。
#AMD CPU(AMD-Vi),使用 amd_iommu=on
#iommu=pt 防止Linux试图接触(touching)无法直通的设备
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"
#更新grub文件
sudo update-grub
重启后检查dmesg 以确认 IOMMU 已经被正确启用
dmesg | grep -e DMAR -e IOMMU
确保PCI设备被分配到IOMMU组中
创建脚本执行输出PCI 设备是如何被分配到 IOMMU 组之中的,如果没有任何输出,代表没有启用IOMMU支持或你的硬件不支持IOMMU
#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done;
隔离GPU
Linux 4.1 开始,内核包括了 vfio-pci
。这是一个 VFIO 驱动程序,与 pci-stub
的作用相同。但它可以在一定程度上控制设备,例如在不使用设备的时候将它们切换到 D3 状态
modinfo vfio-pci
查看显卡信息
./iommu.sh|grep NVIDIA
IOMMU Group 11 01:00.0 3D controller [0302]: NVIDIA Corporation GM108M [GeForce 940MX] [10de:134d] (rev a2)
#ID: 10de:134d
#01:00.0
cat /sys/bus/pci/devices/0000:01:00.0/modalias
#pci:v000010DEd0000134Dsv00001025sd00001133bc03sc02i00
加载vfio-pci
并将ID参数传递给内核,如果有与该显卡同组(IOMMU Group 11)的设备也要将ID加进去
可通过命令:find /sys/kernel/iommu_groups/ -type l
查询同组设备
sudo vim /etc/modprobe.d/vfio.conf
#加入内容,多个ID用 , 分隔
alias pci:v000010DEd0000134Dsv00001025sd00001133bc03sc02i00 vfio-pci
options vfio-pci ids=10de:134d
保证vfio-pci
在其他图形驱动之前加载,在initramfs中静态绑定它和它的依赖项。按照vfio_pci
,vfio
,vfio_iommu_type1
,vfio_virqfd
的顺序添加到mkinitcpio。
确保modconf hook
在mkinitcpio.conf
的 HOOKS 列表中
sudo vim /etc/mkinitcpio.conf
#找到MODULES修改相关参数顺序
MODULES=(... vfio_pci vfio vfio_iommu_type1 vfio_virqfd ...)
#找到HOOKS确保有参数modconf
HOOKS=(... modconf ...)
重新生成initramfs
生成initramfs
映像/etc/mkinitcpio.conf
并将其保存/boot/linux-custom.img
sudo mkinitcpio -c /etc/mkinitcpio.conf -g /boot/linux-custom.img -k 4.19.69-1-MANJARO
如果修改了/etc/modprobe.d/vfio.conf
中的设备ID,就需要重新生成initramfs
重启验证vfio-pci
是否已经正确加载并绑定到正确的设备
dmesg | grep -i vfio
#有设备且为ffffffff:ffffffff
#vfio_pci: add [10de:134d[ffffffff:ffffffff]] class 0x000000/00000000
vfio.conf
中所绑定的设备(甚至是需要直通的设备)并不一定会出现在 dmesg 的输出之中。有时尽管设备没有出现在 dmesg 的输出中,但实际上在虚拟机中可以被使用
lspci -nnk -d 10de:134d
填坑:解除vfio
绑定:还原修改,从新生成initramfs
(sudo mkinitcpio -g /boot/initramfs-linux-lily.img -k 4.19.69-1-MANJARO
)
使用虚拟机
图形化方式使用
virt-manager
命令方式
创建磁盘镜像
qemu-img create -f qcow2 test.qcow2 40G # 动态大小
qemu-img create -f raw test.raw 40G # 直接分配大小
创建虚拟机
vir-install \
--name win \
--ram 1024 \
--vcpu 2 \
-f test.qcow2 \
--cdrom win.iso \
--network bridge=cloudbr0 \
--graphics vnc,listen=0.0.0.0,port=5959,password='123456',keymap='en-us' \
--force --autostart
--name 虚拟机名
--ram 内存
--vcpu CPU数
--f 磁盘镜像
--cdrom 安装镜像
--network 网路
--graphics 连接方式