『看看论文』是一系列分析计算机和软件工程领域论文的文章,我们在这个系列的每一篇文章中都会阅读一篇来自 OSDI、SOSP 等顶会中的论文,这里不会事无巨细地介绍所有的细节,而是会筛选论文中的关键内容,如果你对相关的论文非常感兴趣,可以直接点击链接阅读原文。
本文要介绍的是 2020 年 NSDI 期刊中的论文 —— Firecracker: Lightweight Virtualization for Serverless Applications1,该论文实现的 Firecracker 能够在宿主机上提供轻量级的虚拟化支持。很多开发者在今天都会选择使用 Serverless 的容器和服务以为了减少系统的运维开销、提高硬件的资源利用并实现快速的扩缩容,然而 Serverless 的场景却对容器的隔离性、安全性以及性能都提出了更高的要求。
当利用相同的硬件为多个租户提供服务时,我们期望不同的工作负载可以在最小化额外开销的情况下保证安全和性能上的隔离。然而在过去很长一段时间内,大多数的观点都认为在强安全性和低延迟之间我们只能二选一。
图 1 - 安全性和低延迟
虚拟化技术可以提供较强的安全性但是会引入较大的额外开销,而容器技术与之相反,它提供了弱安全性保证以及较小的额外开销。在这种前提下,公有云和私有云都会根据需求做出了自己的选择:
- 公有云为了保证安全性会使用虚拟机,虽然额外开销较高,但是可以将成本都转嫁给用户;
- 私有云为了保证性能会使用容器技术,虽然容器之间的隔离性较差,但是面向的客户一般都是公司内的业务方,所以安全性一般不是首要考虑的问题,可以优先保证整体的性能;
不同租户之间的隔离性永远都是公有云首先要考虑的问题,租户之间存在一些资源的竞争有时还是可以接受的,但是没有客户能够接受花钱购买的服务可能受到其他租户的攻击。
图 2 - Firecracker
这篇文章介绍的 Firecracker2 是新的虚拟机监视程序(Virtual Machine Monitor、VMM),它可以同时提供强安全性保证和较低的额外开销,目前为 AWS 函数和计算引擎提供支持,支持数百万的工作负载和每个月数万亿的请求。
隔离性
Firecracker 可以为运行的工作负载提供良好的兼容性、性能、具有极低的额外开销并且可以在单个主机上支持上千个函数,但是这些都不是这篇文章要关注的重点,我们在这里展开介绍论文中提到的几种隔离机制。
图 3 - 隔离选项
Linux 容器、语言特定的隔离机制和虚拟化技术是今天比较常见的几种隔离选项,我们在这里花一些时间简单介绍它们三者的异同。
Linux 容器
Linux 的容器组合了内核的多种功能提供运维和安全上的隔离性,其中包括:
- 控制组(cgroups):提供 CPU、内存和其他资源限制;
- 命名空间(namespaces):为用户、进程标识符和网络接口等内核资源提供命名空间;
- 安全计算(seccomp-bpf):限制进程可以使用的系统调用和传入的参数;
- 更改根目录(chroot):提供隔离的文件系统;
容器往往依赖系统调用上的限制来保证安全性,很多容器的运行时都会在系统调用上做文章来保证安全性,例如 Google 的 gvisor 3就在用户空间模拟一些系统调用,这能明显地减少内核需要提供的能力。
语言特定隔离
另一个用于隔离工作负载的常用技术就是编程语言的虚拟机了,例如 Java 虚拟机(Java Virtual Machine、JVM)以及运行 Javascript 的 V8 引擎。这种通过牺牲灵活性和兼容性以获得安全性的方式在一些场景下还是比较适合的,Chrome 的底层引擎 Chromium 就为每个网站单独分配进程资源防止网站访问不相关的信息造成安全问题。
虚拟化技术
现代的虚拟化技术都会使用硬件提供的功能保证虚拟硬件、页表和操作系统内核的隔离性。虽然虚拟化技术能够解决安全性的问题,但是这个世界的问题很多都是按下葫芦浮起瓢,重量级的虚拟化技术也会带来下面的挑战:
- 部署密度低、额外开销大:虚拟机监控程序和独立运行的内核都会占用额外的 CPU 和内存资源从而限制单机能够部署的虚拟机上限;
- 启动时间长:虚拟机的启动时间也会影响它的使用体验,相信很多开发者都经历过运行虚拟机所需要的漫长等待时间,
感觉在本地的虚拟机启动时间仅次于 Jetbrains 全家桶; - 实现复杂、容易出错:虚拟化技术的实现往往异常复杂,虚拟机监控程序 QEMU 中包含 1,400,000 行代码并调用 270 个不同的系统调用4,我们很难保证如此庞大的代码仓库的可靠性;
图 4 - 虚拟化技术的挑战
Firecracker 选择更加安全的语言 Rust 并使用 50,000 行代码实现最小可用的虚拟机监控程序以替代 QEMU,新的 VMM 会与 Linux 的内核虚拟机(Kernel Virtual Machine、KVM)一起为不同的工作负载提供运行环境。
总结
Firecracker 作为虚拟机监控程序,它依赖 Linux 的内核虚拟机(KVM)提供最小的虚拟机 MicroVM,这主要因为 Linux 的组件提供了正确的功能、性能以及设计,绕过这些组件会带来巨大的实现成本,同时也会增加运维工程师理解新系统的成本并影响运维工作。
这篇论文详细地分析了 Firecracker 的性能,以启动时间为例,预先配置版本的启动时间在 100 ~ 150ms,而没有预先配置的 Firecracker 启动时间大约为 150 ~ 250ms;除了提供毫秒级别的启动时间之外,Firecracker 仅需要 3MB 的内存额外开销,这可以显著地提升单机的部署密度。虽然 Firecracker 在启动时间和额外开销上都有着不错的表现,但是它的 I/O 吞吐量与其他系统相比却差很多。
图 5 - I/O 吞吐量
值得注意的是,论文中提到 Firecracker 在测试环境中超售二十倍资源,在生产环境中超售十倍资源都没有带来任何问题。看起来 AWS 的函数引擎 Lambda 的确可以带来相当高的利润,果然想要赚钱就是要把一份资源当成十份甚至二十份来卖。
推荐阅读
Agache, Alexandru, et al. “Firecracker: Lightweight virtualization for serverless applications.” 17th {usenix} symposium on networked systems design and implementation ({nsdi} 20). 2020. ↩︎
Firecracker · Secure and fast microVMs for serverless computing. https://github.com/firecracker-microvm/firecracker ↩︎
gvisor · Application Kernel for Containers https://github.com/google/gvisor ↩︎
Chia-Che Tsai, Bhushan Jain, Nafees Ahmed Abdul, and Donald E. Porter. A study of modern linux api usage and compatibility: What to support when you’re supporting. In Proceedings of the Eleventh European Conference on Computer Systems, EuroSys ’16, pages 16:1–16:16, New York, NY, USA, 2016. ACM. URL: http://doi.acm.org/10.1145/2901318.2901341, doi:10.1145/2901318.2901341. ↩︎
转载申请
本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。
Go 语言设计与实现
各位读者朋友,很高兴大家通过本博客学习 Go 语言,感谢一路相伴! 《Go语言设计与实现》 的纸质版图书已经上架京东,本书目前已经四印,印数超过 10,000 册,有需要的朋友请点击 链接 或者下面的图片购买。