虚拟化基础

基础知识

模拟 (Emulation)

在现有硬件平台之上,使用纯软件方式实现,虚拟出另一套硬件架构 + 操作系统的运行环境。

我们看到的各种游戏机模拟器,还有为开发CPU做仿真而做的模拟程序,就是早期比较常见的虚拟化解决方案。它的工作原理很简单:把CPU的所有寄存器都写在一组变量中(这组变量我们称为CPUFile),然后用一片内存当作被模拟CPU的内存(这片内存这里称为vMEM),然后在用一些数据结构表示IO设备的状态(这里称为vIO),三者的数据结构综合在一起,就是代表一个虚拟化的环境了(这里称之为VM),之后按顺序读出一条条的指令,根据这个指令的语义,更改VM的数据结构的状态(如果模拟了硬件,还要模拟硬件的行为,比如发现显存被写了一个值,可以在虚拟屏幕上显示一个点等),这样,实施虚拟的那个程序就相当于给被虚拟的程序模拟了一台计算机,这种技术,我称它为“解释型虚拟化技术”。指令是被一条一条解释执行的。解释型虚拟化技术很简单,直接,概念也容易理解,但很明显,这个效率是很低的。

虚拟化简史

虚拟化简史

CPU protection ring

X86平台的CPU为了提供更好的安全性和隔离性,在设计上有4个运行级别,分别是Ring 0 到 Ring 3
Ring 0 权限最高,通常被用来运行操作系统内核并直接与硬件交互(CPU,Memory等)
Ring 1 & Ring 2 设计上供驱动程序使用,但多数操作系统不使用该级别
Ring 3 通常用来运行用户空间应用程序(非特权指令,如普通的加减运算等)

X86 平台在虚拟化方面的一个难点就是如何将虚拟机越级的指令使用进行隔离

Intel-VT (Virtualization Technology)

VT是Intel CPU支持虚拟化的指令集。VT可以同时提升虚拟化效率和虚拟机的安全性,在x86平台上的VT技术,一般称之为VT-x,而在Itanium平台上的VT技术,被称之为VT-i。

VT-x增加了两种操作模式:VMX root operation(也被称为Ring -1)和VMX non-root operation(Ring 0)。VMM运行在VMX root operation模式,虚拟机运行在VMX non-root operation模式。

I/O虚拟化

  • 模拟 :把文件模拟成虚拟磁盘
  • 半虚拟化:虚拟机直接与hypervisor交互,完成I/O操作
  • I/O透传 :提供单独的硬件给虚拟机使用

虚拟化的优点

  • 是提高单机的应用密度,重复利用硬件资源(CPU, 内存, 网络),降低成本(硬件,电费)
  • 提供单一、隔离的环境,减少应用冲突,方便部署,管理

虚拟化的种类

全虚拟化 (Full-Virtualization)

全虚拟化的主要特征是:Guest不知道你自己是被模拟的系统

这种虚拟化技术更清晰的描述应该为:基于二进制翻译的全虚拟化(Full Virtualization with Binary Translation)

当Guest使用到特权指令的时候,虚拟化管理器(VMM)对虚拟机指令的使用进行捕获和翻译。

全虚拟化架构图

全虚拟化架构图

这种全虚拟化的产品有:VMware Workstation,QEMU,Virtual PC

优点&适合场景

  • 虚拟机的隔离比较彻底,安全性要优于容器
  • 虚拟机的适合部署长期保留的应用或者服务
  • 为了提供更好的隔离性和安全性,有些企业选贼在虚拟机中部署Docker

半虚拟化 (Para-Virtualization)

半虚拟化的主要特征是:Guest知道自己是运行在Hypervisor上的虚拟系统,通过直接和Hypervisor交互来完成I/O操作

半虚拟化技术通过修改操作系统内核,替换掉不能虚拟化的指令,并使用hypercall直接和底层的hypervisor来通讯,hypervisor 同时也提供了超级调用接口来满足其他关键内核操作,比如内存管理、中断和时间保持。这种做法省去了全虚拟化中的捕获、翻译、和模拟的过程,从而大大提高了效率。

容器虚拟化 (Container)

容器虚拟化也可以理解为应用程序虚拟化,原理是基于CGroups、Namespace等技术将进程隔离。

容器为应用程序提供了隔离的运行空间:每个容器内都包含一个独享的完整用户环境空间,并且一个容器内的变动不会影响其他容器的运行环境。为了能达到这种效果,容器技术使用了一系列的系统级别的机制诸如利用Linux namespaces来进行空间隔离,通过文件系统的挂载点来决定容器可以访问哪些文件,通过cgroups来确定每个容器可以利用多少资源。此外容器之间共享同一个系统内核,这样当同一个库被多个容器使用时,内存的使用效率会得到提升。

每个进程就像一台单独的虚拟机一样,有自己被隔离出来的资源,也有自己的根目录、独立的进程编号、被隔离的内存空间。

容器虚拟化方案的特点是,只有一个OS,但是有多个container。每个container可以部署不同的OS+ Service,可以分配单独IP,可以配置单独主机名,可以有独立的文件系统(文件系统这部分,可以想象一下chroot)。当你ssh进去这样一个系统时,你可能看见了一个完整的进程树,有PID为0的进程,等等。

目前最热的容器虚拟化技术就是Docker。Docker的优势是可以将一个开发环境进行打包,很方便地在另外一个系统上运行起来。

另一种Container方案是OpenVZ,网上常见的所谓VPS,就是OpenVZ部署的,它甚至不是一台虚拟机。

如果你只是希望将应用运行的实例进行隔离,那么对于管理应用运行环境、启动应用实例以及控制资源开销方面容器将是一个极为高效的工具。

硬件辅助的全虚拟化

硬件辅助虚拟化技术,在处理器中加入了新的特权级来运行虚拟机监控层(Hypervisor),使得客户机操作系统可以运行在原始特权级,不需要更改,并且由硬件来完成两个特权级之间的转换。硬件辅助虚拟技术提高了虚拟机的兼容性和性能。

这样全虚拟化下,那些靠“捕获异常-翻译-模拟”的实现就不需要了,靠硬件辅助的全虚拟化技术的性能逐渐逼近半虚拟化

硬件辅助的全虚拟化的产品有:KVM,Hyper-V,VMware ESXi

虚拟化解决方案

虚拟化技术是大数据和云计算应用中的核心技术,经过几年的友展,KVM已经非常成熟和稳定,逐渐取代Xen等商业虚拟化技术和产品,成为该领域事实上的标准。

目前常见的企业级的虚拟化产品有4款:分别是VMware、HyperV、Xen、KVM

Xen

  • Xen是基于X86架构开发的 Hypervisor

  • Xen能实现半虚拟化和全虚拟化方案

  • Xen和Domain 0需要同时安装部署
  • Xen的半虚拟化对Hypervisor和虚拟机的Linux版本有一致性的要求,两者最好使用同样的Linux内核甚至是同样的发行版
  • Xen的半虚拟化需要通过修改Linux内核,使虚拟机自己对特殊的指令进行更改,然后和虚拟化层一起配合工作。
  • Xen的全虚拟化需要使用支持硬件虚拟化的CPU
  • RHEL6以后,不能部署为Dom 0,但能部署为Dom U

KVM

Kernel-based Virtual Machine

  • 在2007年被正式合并到Linux 2.6.20核心中
  • 一般需要运行在64位平台上
  • 只能运行在支持Intel VT 或 AMD-V 虚拟化技术的CPU之上
  • 不需要修改系统内核
  • KVM只是一个内核的模块,没有用户空间的管理工具,KVM的虚拟机可以借助QEMU的管理工具来管理

KVM比较年轻,所以出生的时候就吸取了其他虚拟化技术的优点,一开始就支持硬件虚拟化技术,没有历史兼容包袱。所以KVM推出来的时候,性能就非常优异。目前,KVM是OpenStack平台上首选的虚拟化引擎。KVM已经成为开源解决方案的主流选择。

2015年,虚拟主机供应商Linode宣布它正从Xen过渡到KVM,它声称切换到KVM大幅提升了性能。Linode之前是在2008年从User-mode Linux(UML)切换到Xen虚拟化。测试显示,KVM的得分是Xen的三倍。

Docker

Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。通过分层镜像标准化和内核虚拟化技术,Docker使得应用开发者和运维工程师可以以统一的方式跨平台发布应用,并且以几乎没有额外开销的情况下提供资源隔离的应用运行环境。

Docker系统有两个程序:docker服务端和docker客户端。其中docker服务端是一个服务进程,管理着所有的容器。docker客户端则扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。大部分情况下,docker服务端和客户端运行在一台机器上。

扩展阅读

《深度实践KVM》
【第一章】(http://images.china-pub.com/ebook4790001-4795000/4794120/ch01.pdf
【第二章】(http://images.china-pub.com/ebook4790001-4795000/4794120/ch02.pdf)
【第三章】(http://images.china-pub.com/ebook4790001-4795000/4794120/ch03.pdf)

虚拟化 VS 容器化

RedHat官方虚拟化技术文档

https://www.zhihu.com/question/24123210/answers/created