《KVM Virtualization Cookbook》第1篇-QEMU

1、说明

本系列文章中使用的系统环境是Ubuntu 18.04.5 LTS
qemu版本为5.2.0
原手册中的环境太旧了,已经不太适用于目前最新的软件了,但是其学习路径和思想是可行的

2、源码安装qemu

有时候直接yum安装是可以,但是基本都是旧版本,可能纯在一些未知bug,选择源码安装最新版本
安装依赖

sudo apt-get -y install build-essential pkg-config \
libglib2.0-0 libglib2.0-dev \
libsdl1.2-dev \
libpixman-1-dev libfdt-dev \
autoconf automake libtool \
librbd-dev \ 
libaio-dev \
flex bison 

在进行安装前使用命令查看是否已开启cpu虚拟化支持
egrep '^flags.*(vmx|svm)' /proc/cpuinfo
返回

flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl tsc_reliable nonstop_tsc cpuid pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 x2apic popcnt aes xsave avx f16c hypervisor lahf_lm svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw xop fma4 tbm ssbd vmmcall bmi1 arat npt svm_lock nrip_save vmcb_clean flushbyasid decodeassists overflow_recov succor

这表示已开启cpu虚拟化,如果不返回任何东西,表示需要开启cpu虚拟化,本文是使用workstation虚拟化的虚拟机安装的ubuntu,可以在虚拟机设置里cpu选项找到相关开启虚拟化设置,如果是物理服务器进bios设置

下载qemu源码包
sudo wget https://download.qemu.org/qemu-5.2.0.tar.bz2

在进行安装前需要安装ninja

sudo apt-get -y install re2c   
sudo git clone git://github.com/ninja-build/ninja.git && cd ninja
./configure.py --bootstrap
cp ninja /usr/bin/

遇到报错安装相关包即可

检查ninja
ninja --version

安装qemu
cat make.sh

cd /usr/local/src   \
if [ $(uname -m) = i686 ]; then
   QEMU_ARCH=i386-softmmu
else
   QEMU_ARCH=x86_64-softmmu
fi
sudo tar Jvxf qemu-5.2.0.tar.bz2
sudo cd qemu-5.2.0/build   
sudo ../configure --target-list=${QEMU_ARCH}  
make

编译完成后,不要直接使用make install,这样会把包安装到很多个地方,这样不利于管理,可以使用开源包管理工具checkinstall
该工具除了能实现make install以外,还能将源码包打包成dpkg包(centos就是rpm包),这样就非常方便管理,同时也有很好的可移植性
sudo apt-get -y install checkinstall
sudo checkinstall make install

检查qemu安装情况
qemu-x86_64 --version
返回
qemu-x86_64 version 5.2.0 Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

3、创建空磁盘空间

qemu-img -h | grep Supported 
qemu-img create -f raw debian.img 10G   
ls -lah debian.img
file -s debian.img   
qemu-img info debian.img   

上面第一行是用来查看宿主机系统支持哪些可以运行虚拟机的镜像空间,该空间用来存储客户机文件系统
第二行就是创建了大小为10g的镜像空间,格式为raw
这里看一下支持的磁盘镜像格式有哪些
qemu-img -h | grep Supported
返回

Supported formats: blkdebug blklogwrites blkverify bochs cloop compress copy-on-read dmg file host_cdrom host_device luks nbd null-aio null-co nvme qcow qcow2 qed quorum raw rbd replication throttle vdi vhdx vmdk vpc vvfat

raw : 默认格式
qcow2 : 支持虚拟机快照、压缩、加密
qcow : 旧版本的格式
dmg : 一般不用于运行虚拟机,用于分布式软件
nbd : 网络模块,用来访问远端存储
vdi : virtualbox用到它,当然它也可以在多种cpu架构上运行虚拟机
vmdk : vmware的虚拟化磁盘镜像格式
vhdx : Micosoft Hyper-V的虚拟化磁盘镜像格式

作为学习,主要学习raw和qcow2这两种

4、创建分区并格式化成文件系统

在创建分区和文件系统时根据虚拟机要运行的服务来确定使用什么类型的文件系统,比如进行高密集计算的推荐使用XFS,这里使用更为常见的Ext4

在创建文件系统时需要宿主机已安装以下几个工具
qemu-nbd
sfdisk/fdisk
mkfs
nbd kernel module

载入nbd module
modeprobe nbd

将创建的空镜像文件debian.img与块设备/dev/nbd0链接
qemu-nbd --format=raw --connect=/dev/nbd0 debian.img

在块设备上创建两个分区

sfdisk /dev/nbd0 << EOF
,1024,82
;
EOF

返回

Checking that no-one is using this disk right now ... OK

Disk /dev/nbd0: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

>>> Created a new DOS disklabel with disk identifier 0x14da439a.
/dev/nbd0p1: Created a new partition 1 of type 'Linux swap / Solaris' and of size 512 KiB.
/dev/nbd0p2: Created a new partition 2 of type 'Linux' and of size 10 GiB.
/dev/nbd0p3: Done.

New situation:
Disklabel type: dos
Disk identifier: 0x14da439a

Device      Boot Start      End  Sectors  Size Id Type
/dev/nbd0p1       2048     3071     1024  512K 82 Linux swap / Solaris
/dev/nbd0p2       4096 20971519 20967424   10G 83 Linux

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

查看分区
ls -lah /dev/nbd0*
返回

brw-rw---- 1 root disk 43, 0 Dec 23 16:52 /dev/nbd0
brw-rw---- 1 root disk 43, 1 Dec 23 16:52 /dev/nbd0p1
brw-rw---- 1 root disk 43, 2 Dec 23 16:52 /dev/nbd0p2

创建swap与根分区
mkswap /dev/nbd0p1
返回

Setting up swapspace version 1, size = 508 KiB (520192 bytes)
no label, UUID=863b6f0c-c0ed-4f09-9aef-9c7b4e0f80c2

创建根分区
mkfs.ext4 /dev/nbd0p2
返回

mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done                            
Creating filesystem with 2620928 4k blocks and 655360 inodes
Filesystem UUID: 7963d37d-ebbd-48e3-9440-9bafe6ba8761
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

工作原理
利用nbd内核模块将创建的磁盘镜像文件与块设备关联,可以使用以下方式具体查看nbd内核模块信息, modinfo nbd
返回

filename:       /lib/modules/4.15.0-112-generic/kernel/drivers/block/nbd.ko
license:        GPL
description:    Network Block Device
srcversion:     5944A508AF7E86590D58BAE
depends:        
retpoline:      Y
intree:         Y
name:           nbd
vermagic:       4.15.0-112-generic SMP mod_unload 
signat:         PKCS#7
signer:         
sig_key:        
sig_hashalgo:   md4
parm:           nbds_max:number of network block devices to initialize (default: 16) (int)
parm:           max_part:number of partitions per device (default: 16) (int)
file -s /dev/nbd0   
file -s debian.img   

返回

/dev/nbd0: DOS/MBR boot sector; partition 1 : ID=0x82, start-CHS (0x0,32,33), end-CHS (0x0,48,48), startsector 2048, 1024 sectors; partition 2 : ID=0x83, start-CHS (0x0,65,2), end-CHS (0x119,106,17), startsector 4096, 20967424 sectors

这样就创建了一个可以用来安装客户机操作系统的镜像文件,该镜像文件包括swap分区和根分区

5、客户机安装

需要以下三个条件
前面创建的块设备
ls -la /dev/nbd0*
debootstrap工具
chroot

apt-get install -y debootstrap
mount /dev/nbd0p2 /mnt/
查看挂载情况
mount | grep mnt
从镜像仓库安装客户机操作系统,这里安装一个debian
debootstrap --arch=amd64 --include="openssh-server vim" stable /mnt/ http://ftp.cn.debian.org/debian
返回
Base system installed successfully表示安装完成
挂载目录查看安装的文件系统文件
cd /mnt
ls -la ./*

绑定并挂载宿主机设备目录文件到文件系统
mount --bind /dev/ /mnt/dev

查看nbd设备是否已经在文件系统里
ls -la /mnt/dev | grep nbd0

进入镜像根分区挂载的文件系统(chroot环境)
chroot /mnt

chroot环境中查看系统版本
cat /etc/debian_version

chroot环境中挂载proc和sysfs
mount -t proc none /proc
mount -t sysfs none /sys

chroot环境中安装debian内核包和grub2
apt-get install -y --force-yes linux-image-amd64 grub2
返回这个画面,不要选任何设备,点OK继续
121

chroot环境执行以下命令
grub-install /dev/nbd0 --force
update-grub2

chroot环境修改客户机root密码
passwd

chroot环境执行
echo "pts/0" >> /etc/securetty
systemctl set-default multi-user.target
echo "/dev/sda2 / ext4 defaults,discard 0 0" > /etc/fstab
umount /proc/ /sys/ /dev/

exit退出chroot环境

根分区上安装grub
grub-install /dev/nbd0 --root-directory=/mnt --modules="biosdisk part_msdos" --force

更新grub以此来为客户机重载配置
sed -i 's/nbd0p2/sda2/g' /mnt/boot/grub/grub.cfg
注意:这里之所以是/dev/sda2是因为当我们将raw image与宿主机块设备关联是会出现/dev/nbd0p2,而我们创建的内部镜像的第二个分区默认是sda2

至此客户机就安装好了,如果想要解除挂载并移除镜像文件与块设备的关联,请依次使用以下两条命令

umount /mnt
qemu-nbd --disconnect /dev/nbd0