上一篇我们已经介绍了spice 和qemu的安装,在成功安装QEMU之后便可创建自己的虚拟机。具体步骤如下:

1, 使用qemu-img创建虚拟机镜像,虚拟机镜像用来模拟虚拟机的硬盘,在启动虚拟机之前需要创建镜像文件。

[root@localhost IMG]# qemu-img create -f qcow2 ubuntu.img 10G
Formatting 'ubuntu.img', fmt=qcow2 size=8589934592 cluster_size=65536 lazy_refcounts=off refcount_bits=16

说明:

  • -f 选项用于指定镜像的格式,qcow2格式是QEMU最常用的镜像格式,采用写时复制技术来优化性能。ubuntu.img 是镜像文件的名字,10G是镜像文件大小镜像文件创建完成后,可使用qemu-system-x86来启动x86架构的虚拟机:
[root@localhost IMG]# qemu-system-x86_64 -m 2048 -smp 1 -boot order=cd -cdrom ../ISO/ubuntu-16.04.6-desktop-amd64.iso -hda ./ubuntu.img -vnc :1

参数说明:

  • -m 指定客户机内存大小,默认单位MB
    -smp 指定客户机cpu个数。SMP:(symmetric[sɪ’metrɪk] Multi-processing)对称多处理
    -boot 指定客户机系统启动顺序,order=cd是指先光盘再硬盘。c:CD-ROM d:Hard Disk
    -hda 指定客户机的IDE硬盘(即前面的创建的镜像文件)
    -cdrom 指定客户机的光驱
    -vnc 表示启用vnc连接,并指定端口5901(5900+1)

接下来,我们另开一个终端查看端口开启情况:

[root@localhost ~]# netstat -anolp|grep 5901
-bash: netstat: command not found
[root@localhost ~]#

注:如果出现上面情况,请先执行如下命令安装net-tools,yum install net-tools

我们发现5901端口已经开启,如下:

[root@localhost ~]# netstat -anolp|grep 5901
tcp        0      0 0.0.0.0:5901            0.0.0.0:*               LISTEN      9867/qemu-system-x8  off (0.00/0/0)
tcp6       0      0 :::5901                 :::*                    LISTEN      9867/qemu-system-x8  off (0.00/0/0)
[root@localhost ~]#

这时我们先采用VNC客户端去连接(后续会介绍使用spice 方式去连接),如果发现连接不上,如下:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm 源码解析


请查看firewalld 服务是否为开启状态,如下表示开启:

[root@localhost ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-05-15 10:53:11 EDT; 2min 47s ago
     Docs: man:firewalld(1)
 Main PID: 8837 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─8837 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

May 15 10:53:10 localhost.localdomain systemd[1]: Starting firewalld - dynami...
May 15 10:53:11 localhost.localdomain systemd[1]: Started firewalld - dynamic...
Hint: Some lines were ellipsized, use -l to show in full.

将防火墙关闭,如下:

[root@localhost ~]# systemctl stop firewalld   //关闭防火墙
[root@localhost ~]# systemctl disable firewalld  //关闭开机启动

关闭防火墙以后,我们再用VNC客户端连接,发现可以连接成功,如下进入系统安装界面:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm_02

系统安装过程就不介绍了,安装好操作系统以后,启动操作系统时去掉-cdrom,如下:

[root@localhost IMG]# qemu-system-x86_64 -m 2048 -smp 1 -boot order=cd -hda ./ubuntu.img -vnc :1

kvm 源码解析 qemu/kvm源码解析与应用 pdf_spice_03




带来的几个问题

1)那如果我们的应用程序想管理该虚机,即创建、启动、停止、迁移等虚机该怎么办呢? 这些命令使用起来肯定是复杂的,而且这样的命令、参数也是太多。

2)上面的是针对kvm 虚机,那针对其它厂家类型的虚机,如xen、vwware或者lxc 等,我们又怎么办呢?

3)针对上面的问题,我们有简单的、统一的封装接口可以使用吗?答案是有的,就是我们接下来将要介绍的libvrit 了;
了,下面进入编译环节:

  目前,libvirt 已经成为使用最为广泛的对各种虚拟机进行管理的工具和应用程序接口(API),而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和云计算框架平台(如OpenStack、OpenNebula、Eucalyptus等)都在底层使用libvirt的应用程序接口,利用libvirt接口还可以操作远程虚机。这里本文不作深的讲述,本来也不会重点讲述libvirt的API使用,后面会有陆续的文章进行介绍。既然应用这么广泛,我们也从源码的编译到使用来进行介绍;源码的下载路径已经在上一篇给过。

编译libvirt

1、解压并进入目录

[root@localhost zhb]# tar xf libvirt-5.2.0.tar.xz
[root@localhost zhb]# ls
IMG                   qemu-3.1.0            spice-protocol-0.12.15
ISO                   qemu-3.1.0.tar.xz     spice-protocol-0.12.15.tar.bz2
libvirt-5.2.0         spice-0.14.0
libvirt-5.2.0.tar.xz  spice-0.14.0.tar.bz2
[root@localhost zhb]# cd libvirt-5.2.0
[root@localhost libvirt-5.2.0]#

2、执行命令./configure

[root@localhost libvirt-5.2.0]# ./configure --with-driver-modules --with-interface --with-qemu --with-sasl

这其中会发现缺少很多库文件,一一安装即可。我编译的机器是centos 7 64位 最小化安装的机器(虽然前面编译spice、qemu已经安装过一些软件包),所以会有很多需要安装。例如:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm_04

如果不知道安装什么包,方法就是先查有哪些相关包可以装,具体在上一篇已经说过,这个就不说了,我们这个是64位机器,所以需要执行下面命令来安装:

[root@localhost libvirt-5.2.0]# yum install -y gnutls-devel.x86_64

3、再重复第三步,直到./configure 没有报错

下面给出我在编译过程种提示需要安装的包,你也可以先执行一遍下面的命令,肯定会减少很多报错或许一次性就通过了。

[root@localhost libvirt-5.2.0]# yum install -y  gnutls-devel.x86_64 libnl-devel.x86_64  libxml2-devel.x86_64 libxslt.x86_64 device-mapper-devel libpciaccess-devel.x86_64 yajl-devel.x86_64 cyrus-sasl-devel.x86_64

当出现如下界面时,表示./configure 成功并生成Makefile文件。

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm 源码解析_05

4、make && make install

[root@localhost libvirt-5.2.0]# make && make install

没有任何错误提示的话,表示安装完毕,查看版本号:

[root@localhost libvirt-5.2.0]# virsh version
virsh: error while loading shared libraries: libvirt-lxc.so.0: cannot open shared object file: No such file or directory

解决方法:执行ldconfig,再查看

[root@localhost libvirt-5.2.0]# virsh version
error: failed to connect to the hypervisor
error: Failed to connect socket to '/usr/local/var/run/libvirt/libvirt-sock': No such file or directory

解决办法:启动libvirtd服务,即执行systemctl start libvirtd即可,再查看版本号:

[root@localhost libvirt-5.2.0]# systemctl start libvirtd
[root@localhost libvirt-5.2.0]# virsh version
Compiled against library: libvirt 5.2.0
Using library: libvirt 5.2.0
Using API: QEMU 5.2.0
Running hypervisor: QEMU 3.1.0

再次,我们也将该服务设置开机自启动,即执行命令:

[root@localhost libvirt-5.2.0]# systemctl enable libvirtd

至此,我们的libvirt 也就编译安装完毕了,接下来就进入使用环节了~

前面已经介绍过了,虚机管理工具virsh 是通过调用libvirt应用程序接口开管理虚机,且我们编译安装完libvirt就会自带virsh工具,因此本文接下来将会介绍利用virsh工具管理KVM虚机,大致分为四步:

第一步: 通过qemu-img创建一个镜像文件

[root@localhost IMG]# qemu-img create -f qcow2 CentOS.img 8G
Formatting 'CentOS.img', fmt=qcow2 size=8589934592 cluster_size=65536 lazy_refco

第二步: 编辑虚机属性xml文件,如test.xml,内容如下:

<domain type='kvm'>
     <name>test_centos</name>
         <memory>1048576</memory>
         <currentMemory>1048576</currentMemory>
          <vcpu>1</vcpu>
          <os>
         <type arch='x86_64' machine='pc'>hvm</type> //#hvm:全虚拟化
         <boot dev='hd'/>
         <boot dev='cdrom'/>
      </os>
   <features>
     <acpi/>
     <apic/>
     <pae/>
   </features>
   <clock offset='localtime'/>
   <on_poweroff>destroy</on_poweroff>
   <on_reboot>restart</on_reboot>
   <on_crash>destroy</on_crash>
   <devices>
     <emulator>/usr/libexec/qemu-kvm</emulator>
     <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
       <source file='/zhb/IMG/CentOS.img'/>
       <target dev='hda' bus='ide'/>
       //#使用virtio,采用普通的驱动,即硬盘和网卡都采用默认配置情况下,硬盘是 ide 模式,
       //#而网卡工作在 模拟的rtl 8139 网卡下,速度为100M 全双工。
       //#采用 virtio 驱动后,网卡工作在 1000M 的模式下,硬盘工作是SCSI模式下。
       //#硬盘采用 virtio 后,安装windows 系统,将不能正常的识别硬盘,解决的方法是:
       //#从kvm 的官网下载virtio的驱动iso。
       //#1. 先采用ide模式安装系统。
       //#2. 安装完成后,添加一个virtio模式的硬盘。
       //#3. 启动vm后,系统会自动搜索 SCSI的驱动,找到下载的virtio 驱动后,安装即可。
       //#4. 修改vm 配置文件,删除掉添加的 vitro 硬盘后,修改ide硬盘为 virtio模式即可
     </disk>
     <disk type='file' device='cdrom'>
       <source file='/zhb/ISO/CentOS-7-x86_64-Minimal-1810.iso'/>
       <target dev='hdb' bus='ide'/>
     </disk>
    <interface type='bridge'>     //虚拟机网络连接方式
      <source bridge='br0'/>
      <mac address="00:16:3e:5d:aa:a8"/>    //为虚拟机分配mac地址,务必唯一,否则dhcp获得同样ip,引起冲突
    </interface>
    <input type='mouse' bus='ps2'/>
     <graphics type='vnc' port='-1' autoport='yes' listen = '0.0.0.0' keymap='en-us'/>//vnc方式登录,端口号自动分配,自动加1
   </devices>
</domain>

第三步: 定义虚机,命令如下:

[root@localhost IMG]# virsh define test.xml
error: Failed to define domain from test.xml
error: Cannot check QEMU binary /usr/libexec/qemu-kvm: No such file or directory

如果出现上面的错误,需要做一个软连接,如下:

[root@localhost IMG]# ln -s /usr/bin/qemu-system-x86_64 /usr/libexec/qemu-kvm

或者修改/usr/libexec/qemu-kvm路径为qemu-system-x86_64路径即可。

我们再次执行virsh define test.xml,如下表示OK了:

[root@localhost IMG]# virsh define test.xml
Domain test_centos defined from test.xml

我们先看一下我们已经定义了哪些虚机(域)

kvm 源码解析 qemu/kvm源码解析与应用 pdf_libvirt_06


我们可以看到我们刚刚定义的虚机(域)是出于关闭状态;

第四步: 启动虚机,命令如下:

[root@localhost IMG]# virsh start test_centos
error: Failed to start domain test_centos
error: Cannot get interface MTU on 'br0': No such device

如果出现上面的错误,表示缺少br0网桥信息,配置br0 网桥;参考连接

1)为桥接新建配置文件

[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-ens33 ifcfg-br0
注:因为我原来的网卡是ifcfg-ens33,你的机器可能不是这个,如ifcfg-eth0.

2)编辑bridge网桥配置文件

编辑配置文件,让数据包通过bridge(网桥)进行上网.你的网络配置很可能是通过静态ip(BOOTPROTO=static)上网或者是从DHCP服务器获得ip(BOOTPROTO=dhcp)上网的.

DHCP 配置

/etc/sysconfig/network-scripts/ifcfg-ens33

/etc/sysconfig/network-scripts/ifcfg-br0

DEVICE=ens33

TYPE=Ethernet

HWADDR=00:0c:29:dc:d9:63

ONBOOT=yes

NM_CONTROLLED=no

BRIDGE=br0

DEVICE=br0

TYPE=Bridge

NM_CONTROLLED=no

BOOTPROTO=dhcp

ONBOOT=yes

如果你的网络是通过静态ip地址来配置的,那么你的配置很可能是和下面一样的:

static 配置

/etc/sysconfig/network-scripts/ifcfg-ens33

/etc/sysconfig/network-scripts/ifcfg-br0

DEVICE=ens33

TYPE=Ethernet

HWADDR=00:0c:29:dc:d9:63

ONBOOT=yes

NM_CONTROLLED=no

BRIDGE=br0

DEVICE=br0

TYPE=Bridge

NM_CONTROLLED=no

BOOTPROTO=static

IPADDR=192.168.222.128

NETMASK=255.255.255.0

ONBOOT=yes

当我们配置好网络以后,ifconfig 查看如下:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_spice_07

再次启动虚机(域),如下:

[root@localhost IMG]# virsh start test_ubuntu
error: Failed to start domain test_ubuntu
error: internal error: qemu unexpectedly closed the monitor: libvirt:  error : cannot execute binary /usr/bin/qemu-system-x86_64: Permission denied

解决方法:关闭selinux(/etc/selinux/config中SELINUX项设为disabled),重启系统,搞定~,如下表示已经启动成功:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_libvirt_08

我们还可以通过下面命令,查看vnc 的端口:

[root@localhost IMG]# virsh vncdisplay test_centos
:0

到此,利用virsh 创建虚机已经基本完成,接下来我们还是用vnc进行连接,端口是5900+0,如下进入操作系统安装界面,具体安装就不再介绍了:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm_09

操作系统安装好以后,这是最小化安装的CentOS7,已经进入登陆界面了,如下:

kvm 源码解析 qemu/kvm源码解析与应用 pdf_kvm_10


  好了,本文就介绍到这里了,可能有的学者已经发现,第一,讲解的libvirt 创建和使用虚机基本不都还是命令吗?是的,但是这些virsh 命令都是有对应libvirt API 可供我们的。第二,我们前面说的spice 还一直没有体现,这个我将放到下一篇博客进行介绍,请继续关注~






最后我也说一下在使用过程中可能遇到的一些问题及其解决方案,有的在正文中已经介绍了

问题1:

[root@localhost IMG]# virsh start test_centos
error: Failed to start domain test_centos
error: Failed to connect socket to '/usr/local/var/run/libvirt/virtlogd-sock': N                                                                     o such file or directory

如果出现上面的错误错误,我们需要启动以下virtlogd 服务,如下:

[root@localhost IMG]# virtlogd -d

问题2:

在使用QEMU 命令启动KVM虚拟机时,指令执行后,控制台只出现了如下类似的提示:
VNC server running on ::1:5901

原因是安装qemu的时候没有安装SDL相关库,这里需要我们先安装SDL库,再重新配置、编译、安装qemu,解决方法步骤如下:

  1. 安装SDL开发库
[root@localhost ~]# yum install SDL-devel -y
  1. 重新编译QEMU
[root@localhost qemu-3.1.0]#  export PKG_CONFIG_PATH=/usr/local/share/pkgconfig/:/usr/local/lib/pkgconfig/
[root@localhost qemu-3.1.0]# ./configure --enable-spice --enable-kvm --target-list=x86_64-softmmu --prefix=/usr

由于上篇已经具体介绍过了,这里就不截图了,变化的是执行以上指令后,我们可以从输出中看到与上一篇不同的是:SDL support yes (1.2.15)

# make && make install