KVM

一、预备知识

1、虚拟化

       虚拟化是云计算的基础。简单的说,虚拟化使得在一台物理的服务器上可以跑多台虚拟机,虚拟机共享物理机的 CPU、内存、IO 硬件资源,但逻辑上虚拟机之间是相互隔离的。物理机我们一般称为宿主机(Host),宿主机上面的虚拟机称为客户机(Guest)。

那么 Host 是如何将自己的硬件资源虚拟化,并提供给 Guest 使用的呢?这个主要是通过一个叫做 Hypervisor 的程序实现的。根据 Hypervisor 的实现方式和所处的位置,虚拟化又分为两种:1型虚拟化和2型虚拟化。

1)1型虚拟化

Hypervisor 直接安装在物理机上,多个虚拟机在 Hypervisor 上运行。Hypervisor 实现方式一般是一个特殊定制的 Linux 系统。Xen 和 VMWare 的 ESXi 都属于这个类型。

 2)2型虚拟化

物理机上首先安装常规的操作系统,比如 Redhat、Ubuntu 和 Windows。Hypervisor 作为 OS 上的一个程序模块运行,并对管理虚拟机进行管理。KVM、VirtualBox 和 VMWare Workstation 都属于这个类型。

理论上讲:

1型虚拟化一般对硬件虚拟化功能进行了特别优化,性能上比2型要高;

2型虚拟化因为基于普通的操作系统,会比较灵活,比如支持虚拟机嵌套。嵌套意味着可以在KVM虚拟机中再运行KVM。

二、kvm

1、基本概念

      在 x86 平台上最热门运用最广泛的虚拟化方案莫过于 KVM 了。OpenStack 对 KVM 支持得也最好,我们的教程也理所当然选择 KVM 作为 实验环境的 Hypervisor。KVM 全称是 Kernel-Based Virtual Machine。也就是说 KVM 是基于 Linux 内核实现的。KVM有一个内核模块叫 kvm.ko,只用于管理虚拟 CPU 和内存。

那 IO 的虚拟化,比如存储和网络设备由谁实现呢?这个就交给 Linux 内核和Qemu来实现。

说白了,作为一个 Hypervisor,KVM 本身只关注虚拟机调度和内存管理这两个方面。IO 外设的任务交给 Linux 内核和 Qemu。

Libvirt

大家在网上看 KVM 相关文章的时候肯定经常会看到 Libvirt 这个东西。Libvirt 是啥?简单说就是 KVM 的管理工具。其实,Libvirt 除了能管理 KVM 这种 Hypervisor,还能管理 Xen,VirtualBox 等。

OpenStack 底层也使用 Libvirt,所以很有必要学习一下。

Libvirt 包含 3 个东西:后台 daemon 程序 libvirtd、API 库和命令行工具 virsh

libvirtd是服务程序,接收和处理 API 请求;      

API 库使得其他人可以开发基于 Libvirt 的高级工具,比如 virt-manager,这是个图形化的 KVM 管理工具,后面我们也会介绍;     

virsh 是我们经常要用的 KVM 命令行工具,后面会有使用的示例。   

作为 KVM 和 OpenStack 的实施人员,virsh 和 virt-manager 是一定要会用的

2、kvm实操

系统环境说明

[root@kvm ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@kvm ~]# uname -r
3.10.0-693.el7.x86_64
[root@kvm ~]# sestatus SELinux status:               
 disabled
[root@kvm ~]# systemctl status firewalld.service 
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[root@kvm ~]# hostname -I
172.16.1.240 10.0.0.240# kvm主机内存不能低于4GB

3、安装KVM虚拟化软件

安装依赖包(可以使用本地yum源)

yum install libvirt virt-install  qemu-kvm  -y
安装软件说明内容:
libvirt    # 虚拟机管理
virt       # 虚拟机安装克隆
qemu-kvm   # 管理虚拟机磁盘

启动服务

[root@kvm ~]# systemctl start libvirtd.service
[root@kvm ~]# systemctl status libvirtd.servic

安装VNC软件:

  下载vnc软件方法,tightvnc官网:http://www.tightvnc.com

  VNC软件,用于VNCVirtual Network Computing,为一种使用RFB协议的显示屏画面分享及远程操作软件。此软件借由网络,可发送键盘与鼠标的动作及即时的显示屏画面。

  VNC与操作系统无关,因此可跨平台使用,例如可用Windows连接到某Linux的电脑,反之亦同。甚至在没有安装客户端程序的电脑中,只要有支持JAVA的浏览器,也可使用。

  安装VNC时,使用默认安装即可,无需安装server端。

4、配置第一台KVM虚拟机

使用qemu命令创建一个10G的硬盘(最小10,G,可以更多),硬盘的名称为: CentOS-7-x86_64.raw

[root@kvm ~]# qemu-img create -f raw /opt/CentOS-7-x86_64.raw 10G
Formatting '/opt/CentOS-7-x86_64.raw', fmt=raw size=10737418240 
[root@kvm-node1 ~]# ll -h /opt
total 0
-rw-r--r-- 1 root root 10G Aug 22 07:59 CentOS-7-x86_64.raw

使用命令

[root@kvm ~]# virt-install --virt-type kvm --os-type=linux --os-variant rhel7 --name centos7 --memory 1024 --vcpus 1 --disk /data/clsn.raw,format=raw,size=10 --cdrom /data/CentOS-7-x86_64-DVD-1511.iso --network bridge=br0 --graphics vnc,listen=0.0.0.0,port=5900 --noautoconsole

备注:虚拟机镜像和新创建的逻辑磁盘尽量不要放在root目录下,在创建的时候会出现permission denied

参数

参数说明

--virt-type HV_TYPE

要使用的管理程序名称 (kvm, qemu, xen, ...)

--os-type

系统类型

--os-variant DISTRO_VARIANT

在客户机上安装的操作系统,例如:'fedora18'、'rhel6'、'winxp' 等。

-n NAME, --name NAME

客户机实例名称

--memory MEMORY

配置客户机虚拟内存大小

--vcpus VCPUS

配置客户机虚拟 CPU(vcpu) 数量。

--disk DISK

指定存储的各种选项。

-cdrom CDROM

光驱安装介质

-w NETWORK, --network NETWORK

配置客户机网络接口。

--graphics GRAPHICS

配置客户机显示设置。

虚拟化平台选项:

-v, --hvm

这个客户机应该是一个全虚拟化客户机

-p, --paravirt

这个客户机应该是一个半虚拟化客户机

--container

这个客户机应该是一个容器客户机

--virt-type HV_TYPE

要使用的管理程序名称 (kvm, qemu, xen, ...)

--arch ARCH

模拟 CPU 架构

--machine MACHINE

机器类型为仿真类型

其它选项:

--noautoconsole

不要自动尝试连接到客户端控制台

--autostart

主机启动时自动启动域。

--noreboot

安装完成后不启动客户机。

以上信息通过 " virt-install --help " 获得。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

注意:需要先将镜像文件拷贝到 /data/CentOS-7-x86_64-DVD-1511.iso 

使用参数说明:

   在启动的同时使用vnc连接

 下面就进入到安装系统的操作,关于系统安装的方法参考:http://www.cnblogs.com/clsn/p/7489784.html

5、KVM虚拟机管理操作

virsh命令常用参数总结

参数

参数说明

基础操作

list

查看虚拟机列表,列出域

start

启动虚拟机,开始一个(以前定义的)非活跃的域

shutdown

关闭虚拟机,关闭一个域

destroy(危险)

强制关闭虚拟机,销毁(停止)域

vncdisplay

查询虚拟机vnc端口号

配置管理操作

dumpxml

导出主机配置信息

undefine

删除主机

define

导入主机配置

domrename

对虚拟机进行重命名

挂起与恢复

suspend

挂起虚拟机

resume

恢复虚拟机

自启动管理

autostart

虚拟机开机启动

autostart --disable

取消虚拟机开机启动

以上参数通过  virsh  --help 获得。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

操作过程:

KVM虚拟机配置文件位置

[root@kvm ~]# ll /etc/libvirt/qemu/centos7.xml

修改KVM虚拟机配置的方法

[root@kvm ~]# virsh edit centos7

   使用该命令修改可以对文件进行语法校验。

备份与恢复

备份虚拟机配置(关机时备份):

[root@kvm ~]# virsh dumpxml centos7  > centos7.xml

删除虚拟机配置

# 查看
[root@kvm ~]# virsh list --all  Id    名称                         状态----------------------------------------------------
 -     centos7                        关闭
 # 删除
[root@kvm ~]# virsh undefine centos7 域 centos7 已经被取消定义
[root@kvm ~]# virsh list --all  Id    名称                         状态----------------------------------------------------

导入虚拟机

# 导入
[root@kvm ~]# virsh define centos7-o    ff.xml 
定义域 centos7(从 centos7-off.xml)# 查看
[root@kvm ~]# virsh list --all  Id    名称                         状态----------------------------------------------------
 -     centos7                        关闭

修改虚拟机名称

# 重命名
[root@kvm ~]# virsh domrename centos7 clsn7Domain successfully renamed# 查看
[root@kvm ~]# virsh list Id    名称                         状态----------------------------------------------------
 9     clsn7                          关闭

虚拟机挂起与恢复

# 挂起虚拟机
[root@kvm ~]# virsh suspend clsn7域 clsn7 被挂起# 查看状态
[root@kvm ~]# virsh list --all Id    名称                         状态----------------------------------------------------
 9     clsn7                          暂停
恢复虚拟机
[root@kvm ~]# virsh resume clsn7 
域 clsn7 被重新恢复

查询虚拟机vnc端口

[root@kvm ~]# virsh vncdisplay clsn7 
:0  # :0 即 为 5900 端口,以此类推 :1为5901 。

开机自启动设置

# 设置 libvirtd 服务开机自启动。
[root@kvm ~]# systemctl is-enabled libvirtd.service 
enabled

设置宿主机开机虚拟机在其他

[root@kvm ~]# virsh autostart clsn7 域 clsn7标记为自动开始# 实质为创建软连接
[root@kvm ~]# ll /etc/libvirt/qemu/autostart/clsn7.xml 
lrwxrwxrwx 1 root root 27 1月  22 12:17 /etc/libvirt/qemu/autostart/clsn7.xml -> /etc/libvirt/qemu/clsn7.xml
取消开机自启动
[root@kvm ~]# virsh autostart --disable clsn7 
域 clsn7取消标记为自动开始

 三、 kvm虚拟化原理

1、 CPU虚拟化

KVM 的虚拟化是需要 CPU 硬件支持的。还记得我们在前面的章节讲过用命令来查看 CPU 是否支持KVM虚拟化吗?

如果有输出 vmx 或者 svm,就说明当前的 CPU 支持 KVM。CPU 厂商 Intel 和 AMD 都支持虚拟化了,除非是非常老的 CPU。

一个 KVM 虚机在宿主机中其实是一个 qemu-kvm 进程,与其他 Linux 进程一样被调度。 比如在我的实验机上运行的虚机 kvm1 在宿主机中 ps 能看到相应的进程。

 

 

 虚机中的每一个虚拟 vCPU 则对应 qemu-kvm 进程中的一个线程。看下图

在这个例子中,宿主机有两个物理 CPU,上面起了两个虚机 VM1 和 VM2。 VM1 有两个 vCPU,VM2 有 4 个 vCPU。可以看到 VM1 和 VM2 分别有两个和 4 个线程在两个物理 CPU 上调度。

这里也演示了另一个知识点,即虚机的 vCPU 总数可以超过物理 CPU 数量,这个叫 CPU overcommit(超配)。 KVM 允许 overcommit,这个特性使得虚机能够充分利用宿主机的 CPU 资源,但前提是在同一时刻,不是所有的虚机都满负荷运行。 当然,如果每个虚机都很忙,反而会影响整体性能,所以在使用 overcommit 的时候,需要对虚机的负载情况有所了解,需要测试。

2、内存虚拟化

KVM 通过内存虚拟化共享物理系统内存,动态分配给虚拟机。看下图

为了在一台机器上运行多个虚拟机,KVM 需要实现 VA(虚拟内存) -> PA(物理内存) -> MA(机器内存)直接的地址转换。虚机OS 控制虚拟地址到客户内存物理地址的映射 (VA -> PA),但是虚机 OS 不能直接访问实际机器内存,因此 KVM 需要负责映射客户物理内存到实际机器内存 (PA -> MA)。具体的实现就不做过多介绍了,大家有兴趣可以查查资料。

还有一点提醒大家,内存也是可以 overcommit 的,即所有虚机的内存之和可以超过宿主机的物理内存。但使用时也需要充分测试,否则性能会受影响。

3、存储虚拟化

KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的。

Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种类型,后面会详细讨论。Volume 是在 Storage Pool 中划分出的一块空间,宿主机将 Volume 分配给虚拟机,Volume 在虚拟机中看到的就是一块硬盘。

下面我们学习不同类型的 Storage Pool

3.1 目录类型的 Storage Pool

文件目录是最常用的 Storage Pool 类型。
KVM 将宿主机目录 /var/lib/libvirt/images/ 作为默认的 Storage Pool。那么 Volume 是什么呢?
答案就是该目录下面的文件了,一个文件就是一个 Volume。

大家是否还记得我们之前创建第一个虚机 kvm1 的时候,就是将镜像文件 cirros-0.3.3-x8664-disk.img 放到了这个目录下。文件 cirros-0.3.3-x8664-disk.img 也就是Volume,对于 kvm1 来说,就是它的启动磁盘了。

 

 

 那 KVM 是怎么知道要把 /var/lib/libvirt/images 这个目录当做默认 Storage Pool 的呢? 实际上 KVM 所有可以使用的 Storage Pool 都定义在宿主机的 /etc/libvirt/storage 目录下,每个 Pool 一个 xml 文件,默认有一个 default.xml,其内容如下:

注意:Storage Pool 的类型是 “dir”,目录的路径就是 /data/centos7

下面我们为虚机 kvm1 添加一个新的磁盘,看看有什么变化。 在 virt-manager 中打开 kvm1 的配置页面,右键添加新硬件

在默认 Pool 中创建一个 8G 的卷。

点击 “Finish”,可以看到新磁盘的信息。

 

 

  

在 /var/lib/libvirt/images/ 下多了一个 8G 的文件 kvm1.img

root@ubuntu:~# ls -l /var/lib/libvirt/images/        
total 14044 -rw-r--r-- 1 root root   14417920 Sep  4 11:24 cirros-0.3.3-x86_64-disk.img -rw------- 1 root root 8589934592 Sep  4 21:39 kvm1.img

使用文件做 Volume 有很多优点:存储方便、移植性好、可复制、可远程访问。 前面几个优点都很好理解,这里对“可远程访问”多解释一下。

远程访问的意思是镜像文件不一定都放置到宿主机本地文件系统中,也可以存储在通过网络连接的远程文件系统,比如 NFS,或者是分布式文件系统中,比如 GlusterFS。

这样镜像文件就可以在多个宿主机之间共享,便于虚机在不同宿主机之间做 Live Migration;如果是分布式文件系统,多副本的特性还可以保证镜像文件的高可用。

KVM 支持多种 Volume 文件格式,在添加 Volume 时可以选择。

raw 是默认格式,即原始磁盘镜像格式,移植性好,性能好,但大小固定,不能节省磁盘空间。

qcow2 是推荐使用的格式,cow 表示 copy on write,能够节省磁盘空间,支持 AES 加密,支持 zlib 压缩,支持多快照,功能很多。

vmdk 是 VMWare 的虚拟磁盘格式,也就是说 VMWare 虚机可以直接在 KVM上 运行。

3.2 LVM 类型的 Storage Pool

不仅一个文件可以分配给客户机作为虚拟磁盘,宿主机上 VG 中的 LV 也可以作为虚拟磁盘分配给虚拟机使用。

不过,LV 由于没有磁盘的 MBR 引导记录,不能作为虚拟机的启动盘,只能作为数据盘使用。

这种配置下,宿主机上的 VG 就是一个 Storage Pool,VG 中的 LV 就是 Volume。 LV 的优点是有较好的性能;不足的地方是管理和移动性方面不如镜像文件,而且不能通过网络远程使用。

下面举个例子。

首先,在宿主机上创建了一个容量为 10G 的 VG,命名为 HostVG。

 

 

 然后创建了一个 Storage Pool 的定义文件 /etc/libvirt/storage/HostVG.xml,内容为

 

 

 然后通过 virsh 命令创建新的 Storage Pool “HostVG”

 

 

并启用这个 HostVG 

现在我们可以在 virt-manager 中为虚机 kvm1 添加 LV 的虚拟磁盘了。

点击 Browse

 

可以看到 HostVG 已经在 Stroage Pool 的列表中了,选择 HostVG

 

为 volume 命名为 newlv 并设置大小 100MB

 

点击 Finish,newlv 创建成功

 

点击 Choose Volume

 

点击 Finish 确认将 newlv 作为 volume 添加到 kvm1

 

新 volume 添加成功 在宿主机上则多了一个命名为newlv的LV

 

3.3 其他类型的Storage Pool

KVM 还支持 iSCSI,Ceph 等多种类型的 Storage Pool,这里就不一一介绍了,最常用的就是目录类型,其他类型可以参考文档 http://libvirt.org/storage.html

 

 

 

 4、网络虚拟化

网络虚拟化是虚拟化技术中最复杂的部分,学习难度最大。 但因为网络是虚拟化中非常重要的资源,所以再硬的骨头也必须要把它啃下来。

为了让大家对虚拟化网络的复杂程度有一个直观的认识,请看下图:

这是 OpenStack 官网上给出的计算节点(可以理解为 KVM 的宿主机)虚拟网络的逻辑图,上面的网络设备很多,层次也很复杂。

我第一次看到这张图,也着实被吓了一跳。

不过大家也不要怕,万丈高楼从地起,虚拟网络再复杂,也是由一些基础的组件构成的。只要我们将这些基础组件的概念和它们之间的逻辑关系搞清楚了,就能深刻理解虚拟网络的架构,那么云环境下的虚拟化网络也就不在话下了。

下面我们来学习网络虚拟化中最重要的两个东西:Linux Bridge 和 VLAN 。

 4.1  Linux Bridge 

假设宿主机有 1 块与外网连接的物理网卡 eth0,上面跑了 1 个虚机 VM1,现在有个问题是: 如何让 VM1 能够访问外网?

至少有两种方案

1. 将物理网卡eth0直接分配给VM1,但随之带来的问题很多: 宿主机就没有网卡,无法访问了; 新的虚机,比如 VM2 也没有网卡。 下面看推荐的方案

2. 给 VM1 分配一个虚拟网卡 vnet0,通过 Linux Bridge  br0 将 eth0 和 vnet0 连接起来,如下图所示

Linux Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备,其功能大家可以简单的理解为是一个二层交换机或者 Hub。多个网络设备可以连接到同一个 Linux Bridge,当某个设备收到数据包时,Linux Bridge 会将数据转发给其他设备。

在上面这个例子中,当有数据到达 eth0 时,br0 会将数据转发给 vnet0,这样 VM1 就能接收到来自外网的数据; 反过来,VM1 发送数据给 vnet0,br0 也会将数据转发到 eth0,从而实现了 VM1 与外网的通信。

现在我们增加一个虚机 VM2,如下图所示

VM2 的虚拟网卡 vnet1 也连接到了 br0 上。 现在 VM1 和 VM2 之间可以通信,同时 VM1 和 VM2 也都可以与外网通信。

有了上面的基础知识,下一节将演示如何在实验环境中实现这套虚拟网络。

本节将演示如何在实验环境中实现下图所示的虚拟网络

 

 

posted @ 2020-03-16 12:22  流年晕开时光  阅读(601)  评论(0编辑  收藏  举报