虚拟化是云计算的基础。简单的说,虚拟化使得在一台物理的服务器上可以跑多台虚拟机,虚拟机共享物理机的 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。
在 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 是一定要会用的
系统环境说明
[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
安装依赖包(可以使用本地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软件,用于VNC(Virtual Network Computing),为一种使用RFB协议的显示屏画面分享及远程操作软件。此软件借由网络,可发送键盘与鼠标的动作及即时的显示屏画面。
VNC与操作系统无关,因此可跨平台使用,例如可用Windows连接到某Linux的电脑,反之亦同。甚至在没有安装客户端程序的电脑中,只要有支持JAVA的浏览器,也可使用。
安装VNC时,使用默认安装即可,无需安装server端。
使用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
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 的虚拟化是需要 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 的时候,需要对虚机的负载情况有所了解,需要测试。
KVM 通过内存虚拟化共享物理系统内存,动态分配给虚拟机。看下图
为了在一台机器上运行多个虚拟机,KVM 需要实现 VA(虚拟内存) -> PA(物理内存) -> MA(机器内存)直接的地址转换。虚机OS 控制虚拟地址到客户内存物理地址的映射 (VA -> PA),但是虚机 OS 不能直接访问实际机器内存,因此 KVM 需要负责映射客户物理内存到实际机器内存 (PA -> MA)。具体的实现就不做过多介绍了,大家有兴趣可以查查资料。
还有一点提醒大家,内存也是可以 overcommit 的,即所有虚机的内存之和可以超过宿主机的物理内存。但使用时也需要充分测试,否则性能会受影响。
KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的。
Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种类型,后面会详细讨论。Volume 是在 Storage Pool 中划分出的一块空间,宿主机将 Volume 分配给虚拟机,Volume 在虚拟机中看到的就是一块硬盘。
下面我们学习不同类型的 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上 运行。
不仅一个文件可以分配给客户机作为虚拟磁盘,宿主机上 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
KVM 还支持 iSCSI,Ceph 等多种类型的 Storage Pool,这里就不一一介绍了,最常用的就是目录类型,其他类型可以参考文档 http://libvirt.org/storage.html
网络虚拟化是虚拟化技术中最复杂的部分,学习难度最大。 但因为网络是虚拟化中非常重要的资源,所以再硬的骨头也必须要把它啃下来。
为了让大家对虚拟化网络的复杂程度有一个直观的认识,请看下图:
这是 OpenStack 官网上给出的计算节点(可以理解为 KVM 的宿主机)虚拟网络的逻辑图,上面的网络设备很多,层次也很复杂。
我第一次看到这张图,也着实被吓了一跳。
不过大家也不要怕,万丈高楼从地起,虚拟网络再复杂,也是由一些基础的组件构成的。只要我们将这些基础组件的概念和它们之间的逻辑关系搞清楚了,就能深刻理解虚拟网络的架构,那么云环境下的虚拟化网络也就不在话下了。
下面我们来学习网络虚拟化中最重要的两个东西:Linux Bridge 和 VLAN 。
假设宿主机有 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 也都可以与外网通信。
有了上面的基础知识,下一节将演示如何在实验环境中实现这套虚拟网络。
本节将演示如何在实验环境中实现下图所示的虚拟网络
原文:https://www.cnblogs.com/deny/p/12503021.html