nsdi22-Starlight-Fast Container Provisioning on the Edge and over the WAN

background

解决的核心问题:

container provisioning outside the cloud,比如在mobile and edge computing上,会受到network traffic的影响而变得很慢。渐进式的方法并不能解决这个问题。

starlight是一个用于container provisioning的加速器。通过重新设计容器部署协议、文件系统和image存储格式,将配置与开发脱钩。

开源,https://github.com/mc256/starlight

motivation

是什么导致optimizing provisioning difficult?

pull-based protocol(其实是registry的并发连接个数限制导致排队延时)

用户主动从registry去pull他们需要的层。当outside the cloud的时候会产生排队延时。因为registry的实现限制了每个client的并发连接个数在2-3。

eStargz[58]使用文件系统的文件访问跟踪来确定压缩层中的文件顺序,从而进一步加剧了排队情况。然而,在实践中,由于多线程和运行时的配置,容器工作负载的文件访问顺序并不是完全确定的。容器的启动因此而变慢,因为多个HTTP请求由于文件访问顺序混乱而在注册表中排队并相互延迟。

layer-based structure

container image是以a stack of independent layer的形式构造的。这让optimizing provisioning更加困难

  • Distributed Metadata
    • 每一层有自己的metadata(包括这一层有哪些文件),同时这个metadata还is intermingled with file contents
    • 再考虑一下eStargz:由于标准的容器图像缺乏文件元数据,eStargz在每一层的末尾都存储一个内容表(ToC)。不幸的是,压缩层的大小和ToC的确切开始都没有在图像元数据中编码。这又意味着每个图层至少有两个甚至三个HTTP请求:一个是确定其压缩图像文件的大小,另一个是在结束前的估计位置检索该图层的ToC,如果ToC比预期的大,则可能有第三个请求。
  • Layer vs. File Granularity
    • 改变文件内容或者改变metadata时需要我们首先把它从原来的只读层复制到顶部的读写层。这种复制浪费了很多资源
  • Limited Layer-reuse
    • 对stack里面的low-level的层改动会导致级联效应,也就是它上面的所有层都需要被更新

no explicit update support

在worker的生命周期中,我们会出于不同的原因多次部署容器:初始配置、软件更新、安全补丁等等。由于用户的流动性和边缘数据中心的有限资源,这种情况在边缘工作者上甚至更为常见(§2.1)。

这不仅导致了频繁的配置,也意味着worker的内容高度多样化:随着worker的更新和重新使用,本地存储中可用的容器镜像的版本也因worker而异。如上所述,这种更新是一个优化的机会,因为许多文件事实上并没有改变(§3.2)。

设计原则

有以下的设计原则

  • 尽早启动容器
  • 只向worker发送他们需要的东西
  • 基于push来避免昂贵的往返
  • 优先考虑工作者的性能而不是云

得到了以下的设计点

  • provisioning协议不应该resemble the stack-of-layer structure of container images。相反,它应该是基于push的,并以文件而不是层的粒度进行操作。文件的列表和顺序应该在多个层和容器中共同优化。
  • provisioning协议应该将文件元数据和内容干净地分开,并首先发送元数据。这允许Starlight通过挂载一个 "模拟 "文件系统提前启动容器,同时在后台下载内容。
  • 配置协议应该让工作者explicitly request updates,并指定他们在本地可以使用的内容。
  • 通过在registry附近放置一个代理来避免改变registry,这样我们就可以在不影响现有工作者的情况下改变provisioning协议。
  • proxy应该根据worker已经拥有的东西按需创建provisioning packages。这使得更新worker的效率更高,avoids inflating the registry with packages for every conceivable update,并将计算负担放在云上,因为那里更便宜(§2.1)。支持这一点需要为每个容器存储一个内容表和文件元数据。
  • 使用seekable的向后兼容的格式来存储压缩层,允许Starlight和传统的worker使用相同的压缩层文件和标准的registries,并避免膨胀的registry大小。
  • 使用标准的容器镜像来支持现有的构建、存储和服务容器的工具的大型生态系统。

delta bundle protocol

provisioning request包括了name和version of the requested container image

response包括两个部分:header和body,header中包括了requested container's filesystem的扁平化视图

proxy and directory database

尽管名字叫proxy,但它不仅仅是一个代理服务器或一个简单的桥梁。

它负责优化和建立发送给worker的delta bundle,以及收集和分析用于这种优化的文件系统痕迹。

snapshotter plugin

containerd snapshotter守护进程管理着容器文件系统的生命周期:从下载图像到跟踪容器挂载的文件系统的变化。我们利用基于快照器插件的设计[7],编写了一个快照器插件来支持Starlight的供应。图3显示了Starlight快照器插件的概况,它包括两个组件:下载器和元数据管理器。快照器还维护着StarlightFS的用户空间组件的状态--每个挂载的容器实例都有一个。

starlight filesystem

这个定制的文件系统有两个目标。首先,我们需要提前启动容器,只使用它们的SLM。第二,我们想在各层和图像之间重用文件内容。由于OverlayFS和其他文件系统不支持这两个特性,我们使用FUSE[33]来实现StarlightFS。

总结

  • 重新设计worker-cloud部署协议。首先发送所有文件元数据,允许容器在文件内容可用之前启动。它使用基于push的方法来避免昂贵的往返请求:worker可以指定他们已经存储的内容,所以我们只按照他们需要的顺序发送他们需要的文件。
  • 在worker端,我们使用一个新的文件系统,在元数据可用时立即挂载文件,使我们的自定义snapshotter插件能够快速启动容器,同时在后台下载文件内容。当一个容器打开一个内容待定的文件时,我们会阻止它,直到内容可用。
  • worker连接到云中的一个新的proxy组件,该组件实现了新的协议。proxy跨layer和container按需优化文件的列表和顺序,从而减少重复,使更新更快。该proxy与现有的基础设施透明地工作:压缩层存储在一个标准的registry中,传统的worker可以正常地连接到该registry。
  • 一个seekable的压缩层格式允许代理将单个压缩文件发送给worker,而不必先解压存储的层。这种格式的开销很低(平均为4.2%),并与现有的worker和registry向后兼容,因此没有必要以两种格式存储容器image。

文章正文