虚拟化技术

概述

虚拟化(Virtualization)技术最早出现在 20 世纪 60 年代的 IBM 大型机系统,在70年代的 System370 系列中逐渐流行起来,这些机器通过一种叫虚拟机监控器(Virtual Machine Monitor,VMM)的程序在物理硬件之上生成许多可以运行独立操作系统软件的虚拟机(Virtual Machine)实例

VMM虚拟机监控器也称为Hypervisor,就是为了虚拟化而引入的一个软件层,它向下掌控实际的物理资源,向上呈现出N份逻辑资源,虚拟机监控器运行的实际物理环境,称为宿主机;其上虚拟出来的逻辑主机,称为客户机

虚拟化方案

软件虚拟化和硬件虚拟化

软件虚拟化

  • 通过软件模拟来实现VMM层,通过纯软件的环境来模拟执行客户机里的指令
  • 最纯粹的软件虚拟化实现是QEMU,在没有启用硬件虚拟化辅助的时候,通过软件的二进制翻译仿真出目标平台呈现给客户机,客户机里的每一条目标平台指令都会被QEMU截取,并翻译成宿主机平台的指令,然后交给实际的物理平台执行
  • 虚拟化性能较差,但是可以呈现给各种平台给客户机

硬件虚拟化

  • 计算机硬件本身提供能力让客户机指令独立运行,而不需要VMM截获重定向
  • Intel从2005年开始在其x86cpu中加入硬件虚拟化的支持,简称Intel VT技术

半虚拟化和全虚拟化

部分虚拟化

  • VMM 只模拟部分底层硬件,只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改,不做修改是无法在虚拟机中运行的,其它程序可能也需要进行修改
  • 在历史上,部分虚拟化是通往全虚拟化道路上的重要里程碑,最早出现在第一代的分时系统 CTSS 和 IBM M44/44X 实验性的分页系统中

全虚拟化

  • 虚拟机模拟了完整的底层硬件,包括处理器、物理内存、时钟、外设等,使得为原始硬件设计的操作系统或其它系统软件完全不做任何修改就可以在虚拟机中运行
  • 例如ⅤMware Workstation、ⅤirtualBox、QEMU等

超虚拟化

  • 修改 Guest OS 部分访问特权状态的代码以便直接与 VMM 交互的技术
  • 在超虚拟化虚拟机中,部分硬件接口以软件的形式提供给客户机操作系统,客户操作系统需要进行修改,例如早期的Xen

一个优秀的虚拟化软件往往融合了多项虚拟化技术,例如 VMware Workstation是一个著名的全虚拟化VMM,但是它使用了一种被称为动态二进制翻译的技术把对特权状态的访问转换成对影子状态的操作,从而避免了低效的 Trap-And-Emulate 的处理方式,这与超虚拟化相似,只不过超虚拟化是静态地修改程序代码

对于超虚拟化而言,如果能利用硬件特性,那么虚拟机的管理将会大大简化,同时还能保持较高的性能

Type1虚拟化和Type2虚拟化

  • Type1类型也叫裸金属架构,这类虚拟化层直接运行在硬件之上,没有所谓的宿主机操作系统,他们直接控制硬件资源以及客户机

    • 例如xen和vmware ESXI
  • Type2类型也叫宿主机型架构,这类VMM通常就是宿主机操作系统上的一个应用程序,像其他应用程序一样受宿主机操作系统的管理,通常抽象为进程

    • 例如,VMware workstation、KVM

KVM虚拟化 - 图1

KVM虚拟化技术介绍

架构

KVM虚拟化的核心主要由一下两个模块组成

  • KVM内核模块:它属于标准Linux内核的一部分,是一个专门提供虚拟化功能的模块,主要负责CPU和内存的虚拟化,包括:客户机的创建、虚拟内存的分配、CPU执行模式的切换、VCPU寄存器的访问、VCPU的执行,KVM模块是KVM虚拟化的核心模块

    • 它在内核中由两部分组成,一个是处理器架构无关的部分,可以用lsmod命令看到,叫做KVM模块;另一个是处理器架构相关的部分,在intel平台上就是kvm_intel这个内核模块
    • KVM主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚拟客户机的运行提供一定的支持
  • QEMU用户态工具:它是一个普通的Linux进程,为客户机提供设备模拟的功能,包括模拟BIOS、数据总线、磁盘、网卡、显卡、声卡、键盘、鼠标等,同时它通过系统调用与内核态的KVM模块进行交互

    • 作为一个存在已久的虚拟机监控器软件,QEMU的代码中有完整的虚拟机实现,包括处理器虚拟化、内存虚拟化,以及KVM也会用到的设备模拟功能
    • QEMU既是一个功能完整的虚拟机监控器,也在QEMU/KVM软件栈中承担设备模拟的功能

在KVM虚拟化架构下,每一个客户机就是一个QEMU进程,在一个宿主机上有多少个虚拟机就会有多少个QEMU进程;客户机中的每一个虚拟CPU对应QEMU进程中的一个执行线程;一个宿主机只有一个KVM内核模块,所有客户机都与这个内核模块进行交互

上层管理工具

libvirt

libvirt是使用最广泛的对KVM虚拟化进行管理的工具和应用程序接口,已经是事实上的虚拟化接口标准,后部分介绍的许多工具都是基于libvirt的API来实现,作为通用的虚拟化API,libvirt不但能管理KVM,还能管理VMware、Hyper-v等其他虚拟化方案

virsh

virsh是一个常用的管理KVM虚拟化的命令行工具,对于系统管理员在单个宿主机上进行运维操作,virsh命令行可能是最佳选择,virsh是用C语言编写的一个使用libvirt API的虚拟化管理工具,其源代码也是在libvirt这个开源项目中的

virt-manager

virt-manager是专门针对虚拟机的图形化管理软件,底层与虚拟化交互的部分仍然是调用libvirt API来操作的,virt-manager除了提供虚拟机生命周期(包括:创建、启动、停止、打快照、动态迁移等)管理的基本功能,还提供了性能和资源使用率的监控

KVM安装

环境准备

更新软件包,并安装图形化桌面程序

  1. [root@server ~]# yum upgrade -y
  2. [root@server ~]# yum groupinstall -y "GNOME 桌面"

进入桌面程序

[root@server ~]# startx

开启硬件辅助虚拟化

KVM虚拟化 - 图2

查看CPU支持的功能中是否存在

  • vmx:INTEL的虚拟化功能
  • svm:AMD的虚拟化功能
[root@server ~]# cat /proc/cpuinfo | grep vmx
[root@server ~]# cat /proc/cpuinfo | grep svm

查看是否加载kvm

[root@server libvirt]# lsmod | grep kvm
kvm_intel             188740  0 
kvm                   637515  1 kvm_intel
irqbypass              13503  1 kvm

设置开机启动

[root@server ~]# systemctl set-default graphical.target     # 开机启动图形界面
[root@server ~]# systemctl set-default multi-user.target    # 开机启动命令界面

清理预装KVM

[root@server libvirt]# yum remove `rpm -qa |egrep 'qemu|virt|kvm'` -y
[root@server libvirt]# rm -rf /var/lib/libvirt /etc/libvirt/

安装KVM相关工具

[root@server ~]# yum install *qemu* *virt* librbd1-devel -y

启动服务

[root@server ~]# systemctl start libvirtd.service 
[root@server ~]# systemctl enable libvirtd.service

Guest OS安装

图形化模式安装Guest OS

为了让空间足够,这里先挂载上一块20G的硬盘,在挂载前需要把/var/lib/libvirt/中的内容先备份走,否则里面原有的default存储池会被覆盖,等挂载完成后,再将这些内容移动回来

[root@server ~]# fdisk /dev/sdb
[root@server ~]# mkfs -t ext4 /dev/sdb1
[root@server ~]# blkid
[root@server ~]# vim /etc/fstab 
[root@server ~]# mv /var/lib/libvirt/* /tmp/vm
[root@server ~]# mount -a
[root@server ~]# mv /tmp/vm/* /var/lib/libvirt/
[root@server ~]# virt-manager

KVM虚拟化 - 图3

KVM虚拟化 - 图4

KVM虚拟化 - 图5

KVM虚拟化 - 图6

KVM虚拟化 - 图7

点击完成后,接下来就跟正常安装系统一样进行安装即可

KVM虚拟化 - 图8

KVM虚拟化 - 图9

借助已有虚拟机安装

虚拟机的组成部分

  1. 虚拟机配置文件
[root@server ~]# ls /etc/libvirt/qemu
networks  vm1.xml
  1. 存储虚拟机的介质
[root@server ~]# ls /var/lib/libvirt/images/
vm1.qcow2

根据配置文件创建虚拟机

  1. 拷贝配置文件
[root@server ~]# cd /etc/libvirt/qemu/
[root@server qemu]# cp vm1.xml vm2.xml
[root@server qemu]# ls
networks  vm1.xml  vm2.xml
  1. 修改新的配置文件信息
[root@server images]# uuidgen
c37b9579-7d35-4c74-9216-465c7980f5ab
[root@server images]# vim /etc/libvirt/qemu/vm2.xml
# 将uuid修改、将所有的vm1改为vm2
  1. 拷贝磁盘镜像文件
[root@server qemu]# cd /var/lib/libvirt/images/
[root@server images]# cp vm1.qcow2 vm2.qcow2
[root@server images]# ls
vm1.qcow2  vm2.qcow2
  1. 创建虚拟机
[root@server ~]# virsh define /etc/libvirt/qemu/vm2.xml 
定义域 vm2(从 /etc/libvirt/qemu/vm2.xml)
  1. 查看虚拟机启动信息
[root@server ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 -     vm1                            关闭
 -     vm2                            关闭

[root@server ~]# virsh start vm2
域 vm2 已开始

[root@server ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 2     vm2                            running
 -     vm1                            关闭

同样可以进入虚拟系统管理器查看KVM虚拟化 - 图10

命令安装虚拟机

  • 配置FTP,并将镜像挂载上去
[root@server ~]# systemctl stop firewalld.service
[root@server ~]# yum install -y vsftpd
[root@server ~]# systemctl start vsftpd
[root@server ~]# cd /var/ftp/
[root@server ftp]# mkdir centos
[root@server ftp]# mount /root/CentOS-7-x86_64-Minimal-1810.iso /var/ftp/centos/
mount: /dev/loop0 写保护,将以只读方式挂载
  • 使用命令安装
[root@server centos]# virt-install --connect qemu:///system -n vm3 -r 2048 --disk path=/var/lib/libvirt/images/vm3.img,size=7 --os-type=linux --os-variant=centos7.0 --vcpus=2 --location=ftp://192.168.31.88/centos -x console=ttyS0 --nographics

参数说明:
-n:虚拟机名字
-r:以M为单位指定分配给虚拟机的内存大小
—disk:指定作为客户机存储的媒介size以G为单位的存储
—os-type:针对一类操作系统优化虚拟机配置
—os-variant:针对特定操作系统变体进一步优化虚拟机配置
—vcpus:CPU核数
—location:客户虚拟机kernel+initrd安装源,必须为镜像挂载在ftp目录下
-x:当执行从”–location”选项指定位置的客户机安装时,附加内核命令行参数到安装程序
—nographics:指定没有控制台被分配给客户机

  • 进入命令化安装,一开始输入2:

KVM虚拟化 - 图11

  • 输入对应的数字,配置这些没有配置的配置

KVM虚拟化 - 图12

  • 最后全部配置完后输入b就可以进行安装了

KVM虚拟化 - 图13

KVM虚拟化 - 图14

[root@server ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 2     vm3                            running
 -     vm2                            关闭
 -     vm1                            关闭
  • 本地有镜像的安装方法
[root@server ~]# virt-install -name=vm3 --ram 512 --vcpus=1 --disk path=/var/lib/libvirt/images/vm3.qcow2,size=5,bus=virtio --accelerate --cdrom /root/CentOS-7-x86_64-Minimal-1810.iso --vnc --vncport=-1 --vnclisten=0.0.0.0 --network bridge=virbr0,model=virtio --noautoconsole

KVM基础管理

下面这些操作在KVM图形化界面都能实现

常用管理命令

  • 查看命令
[root@server ~]# virsh list --all
[root@server ~]# virsh dumpxml vm1        # 查看虚拟机的配置
[root@server ~]# virsh edit vm1            # 更改虚拟机的配置
[root@server ~]# virsh list --all --autostart    # 查看开机自启动的虚拟机
[root@server ~]# ls /etc/libvirt/qemu/autostart    # 这个目录下存放着开机自启动的虚拟机的xml配置文件
  • 虚拟机操作命令
[root@server ~]# virsh start vm1        # 开启虚拟机
[root@server ~]# virsh suspend vm1         # 暂停虚拟机
[root@server ~]# virsh resume vm1         # 恢复虚拟机
[root@server ~]# virsh shutdown vm1     # 关闭虚拟机
[root@server ~]# virsh reboot vm1         # 重启虚拟机
[root@server ~]# virsh reset vm1        # 重置虚拟机
[root@server ~]# virsh undefine vm1     # 删除虚拟机
[root@server ~]# virsh autostart vm1     # 开机自启动虚拟机
[root@server ~]# virsh autostart --disable vm1     # 取消开机自动启动虚拟机
[root@server ~]# virsh destroy vm1         # 强行删除虚拟机,即使虚拟机是开启状态

使用命令删除虚拟机后,需要把磁盘文件和配置文件一同删除

[root@server ~]# virsh undefine vm2
[root@server ~]# rm -f /var/lib/libvirt/images/vm2.qcow2
[root@server ~]# rm -f /etc/libvirt/qemu/vm2.xml

虚拟机克隆

  • 不指定名字自动分配
[root@server ~]# virt-clone -o vm1 --auto-clone
正在分配 'vm1-clone.qcow2'                                                    | 8.0 GB  00:00:09     

成功克隆 'vm1-clone'。

[root@server ~]# virsh list --all 
 Id    名称                         状态
----------------------------------------------------
 -     vm1                            关闭
 -     vm1-clone                      关闭
  • 指定名字分配
[root@server ~]# virt-clone -o vm1 -n vm2 --auto-clone
正在分配 'vm2.qcow2'                                                          | 8.0 GB  00:00:04     

成功克隆 'vm2'。
[root@server ~]#  virsh list --all 
 Id    名称                         状态
----------------------------------------------------
 -     vm1                            关闭
 -     vm1-clone                      关闭
 -     vm2                            关闭
  • 指定克隆之后虚拟机的磁盘镜像文件
[root@server ~]# virt-clone -o vm1 -n vm2 --auto-clone -f /var/lib/libvirt/images/vm2_disk.qcwo2 
正在分配 'vm2_disk.qcwo2'                                                     | 8.0 GB  00:00:04     

成功克隆 'vm2'。
[root@server ~]# ls /var/lib/libvirt/images/
vm1.qcow2  vm2_disk.qcwo2
[root@server ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 -     vm1                            关闭
 -     vm2                            关闭

虚拟机快照

  • 生成快照:virsh snapshot-create-as 虚拟机名称 快照名称
[root@server ~]# virsh snapshot-create-as vm1 vm1.snap
已生成域快照 vm1.snap

[root@server ~]# qemu-img info /var/lib/libvirt/images/vm1.qcow2 
image: /var/lib/libvirt/images/vm1.qcow2
file format: qcow2
virtual size: 8.0G (8589934592 bytes)
disk size: 8.3G
cluster_size: 65536
Snapshot list:        # 快照列表
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         vm1.snap               269M 2022-03-12 20:30:00   00:02:09.037
Format specific information:
    compat: 1.1
    lazy refcounts: true
  • 查看快照:virsh snapshot-list 虚拟机名称
[root@server ~]# virsh snapshot-list vm1
 名称               生成时间              状态
------------------------------------------------------------
 vm1.snap             2022-03-12 20:30:00 +0800 running

# 或者使用

[root@server ~]# qemu-img info /var/lib/libvirt/images/vm1.qcow2 
image: /var/lib/libvirt/images/vm1.qcow2
file format: qcow2
virtual size: 8.0G (8589934592 bytes)
disk size: 8.3G
cluster_size: 65536
Snapshot list:        # 快照列表
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         vm1.snap               269M 2022-03-12 20:30:00   00:02:09.037
Format specific information:
    compat: 1.1
    lazy refcounts: true
  • 转到快照:virsh snapshot-revert 虚拟机名称 快照名称
[root@server ~]# virsh snapshot-revert vm1 vm1.snap
  • 删除快照:virsh snapshot-delete 虚拟机名称 --snapshotname 快照名称
[root@server ~]# virsh snapshot-delete vm1 --snapshotname vm1.snap
已删除域快照 vm1.snap

[root@server ~]# virsh snapshot-list vm1
 名称               生成时间              状态
------------------------------------------------------------

快照的信息在图形化界面也能看到

KVM虚拟化 - 图15

Guest OS修改配置

下面这些操作在KVM图形化界面都能实现

添加磁盘

  1. 修改配置文件
[root@server images]# vim /etc/libvirt/qemu/vm1.xml 
      <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </disk>
# 下面是添加的部分
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1-1.qcow2'/>
      <target dev='vdb' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x17' function='0x0'/>
    </disk>

注意:centos8里面硬盘和网卡的添加已经不能修改slot了,要求修改的是bus地址

  1. 创建新的空磁盘卷
[root@server images]# qemu-img create -f qcow2 vm1-1.qcow2 5G
Formatting 'vm1-1.img', fmt=qcow2 size=5368709120 encryption=off cluster_size=65536 lazy_refcounts=off 
[root@server images]# ls
vm1-1.qcow2  vm1.qcow2  vm2_disk.qcwo2
  1. 重新定义
[root@server images]# virsh define /etc/libvirt/qemu/vm1.xml 
定义域 vm1(从 /etc/libvirt/qemu/vm1.xml)
  1. 查看当前的磁盘源信息
[root@server ~]# virsh domblklist vm1
目标     源
------------------------------------------------
vda        /var/lib/libvirt/images/vm1.qcow2
vdb        /var/lib/libvirt/images/vm1-1.qcow2
hda        -

KVM虚拟化 - 图16

  1. 删除磁盘
[root@server ~]# virsh detach-disk vm1 /var/lib/libvirt/images/vm1-1.qcow2 
成功分离磁盘

[root@server ~]# virsh domblklist vm1
目标     源
------------------------------------------------
vda        /var/lib/libvirt/images/vm1.qcow2
hda        -
[root@server ~]# ls /var/lib/libvirt/images/vm1-1.qcow2 
/var/lib/libvirt/images/vm1-1.qcow2
# 仅是分离,磁盘文件并没有被删除

添加CPU核数

  1. 修改配置文件
[root@server ~]# virsh edit vm1
<domain type='kvm'>
  <name>vm1</name>
  <uuid>a47e13cd-5610-4f7c-a4b4-2ef417b099de</uuid>
  <memory unit='KiB'>524288</memory>
  <currentMemory unit='KiB'>524288</currentMemory>
  <vcpu placement='auto' current='2'>4</vcpu>    # 修改此处,代表最大CPU支持4个,当前使用2个

也可以通过修改/etc/libvirt/qemu/vm1.xml来配置,但是不适用virsh edit修改方式的话,需要virsh define重新定义一下

  1. 查看vm1虚拟机系统情况
[root@server ~]# virsh dominfo vm1
Id:             -
名称:       vm1
UUID:           a47e13cd-5610-4f7c-a4b4-2ef417b099de
OS 类型:    hvm
状态:       关闭
CPU:          2
最大内存: 524288 KiB
使用的内存: 524288 KiB
持久:       是
自动启动: 禁用
管理的保存: 否
安全性模式: none
安全性 DOI: 0
  1. 也可以进入客户机查看cpu核数情况

KVM虚拟化 - 图17

内存热添加

热添加的意思就是可以在虚拟机不重启的情况下完成添加,不支持热减少

  • 修改配置文件
[root@server ~]# virsh edit vm1
<domain type='kvm'>
  <name>vm1</name>
  <uuid>a47e13cd-5610-4f7c-a4b4-2ef417b099de</uuid>
  <memory unit='KiB'>1048576</memory>    # 最大可用内存
  <currentMemory unit='KiB'>1048576</currentMemory>    # 当前使用内存
  <vcpu placement='auto' current='2'>4</vcpu>

KVM虚拟化 - 图18

KVM存储

  • KVM必须配置一个目录当作存储磁盘镜像的目录,这个目录就是存储池
  • 默认存储池:/var/lib/libvirt/images

存储池创建使用相关命令

  1. 创建基于文件夹的存储池,并且定义存储池及其目录
[root@server ~]# mkdir -p /data/vmfs/
[root@server ~]# virsh pool-define-as vmdisk1 --ype dir --target /data/vmfs
  1. 创建已经定义的存储池,然后查看已定义的存储池,存储池不激活无法使用
[root@server ~]# virsh pool-build vmdisk1 
构建池 vmdisk1

[root@server ~]# virsh pool-start vmdisk1 
池 vmdisk1 已启动

[root@server ~]# virsh pool-list --all 
 名称               状态     自动开始
-------------------------------------------
 default              活动     是       
 vmdisk1              活动     否       

[root@server ~]# virsh pool-autostart vmdisk1 
池 vmdisk1 标记为自动启动

[root@server ~]# virsh pool-list --all 
 名称               状态     自动开始
-------------------------------------------
 default              活动     是       
 vmdisk1              活动     是
  1. 在存储池中创建虚拟机存储卷
[root@server ~]# virsh vol-create-as vmdisk1 vm1-2.qcow2 2G --format qcow2
创建卷 vm1-2.qcow2 

[root@server ~]# ls /data/vmfs/
vm1-2.qcow2

存储池删除相关管理命令

  1. 在存储池中删除虚拟机存储卷
[root@server ~]# virsh vol-delete --pool vmdisk1 vm1-2.qcow2 
卷 vm1-2.qcow2 被删除
  1. 取消激活存储池
[root@server ~]# virsh pool-destroy vmdisk1 
销毁池 vmdisk1
[root@server ~]# virsh pool-list --all 
 名称               状态     自动开始
-------------------------------------------
 default              活动     是       
 vmdisk1              不活跃  是
  1. 删除存储池定义的目录
[root@server ~]# virsh pool-delete vmdisk1 
池 vmdisk1 被删除
[root@server ~]# ls /data/vmfs/
ls: 无法访问/data/vmfs/: 没有那个文件或目录
  1. 取消定义存储池
[root@server ~]# virsh pool-undefine vmdisk1 
池 vmdisk1 已经被取消定义
[root@server ~]# virsh pool-list --all 
 名称               状态     自动开始
-------------------------------------------
 default              活动     是

磁盘格式

raw:KVM磁盘的默认格式,指定多大就创建多大,直接占用指定大小的空间,性能最好

qcow:一代的qemu的cow格式,刚刚出现的时候有比较好的特性,但其性能和raw格式对比还是有很大的差距,目前已经被新版本的qcow2取代

qcow2:空间是动态增长的,性能上还是不如raw,但是raw不支持快照,qcow2支持快照

写时拷贝(Copy On Write)

写时拷贝(copy-on-write, COW)就是等到修改数据时才真正分配内存空间,这是对程序性能的优化,可以延迟甚至是避免内存拷贝,当然目的就是避免不必要的内存拷贝

  • raw是立刻分配空间,不管你有没有用到那么多空间
  • qcow2只是承诺给你分配空间,但是只有当你需要用空间的时候才会给你空间,最多只给你承诺空间的大小,避免空间浪费
[root@server ~]# qemu-img create -f qcow2 test1.qcow2 1G
Formatting 'test1.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off 

[root@server ~]# qemu-img create -f raw test2.raw 1G
Formatting 'test2.raw', fmt=raw size=1073741824 

[root@server ~]# ls -lh test1.qcow2 test2.raw 
-rw-r--r-- 1 root root 193K 3月  12 19:36 test1.qcow2
-rw-r--r-- 1 root root 1.0G 3月  12 19:37 test2.raw

虚拟机磁盘挂载至宿主机

  • 有时候虚拟机会出现故障,比如说配置文件有问题导致无法启动,这个时候就可以将虚拟机的磁盘文件挂载到宿主机上,获得其中的文件
  1. 查看磁盘镜像分区信息
[root@server images]# virt-df -h -d vm1
文件系统                           大小     已用空间    可用空间   使用百分比%
vm1:/dev/sda1                   1014M       100M       914M      10%
vm1:/dev/centos/root             6.2G       971M       5.2G      16%
  1. 挂载磁盘镜像分区,挂载完成后可以看到vm1虚拟机根目录下的文件
[root@server ~]# guestmount -d vm1 -m /dev/centos/root --rw /mnt/vm1
[root@server ~]# cd /mnt/vm1/
[root@server vm1]# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
[root@server vm1]# cat root/test 
hello world
  1. 取消挂载
[root@server vm1]# cd ~
[root@server ~]# guestunmount /mnt/vm1/

KVM网络管理

KVM的网络有三种模式:

  • nat:NAT模式
  • isolated:隔离模式
  • bridge:桥接模式

虚拟交换机

  • linux-brige(linux自带)
  • ovs(open-vswitch)

NAT模式

  • 默认网络

  • 宿主机和虚拟机之间可以互相访问

  • 数据包由NAT方式通过主机的接口进行传送,可以访问外网,但是无法从外网访问虚拟机网络

KVM虚拟化 - 图19

配置NAT模式

  1. 复制默认的NAT网络配置
[root@server ~]# cd /etc/libvirt/qemu/networks/
[root@server networks]# cp default.xml nat1.xml
  1. 修改配置文件
[root@server networks]# uuidgen
0dd9623e-a6b5-422a-937b-c7917a34f416
[root@server networks]# vim nat1.xml 

<network>
  <name>nat1</name>
  <uuid>0dd9623e-a6b5-422a-937b-c7917a34f416</uuid>
  <forward mode='nat'/>
  <bridge name='virbr1' stp='on' delay='0'/>
  <mac address='52:54:00:3e:b6:3a'/>
  <ip address='192.168.100.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.100.2' end='192.168.100.254'/>
    </dhcp>
  </ip>
</network>
  1. 重启libvirtd服务,然后激活新的NAT网络
[root@server networks]# systemctl restart libvirtd
[root@server networks]# virsh net-list
 名称               状态     自动开始  持久
----------------------------------------------------------
 default              活动     是           是

[root@server networks]# virsh net-start nat1
网络 nat1 已开始
[root@server networks]# virsh net-autostart nat1
网络nat1标记为自动启动
[root@server networks]# virsh net-list
 名称               状态     自动开始  持久
----------------------------------------------------------
 default              活动     是           是
 nat1                 活动     是           是
  1. 修改虚拟机的配置,然后启动虚拟机检查网络是否生效
[root@server ~]# virsh edit vm1
    <interface type='network'>
      <mac address='52:54:00:f4:89:dd'/>
      <source network='nat1'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
  1. 也可以在这里更改,当第3步执行完后,网络源中就会有一个nat1网络源了,这个时候可以自己手动选,也可以和第4步一样去修改虚拟机的配置文件

KVM虚拟化 - 图20

KVM虚拟化 - 图21

可以发现IP地址变为了192.168.100.110,和配置文件中的192.168.100.xxx网段一样,NAT模式配置成功

隔离模式

  • 虚拟机和宿主机可以互相访问
  • 宿主机不提供NAT功能,所以虚拟机和宿主机所在物理网络无法互相访问

KVM虚拟化 - 图22

配置隔离模式

  1. 复制默认的NAT网络配置
[root@server ~]# cd /etc/libvirt/qemu/networks/
[root@server networks]# cp default.xml isolated1.xml
  1. 修改配置文件,注意不同于NAT模式的配置文件的是 <forward mode='nat'/>这一行少了
[root@server networks]# uuidgen
889f134d-9b70-4928-a7aa-42383278a325
[root@server networks]# vim isolated1.xml

<network>
  <name>isolated1</name>
  <uuid>889f134d-9b70-4928-a7aa-42383278a325</uuid>
  <bridge name='virbr2' stp='on' delay='0'/>
  <mac address='52:54:00:3e:b6:3a'/>
  <ip address='192.168.200.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.200.2' end='192.168.200.254'/>
    </dhcp>
  </ip>
</network>
  1. 重启libvirtd服务,然后激活新的NAT网络
[root@server networks]# systemctl restart libvirtd
[root@server networks]# virsh net-start isolated1
网络 isolated1 已开始

[root@server networks]# virsh net-autostart isolated1
网络isolated1标记为自动启动

[root@server networks]# virsh net-list
 名称               状态     自动开始  持久
----------------------------------------------------------
 default              活动     是           是
 isolated1            活动     是           是
 nat1                 活动     是           是
  1. 当第3步执行完后,网络源中就会有一个isloated网络源了,这个时候可以自己手动选

KVM虚拟化 - 图23

  • 此时IP地址是192.168.200.110,是隔离网络,无法访问百度

KVM虚拟化 - 图24

桥接模式

  • 虚拟机和宿主机再同一个网段中

  • 虚拟机和宿主机可以互相访问

  • 外部的主机可以直接访问到虚拟机内部

KVM虚拟化 - 图25

配置桥接网络

在宿主机上

  • 添加虚拟网卡
[root@server ~]# brctl addif virbr0 vnet0
  • 新建桥接网卡配置文件
[root@server ~]# vim /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
NAME=br0
DEVICE=br0
ONBOOT=yes
BOOTPROTO=dhcp
  • 修改宿主机网卡配置文件
[root@server ~]# cp /etc/sysconfig/network-scripts/ifcfg-ens33{,.bak}
[root@server ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
DEVICE=ens33
ONBOOT=yes
BRIDGE=br0
  • 重启 libvirtdnetwork 服务
[root@server ~]# systemctl restart network libvirtd
  • 修改虚拟机的配置,然后启动虚拟机检查网络是否生效
[root@server ~]# virsh edit vm1
    <interface type='bridge'>
      <mac address='52:54:00:f4:89:dd'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

KVM虚拟化 - 图26

发现都在同一个网段,因此桥接模式配置成功

删除桥接网卡步骤:

  1. 删除br0的配置文件
  2. 修改正常网卡的配置文件
  3. 重启系统

批量部署虚拟机

  • 编写安装配置文件,会在脚本文件中导入
[root@server ~]# vim kvm.txt
centos01 1024 2 2
centos02 512  3 2
centos03 1024 4 2
centos04 502  5 2
centos05 1024 6 2
  • 编写脚本文件
[root@server ~]# vim kvm-mamge.sh
#!/bin/bash
XML_DIR="/etc/libvirt/qemu"
KVM_DIR="/disk-pool/"
add_kvm(){
if [ ! -e kvm.txt ];then
    echo "文件不存在,请创建"
    exit 401
fi
if [ ! -s kvm.txt ];then
    echo "文件为空,请在其中插入数据"
    exit 402
fi
while read line
do
    NAME=`echo $line | awk '{print $1}'`
    RAM=`echo $line | awk '{print $2}'`
    SIZE=`echo $line | awk '{print $3}'`
    CPU=`echo $line | awk '{print $4}'`
    virt-install -name=${NAME} --ram ${RAM} --vcpus=${CPU} --disk path=/var/lib/libvirt/images/${NAME}.qcow2,size=${SIZE},bus=virtio --accelerate --cdrom /root/CentOS-7-x86_64-Minimal-1810.iso --vnc --vncport=-1 --vnclisten=0.0.0.0 --network bridge=virbr0,model=virtio --noautoconsole
done < kvm.txt

echo "成功创建虚拟机"
exit 200
}

clone_kvm(){
echo "成功克隆虚拟机"
exit 200
}

delete_kvm(){
    read -p "请输入你需要删除的虚拟机,以空格分隔:" name
    for i in `echo ${name} | sed 's/ /\n/g'`
    do
    virsh destroy $i
    virsh undefine $i
    rm -f /var/lib/libvirt/images/${name}.qcow2
    rm -f /etc/libvirt/qemu/${name}.xml
    echo "$i虚拟机成功被删除"

echo "成功删除虚拟机"
exit 200
}
echo 请输入:$0 "{add_kvm|clone_lvm|delete_kvm|help}"

case $1 in
    add_kvm )
    add_kvm
    ;;
    clone_kvm )
    clone_kvm
    ;;
    delete_kvm )
    delete_kvm
    ;;
    * )
    echo 请输入:$0 "{add_kvm|clone_lvm|delete_kvm|help}"
    ;;
esac
  • 运行脚本,增加虚拟机
[root@server ~]# chmod +x kvm-mamge.sh
[root@server ~]# ./kvm-mamge.sh add_kvm

KVM虚拟化 - 图27

  • 进行图形化控制台查看,可以看到有五台虚拟机正在等待被安装

KVM虚拟化 - 图28

KVM虚拟化 - 图29

  • 运行脚本,删除虚拟机
[root@server ~]# ./kvm-mamge.sh delete_kvm
200 ok
401 file not exist
402 file is empty
请输入操作:./kvm-mamge.sh {add_kvm|clone_lvm|delete_kvm|help}
请输入你需要删除的虚拟机,以空格分隔:ame=centos01 ame=centos04
域 ame=centos01 被删除

域 ame=centos01 已经被取消定义

ame=centos01 虚拟机成功被删除
域 ame=centos04 被删除

域 ame=centos04 已经被取消定义

ame=centos04 虚拟机成功被删除
成功删除虚拟机

KVM虚拟化 - 图30