My VM is Lighter (and Safer) than your Container

概述

这篇论文提出了一个基于Xen的Unikernel实现,并做了以下工作:

需求

作者主要关注以下几个指标:

影响虚拟机可扩展性和性能的最主要因素是虚拟机的大小。一个Linux实例需要几百MB到上GB的磁盘空间和内存。这同时也影响了启动时间,读取镜像并解析到内存所需的时间与镜像大小几乎是线性的。

作者通过以下几种方式完成这个目标:

Image

首先需要减小image大小和内存占用,由于大部分容器和虚拟机只跑单应用,所以可以把虚拟机削减到只保留对应用来说必要的功能。

有两种方法可以做到这一点:

Unikernel

用Mini-OS构建一个TCP服务器返回当前时间。最终镜像只有480KB,内存占用只需3.6MB。

但这种方法过于复杂,且需要极强的专业知识和能力。

Tinyx

Tinyx是一个运行特定应用的简约Linux虚拟机镜像的自动化构建系统。

Tinyx通过应用和虚拟机将要运行的平台来构建一个镜像,他分别构建文件系统和distribution。

Tinyx用以下两种方法来推断依赖:

Tinyx先挂载一个OverlayFS,然后在这个目录下安装之前推断的软件包。在这之后,删除所有的缓存文件和包管理器相关文件,卸载这个文件系统,并将其覆盖在BusyBox之上,然后获取合并之后的目录内容。最后,添加一些“胶水”来使得应用能从BusyBox运行。

为了构建内核,Tinyx从一个“tinyconfig”的Linux内核开始,根据目标Hypervisor添加一系列内置选项。

综合以上,最终可以创建相比Debian内核一半大小的内核。

Hyper

作者对Debian、Tinyx、MiniOS、Docker、Process的创建时间和启动时间做了一个对比,

前三者都随着运行实例数的增加而指数增长,同时,随着VM大小减小,实例创建时间占启动虚拟机时间的比例越来越大。

新VM的实例化成为了主要的瓶颈。

XenStore交互和设备创建贡献了主要的overhead。设备创建的overhead随实例数增长几乎为一常数。这主要是因为XenStroe是中心式的。

Toolstack

通过将Xen创建虚拟机时的工具栈进行分割,将其中类似于内存分配、CPU分配等较为相似的功能整合为后台进程,在平时准备多个VM槽位,当虚拟机创建发生时直接在槽位中分配。

将工具栈中比较具有特异性的步骤如解析配置文件、构建image等作为新的工具栈,当虚拟机启动时使用。

总结

最后作者确实也达到了容器级别的启动时间、实例密度等指标,虽然在内存占用中略逊容器一筹,但整体来说相当不错了。

另一方面,Unikernel之所以近几年没有进展,我觉得主要还是因为现有的Unikernel的泛用性太差,不能支持多种场景。

但另一方面,Unikernel之所以快就是因为其专用性,所以这两者似乎形成了一个矛盾。

在我看来,这可能主要还是因为没有找到Unikernel的主要使用场景,这使得Unikernel没有办法将其专用性和泛用性作统一,Severless可能是一种将来的使用场景。