我们可以在改善虚拟机的隔离的同时拥有容器的高效吗?在这篇论文中,几位作者研究了基于Xen的虚拟机性能的边界。他们发现了启动大量轻量级虚拟机(包括unikernel和最小Linux虚拟机)时出现的瓶颈,并消除了瓶颈。因而获得的系统名为LightVM,并借助最小的unikernel镜像,可以在短短4ms内启动虚拟机。相比之下,Linux上的fork/exec则需要大约1ms。在同一个系统上,Docker容器启动需要大约150ms。 64核机器上LightVM的启动时间与Docker容器的启动时间 这些结果是在LightVM来宾(guest)是unikernel的情况下获得的。你可能只会在特殊情况下创建unikernel。(本文中一种颇有意思的例子是基于Micropython的unikernel,它可以用来支持serverless函数的执行)。几位作者还开发了一个名为TinyX的自动化构建系统,用于创建旨在运行单个应用程序的最小Linux虚拟机镜像。如果我们比较一下TinyX虚拟机和Docker的启动时间,性能非常接近于每个内核大约250个虚拟机/容器。 unikernel来宾、Tinyx来宾与Docker容器三者的启动时间 过了这个临界点,Docker开始比虚拟机略占上风,因为即使由TinyX创建的闲置的最小Linux发行版也确实运行一些偶尔的后台任务。 虚拟机数量增加后,Xen扩展起来如何?瓶颈在哪里? 如下图所示,限制虚拟化可伸缩性和性能的最大一个因素是来宾虚拟机的大小。为了制作该图,从ramdisk启动unikernel虚拟机,不同大小的二进制对象注入到未经过压缩的镜像文件。所以所有影响与镜像大小有关。 启动时间随虚拟机镜像的大小呈线性增加 所以,如果我们想要快速启动,我们知道镜像大小会很重要。我们之前在The Morning Paper上见过unikernel,它们提供最小的来宾镜像。在本文中,几位作者使用Mini-OS创建诸多unikernel,包括实现返回当前时间的一项TCP服务的“daytime”unikernel。大小是480KB(未经压缩),在3.6MB的内存中运行。这个unikernel用于测试潜在虚拟机的内存消耗的下限。 不过基于Mini-OS制作你自己的unikernel镜像需要较大的工作量,许多人可能没准备好,于是几位作者还构建了Tinyx。 Tinyx是一种自动化构建系统,可以创建旨在运行单个应用程序的最小Linux虚拟机镜像。实际上,该工具构建的虚拟机包含基于Linux的最小发行版以及经过优化的Linux内核。它在高度专业化的unikernel(拥有最佳性能,但需要将应用程序移植到一款最小操作系统)与功能完备的通用操作系统虚拟机(默认情况下支持大量应用程序,但是带来了性能开销)之间提供了一个中间点。 Tinyx创建的内核镜像大小只有典型Debian内核的一半,运行时耗用的内存却少得多(Tinyx仅要1.6MB,Debian需要8MB)。 使用因而获得的小巧虚拟机镜像,我们可以在启动大量虚拟机时探究Xen本身的行为。启动1000个来宾时,以下是Debian最小安装、Tinyx和MiniOS(unikernel)的启动和创建时间,并在同样硬件上进行了比较:Docker容器和简单的进程创建。 比较了几种来宾的域实例化和启动时间。如果是小巧来宾,实例化在启用新虚拟机时出现的延迟中占了大头 随着我们不断创建虚拟机,创建时间显著延长(注意对数尺度):创建第1000个Debian、Tinyx和unikernel来宾分别需要42s、10s和700ms。 虚拟机变小后,创建时间在获得可用性所需的总时间中占了更大的比重。为了了解所有时间用在那里,研究团队测量了Xen,得出了这张图片: 对虚拟机创建的开销细分后表明,与XenStore的交互和虚拟设备的创建是两大开销。 XenStore交互和设备创建占了大头。其中,设备创建的开销相当稳定,但是XenStore开销呈超线性增加。 LightVM的设计 我们的目标是让虚拟机启动时间与进程启动时间相当。Xen不是为这个目标而设计的,正如前面的结果显示的那样,这些问题的根源远非代码效率低下那么简单。比如说,XenStore的一个基本问题是类似文件系统的集中式API,它在虚拟机创建和引导过程中太慢了、无法使用,需要几十次中断和越过权限域(privilegedomain)。 我敢打赌,这种设计第一次搞出来时,很难想象有人启动1000个来宾虚拟机。 LightVM重新设计了Xen控制平面,使用一种名为noxs(意为“noXenStore”)的精简驱动程序来取代XenStore,并允许前端驱动程序和后端驱动程序之间通过共享内存来直接联系。 LightVM架构显示了noxs、x1的替代者(chaos)、splittoolstack及配套的守护进程以及负责迅速为软件交换机添加虚拟接口的xendevd LightVM还备有一批预先准备好的虚拟机外壳,通过这些外壳,所有虚拟机共有的所有处理都在后台完成。虚拟机创建命令发出后,一个符合该虚拟机需求的合适的外壳从这批外壳中取出,只需要完成最后的初始化步骤,比如将内核镜像加载到内存和完成设备的初始化。 标准Xen中的设备创建最后调用bash脚本,这是个缓慢的过程。LightVM换成了执行预定义设置的二进制守护程序,没有forking或bash脚本。 性能 我们在文章开头看到了有许多镜像的LightVM的启动时间。此外,LightVM可以在30ms内保存虚拟机,在20ms内恢复虚拟机。而标准Xen分别需要128ms和550ms。 unikernel的内存使用非常接近Docker容器,Tinyx需要更多内存,但面对1000个来宾只需要多22GB。这只是当前服务器内存容量的一小部分。 虚拟机的CPU使用情况也与容器相当,只要虚拟机经过简化,只包括必要的功能: unikernel、Tinyx、Debian虚拟机和Docker的CPU使用情况 使用场合 几位作者列出了LightVM +轻量级虚拟机大放异彩的四种不同的使用场合。 在所有下列场合下,使用容器将有助于提升性能,但会削弱隔离,而使用功能完备的虚拟机将提供与轻量级虚拟机同样的隔离,但性能较差。 1. 每个移动用户的个人防火墙在蜂窝基站或其附近的移动网关中运行(移动边缘计算, MEC)。这里使用了ClickOSunikernel镜像,8000个防火墙可在一台64核AMD机器上运行,启动时间为10ms。以这种方式在边缘运行LightVM的一台机器可以为蜂窝小区(cell)中的所有用户运行个性化防火墙,而不会成为瓶颈。 2. 移动边缘计算中的即时服务实例化(类似于JITSU)。 3. CDN处的高密度TLS终结,这需要内容提供商的长期秘密密钥。因此,不同内容提供商的代理之间的强隔离颇受欢迎。 4. 创建轻量级计算服务,比如AWS Lambda。就这个使用场合而言,研究人员使用基于Micropython的unikernel来运行用Python编写的计算。启动和开始执行一个函数需要大约1.3ms。如果有意给系统施加压力,发送测试系统处理能力之外的更多请求,服务时间呈线性上升,直到大约800个虚拟机才停止线性上升。 一台过载机器上的轻量级计算函数服务时间(Minipython unikernel) 我们介绍的使用场合表明,确实需要轻量级虚拟化,而且在获得良好隔离的同时,还能获得与容器同等或更好的性能。 谷歌云平台博客上最近出现了一篇文章:《揭秘基于容器的安全vs基于虚拟机的安全:明文安全性》(https://cloudplatform./2017/08/demystifying-container-vs-VM-based-security-security-in-plaintext.html)。该文从一家长期以来运行基于容器的基础设施的公司出发,阐述了容器安全和隔离方面一个值得关注的观点。 点击放大查看~ |
|