Fakecracker:NetBSD作为基于函数的微虚拟机

2020-06-19 01:58:49

2018年11月,AWS发布了名为Firecracker的开源工具,主要是依赖于KVM的虚拟机监视器、小型Linux内核和QEMU的精简版本。让我困惑的是虚拟机启动和运行服务的速度。整个过程被比作一个容器,但更安全,因为它不共享内核或任何资源,它是一个独立的专用虚拟机。如果你想了解更多关于“鞭炮”的内部结构,这里有一篇写得很好的文章。

我喜欢这个想法,我认为NetBSD将是这类目标的完美匹配,因为内核和整个操作系统可以很容易地剥离。我之所以知道这一点,是因为我在2016年编写了一个名为Sailor的想要成为集装箱的项目,目标是创建运行服务“Ala”docker的容器类型的chroot。我使用这个项目来满足我自己的需要,而你现在看到的这个网站实际上是在一艘水手船上运行的。

这很有趣,但是我们不能真的只用chroot来谈论安全性,而Fireracker解决方案似乎正好适合这一问题,但是整个NetBSD引导过程对我来说有点太长了。

那么,我们究竟如何才能显著提高NetBSD的引导速度呢?嗯,有两个主要的胜利:

第一点非常容易实现,下面是最小的内核配置:

包括";arch/i386/conf/std.i386";makeoptions Copts=";-os";makeoptions use_ssp=";no";maxuser 8#预计用户数选项CONSDEVNAME=";\";com\";";options cons_override options MULTIBOOT options RTC_Offset=0#硬件时钟是这么多分钟。GMT选项PIPE_SOCKETPAIR#较小,但速度较慢的管道(2)包括";conf/compat_netbsd60.config";文件系统FFS#UFS文件系统KERNFS#/kern选项FFS_NO_SNAPSHOT#无FF快照支持选项INET#IP+ICMP+TCP+UDP config netbsd root?类型?选项WSEMUL_VT100#VT100/VT220仿真选项WS_KERNEL_FG=WSCOL_GREEN选项WSDISPLAY_COMPAT_SYSCONS#在Mainbus上仿真一些ioctls选项PCDISPLAY_SOFTCURSOR PCI*?公交车?主总线上的isa0吗?pcdisplay 0 at isa?#CGA,MDA,EGA,HGA wsdisplay*at pcdisplay?控制台?在伊萨来吗?端口0x3f8 irq 4#标准PC串行端口cinclude";arch/i386/conf/GENERIC.local";伪设备fss#文件系统快照设备伪设备vnd#文件的类似磁盘的接口伪设备bpfilter#Berkeley包过滤器伪设备循环#网络环回伪设备tun#tty伪设备上的网络隧道pty#伪终端伪设备时钟clocktl#时钟子系统伪设备的用户控制。戴夫?Function?#virtio PCI device ld*at virtio?#virtio disk device vioif*at virtio?#Virtio network device。

请注意,我们绝对需要virtio驱动程序,因为VirtIO是在虚拟化环境中处理设备的最快方式。

关于第二点,这并不像看起来那么简单。内核必须能够突如其来地加载,即不需要引导加载程序。在NetBSD中,多亏了MULTIBOOT内核选项,这在i386端口上是可能的,不幸的是,到目前为止(2020年6月18日),AMD64端口不支持此选项(但仍在测试中)。因此,本文的其余部分将假设我们使用的是i386,这有点令人沮丧,但并不是真正的问题,因为几乎所有的软件包也都可用于此平台。

我不会讨论如何为交叉编译工具和内核准备环境,相反,这里有一个关于这个主题的非常好的教程。请注意,您可以在64位Linux系统上交叉编译i386NetBSD内核,这实际上就是我要做的。不过,您将需要一台i386NetBSD(可能是虚拟机)来创建用于我们要运行的服务的根磁盘。

tl;dr下面是我用来构建内核的命令(别忘了您必须首先构建工具!):

内核将询问根文件系统的位置,我们还不知道。按Ctrl+a x退出-nograph模式。

现在,关于要启动的真正服务,我们将设置一个nginx web服务器,该服务器将在没有rc.d框架的情况下启动,再次获得宝贵的毫秒时间。要创建根文件系统,我们将使用sailor。再说一次,我不会介绍水手的用法,因为文档已经说明了一切。

$cat示例/test.confship name=fakecrackershippath=";${home}/src/sailor/${ship name}";/bin/sh/sbin/init/usr/bin/printf/sbin/mount/sbin/mount_ff/bin/ls/sbin/mnowd/sbin/ifconfig/usr/bin/nc/usr/bin/ail"。run_at_build=";cd/dev&;&;sh MAKEDEV ALL_Md";

然后,我们创建一个自定义RC文件,该文件将在MicroVM调用init后进行解释:

$cat Ships/fakecracker/etc/rc#!/bin/shexport home=/export path=/sbin:/bin:/usr/sbin:/usr/binumask 022mount-aifconfig vioif0 192.168.2.101/24 upifconfig lo0 127.0.0.1 upprintf";\n启动nginx.。";/usr/pkg/sbin/nginxecho";Done";printf";\n测试Web服务器:\n";printf";head/HTTP/1.0\r\n\r\n";|nc-n 127.0.0.1 80echo ail-f/var/log/nginx/access.log。

更新我听说了makefs(8)实用程序,它使以下步骤变得更容易,而不是vndconfig/newfs/mount/rsync,只需使文件系统<;image-file>;<;directory>;(感谢mlelstv)。

卸载它,从块设备上解绑映像,然后将其复制到KVM主机: