拾遗:Qemu/KVM
WinXP:
#!/bin/bash name=winxp qemu-system-x86_64 \ -enable-kvm \ -cpu host -smp 2,sockets=2,cores=1,threads=1 \ -m 4096 \ -net user \ -drive file=./WinXP.img,if=none,cache=writeback,id=${name}_disk -device ide-hd,drive=${name}_disk \ -drive file=./WinXP.iso,readonly=on,media=cdrom \ -boot order=cd \ -name ${name} \ -display gtk
一、管理 images
1、创建
qemu-img create -f raw -o size=10G,nocow=on base.raw #nocow 用于关闭 btrfs 的写时复制,仅对新创建的文件生效
2、扩容
qemu-img resize base.raw +20G
3、查询信息
qemu-img info base.raw
4、转换格式
qemu-img convert -c -O qcow2 base.raw base.qcow2
5、增量创建
qemu-img create -f qcow2 -o size=20G,nocow=on,backing_file=base.qcow2 linux.qcow2 #批量运行时减少磁盘占用
6、重改基础镜像
qemu-img rebase [-u] -b /PATH/TO/xxx.qcow2 linux.qcow2 # -u 指 unsafe 模式,无需检验,通常用于基础镜像移动位置或重命名之后
二、管理 snapshot
1、创建
qemu-img snapshot -c v0.1_snapshot linux.qcow2
2、查询
qemu-img snapshot -l linux.qcow2
3、应用
qemu-img snapshot -a v0.1_snapshot linux.qcow2
4、删除
qemu-img snapshot -d v0.1_snapshot linux.qcow2
三、热拔插
# 首先需要客户机载入:modprobe pci_hotplug
# 然后在 monitor 中操作
drive_add 0 media=disk,file=/PATH/TO/xxx.qcow2,if=none,id=vd0 #添加到 Qemu
device_add virtio-blk-pci,drive=vd0 #插入到客户机
drive_del tmp_0 #移除
四、Gentoo
/etc/portage/package.use/qemu:
vhost-net -nls -iscsi -nfs -opengl -jpeg -png -usb -usbredir -curl -selinux -spice -ncurses -sdl -gtk -xen -alsa -bluetooth
五、示例
init.sh:
1 #!/usr/bin/env sh 2 # 3 # 0、目录结构:conf、images、ISOs 4 # 1、安装镜像存放于"../ISOs"路径下,命名格式:FreeBSD.iso 5 # 2、配置好每个OS的基础镜像,置于"../images"路径下,命名格式:FreeBSD_base.img 6 # 7 8 if [[ $1 == '' ]];then 9 VmNum=1 10 printf "\033[31;01m\$VmNum is not specified, defaults to 1\n\033[00m" 11 elif [[ $1 =~ [0-9] ]];then 12 VmNum=$1 13 else 14 printf "\033[31;01m\$1 is not a number!!!\n\033[00m" 15 exit 16 fi 17 18 if [[ $2 == '' ]];then 19 OS=Gentoo 20 printf "\033[31;01mOS is not specified, defaults to \"Gentoo\"\n\033[00m" 21 else 22 OS=$2 23 fi 24 25 ISO=${OS}.iso 26 BaseImg=${OS}_base.img 27 CpuNum=4 28 Mem=4G 29 MaxMem=8G 30 DiskSiz=200G 31 MaxVmNum=10 32 HostIP=192.168.0.254 33 34 if [[ $1 -gt $MaxVmNum ]];then 35 printf "\033[31;01mvmNum > ${MaxVmNum}!!!\n\033[00m" 36 exit 37 fi 38 39 case $OS in 40 FreeBSD) 41 Version=11 42 AddrPos=50 43 ;; 44 Gentoo) 45 Version=13 46 AddrPos=40 47 ;; 48 RHEL) 49 Version=07 50 AddrPos=30 51 ;; 52 Debian) 53 Version=08 54 AddrPos=20 55 ;; 56 Ubuntu) 57 Version=17 58 AddrPos=10 59 ;; 60 *) 61 printf "\033[31;01mUnknown OS name!!!\n\033[00m" 62 printf "Supported OS name:FreeBSD Gentoo RHEL Debian Ubuntu\n" 63 exit 64 ;; 65 esac 66 67 vmFunc() { 68 qemu-system-x86_64 \ 69 -enable-kvm \ 70 -machine q35,accel=kvm -device intel-iommu \ 71 -cpu host -smp $CpuNum,sockets=$CpuNum,cores=1,threads=1 \ 72 -m $Mem,slots=4,maxmem=$MaxMem \ 73 -netdev tap,ifname=${OS}_$1,script=tap.sh,downscript=no,id=vmNic_${OS}_$1 -device virtio-net-pci,mac=52:54:00:11:$1:${Version},netdev=vmNic_${OS}_$1 \ 74 -drive file=../images/$ImgName,if=none,cache=writeback,media=disk,id=vmDisk_${OS}_$1 -device virtio-blk-pci,drive=vmDisk_${OS}_$1 \ 75 -drive file=../ISOs/$ISO,readonly=on,media=cdrom \ 76 -boot order=cd \ 77 -name vm${OS}_$1 \ 78 -monitor tcp:$HostIP:$(($1 * 1000)),server,nowait \ 79 -vnc :$1 \ 80 -daemonize 81 } 82 83 OpsFunc() { 84 eval x=$(($1 + $AddrPos)) 85 local ImgName=${OS}_$x.img 86 87 if [[ 0 -eq $(ls ../images | grep -c $ImgName) ]];then 88 qemu-img create -f qcow2 -o size=$DiskSiz,nocow=on,backing_file=../images/$BaseImg ../images/$ImgName 89 if [[ 0 -ne $? ]];then 90 printf "\033[31;01mCan't create $ImgName!!!\n\033[00m" 91 exit 92 fi 93 fi 94 95 vmFunc $x 96 } 97 98 i=0 99 while [[ $i -lt $VmNum ]] 100 do 101 OpsFunc $i 102 let i+=1 103 done
...
/*基于硬件IOMMU支持的硬件直接分配技术:VFIO*/ #modprobe vfio-pci #echo 8086 8c20 > /sys/bus/pci/drivers/vfio-pci/new_id #echo 0000:00:1b.0 > /sys/bus/pci/devices/0000:00:1b.0/driver/unbind #echo 0000:00:1b.0 > /sys/bus/pci/drivers/vfio-pci/bind /*Qemu设置直连物理网卡示例*/ #-device vfio-pci,host=00:1b.0 #-net none
net.sh:
#!/usr/bin/env sh modprobe tun modprobe vhost modprobe vhost_net modprobe bonding IF_0=enp2s0 IF_1=eno1 BD=bond0 SW=br0 ADDR=192.168.0.254/24 ROUTE=192.168.0.1 ip link del $BD #echo -$BD > /sys/class/net/bonding_masters if [[ 0 -eq $(ip link | grep -c $SW) ]];then ip link add $SW type bridge fi ip link add $BD type bond #echo +$BD > /sys/class/net/bonding_masters for x in $IF_0 $IF_1 $BD $SW do ip addr flush dev $x ip route flush dev $x done ip link set $IF_0 down ip link set $IF_1 down ip link set $BD down echo active-backup > /sys/class/net/$BD/bonding/mode #balance-rr/active-backup/broadcast echo 1000 > /sys/class/net/bond0/bonding/miimon echo +$IF_0 > /sys/class/net/$BD/bonding/slaves echo +$IF_1 > /sys/class/net/$BD/bonding/slaves ip link set $IF_0 up ip link set $IF_1 up ip link set $BD up #ip link set $IF_0 promisc on #ip link set $IF_1 promisc on #ip link set $BD promisc on ip link set $BD master $SW ip addr add $ADDR dev $SW ip link set $SW up ip route replace default via $ROUTE dev $SW printf "\033[31;01mSlaves of $BD:\033[00m\n" cat /sys/class/net/$BD/bonding/slaves #printf "\n\033[31;01m$BD info:\033[00m\n" #cat /proc/net/bonding/$BD
tap.sh
开头必须加 #!/usr/bin/env bash 一行
#!/usr/bin/env bash
ip link set $1 up sleep 0.1s ip link set $1 master br0