裂变:无服务器功能作为Kubernetes的服务

编者注:今天的帖子是Platform9 Systems的软件工程师Soam Vasani谈论的是一种新的面向Kubernetes的开源无服务器功能(FaaS)框架。 

裂变 是基于Kubernetes构建的功能即服务(FaaS)/无服务器功能框架。

裂变允许您通过功能轻松在Kubernetes上创建HTTP服务。它在源代码级别工作,并抽象出容器图像(在大多数情况下)。通过使您无需了解Kubernetes就能提供有用的服务,还可以简化Kubernetes的学习过程。

要使用Fission,您只需创建函数并使用CLI添加它们即可。您可以将功能与HTTP路由,Kubernetes事件或其他触发器关联。 裂变今天支持NodeJS和Python。

函数在触发触发器时被调用,并且仅在运行时消耗CPU和内存。空闲功能不会消耗存储以外的任何资源。

为什么要在Kubernetes上建立FaaS框架?

我们认为需要一种可以在公共云和本地基础结构中的各种基础结构上运行的FaaS框架。接下来,我们必须决定是从头开始还是在现有编排系统之上构建它。很快很明显,我们不应该从头开始构建它-我们最终将不得不重新发明集群管理,调度,网络管理等等。

Kubernetes提供了一个强大而灵活的编排系统,并带有一个强大且不断发展的社区支持的综合API。在此基础上进行构建意味着Fission可以将容器编排功能留给Kubernetes,并专注于FaaS功能。

我们不希望使用单独的FaaS集群的另一个原因是FaaS与其他基础架构结合使用时效果最佳。例如,它可能适合小型REST API,但需要与其他服务一起使用以存储状态。 FaaS还可以用作事件处理程序的机制,以处理来自存储,数据库和Kubernetes本身的通知。 Kubernetes是所有这些服务都可以互操作的绝佳平台。

部署和使用裂变

裂变 can be installed with a kubectl create command: see the 项目自述文件 有关说明。

这是您编写“ Hello World” HTTP服务的方法:

$ cat \> hello.py

def main(context):

    print "Hello, world!"


$ fission function create --name hello --env python --code hello.py --route /hello


$ curl http://\<fission router\>/hello

Hello, world!

裂变负责将函数加载到容器中,将请求路由到它,等等。我们将在下一节中详细介绍。

如何在Kubernetes上实现裂变

FaaS框架的核心必须(1)将功能转变为服务,以及(2)管理这些服务的生命周期。

有多种方法可以实现这些目标,每种方法都有不同的权衡。框架应该在源代码级别还是在Docker映像级别(或介于两者之间的某些级别,例如“ buildpacks”)运行?第一次运行函数时可接受的开销是多少?此处所做的选择会影响平台的灵活性,易用性,资源使用和成本以及过程,性能。 

包装,源代码和图像

我们的目标之一是使Fission非常易于新用户使用。我们选择经营
在源代码级别上,以便用户可以避免处理容器映像的构建,将映像推送到注册表,管理注册表凭据,映像版本控制等。

但是,容器映像是打包应用程序的最灵活的方法。例如,纯粹的源代码级接口不允许用户打包二进制依赖项。

因此,Fission采用了一种混合方法-包含用于功能的动态加载程序的容器映像。这种方法允许大多数用户纯粹在源代码级别使用Fission,但是使他们能够在需要时自定义容器映像。

这些映像在Fission中称为“环境映像”,包含该语言的运行时(例如NodeJS或Python),一组常用的依赖项以及函数的动态加载程序。如果这些依赖关系足以满足用户正在编写的功能,则无需重建图像。否则,可以修改依赖项列表,并重建映像。

这些环境图像是Fission唯一特定于语言的部分。它们为框架的其余部分提供了统一的界面。这种设计使Fission可以轻松扩展到更多语言。

冷启动性能

无服务器功能的目标之一是这些功能仅在运行时才使用CPU /内存资源。这优化了功能的资源成本,但是以从空闲状态开始时的一些性能开销(“冷启动”开销)为代价。

在许多用例中,冷启动开销很重要。特别是,在交互式用例中使用的功能(例如,Web或移动应用程序,其中用户正在等待操作完成),几秒钟的冷启动等待时间将是不可接受的。

为了优化冷启动开销,Fission为每个环境保留了一个运行中的容器池。当收到功能请求时,Fission不必部署新的容器-只需选择一个已经运行的容器,将功能复制到容器中,然后动态加载它,然后将请求路由到该实例。对于NodeJS和Python函数,此过程的开销大约为100毫秒。

裂变如何在Kubernetes上工作

fission-arch.png裂变被设计为一组微服务。控制器跟踪功能,HTTP
路线,事件触发器和环境图片。池管理器管理空闲环境容器的池,将功能加载到这些容器中以及在空闲时杀死功能实例。路由器接收HTTP请求并将其路由到功能实例,如有必要,请从池管理器中请求一个实例。

控制器提供裂变API。所有其他组件都在监视控制器的更新。根据托管Kubernetes群集的位置,路由器将以LoadBalancer或NodePort类型的Kubernetes服务公开。

当路由器收到请求时,它会查找缓存以查看此请求是否已具有应路由到的服务。如果不是,它将查找将请求映射到的函数,并向实例请求poolmgr。 poolmgr有一个空闲的pod池;它选择一个,将功能加载到其中(通过向Pod中的sidecar容器发送请求),然后将Pod的地址返回给路由器。路由器将请求代理到此Pod。该Pod被缓存以供后续请求使用,如果空闲了几分钟,它将被杀死。

(目前,Fission将一个功能映射到一个容器;计划在以后的发行版中自动缩放到多个实例。对于不需要隔离的情况,还计划重新使用功能容器来托管多个功能。)

裂变用例

机器人,Webhooks,REST API 
裂变是创建小型REST API,实现Webhooks以及为Slack或其他服务编写聊天机器人的好框架。

作为一个简单的REST API的示例,我们制作了一个小型留言簿应用程序,该应用程序使用用于读取和写入留言簿的功能,并与redis实例配合使用以跟踪状态。您可以找到该应用 在Fission 的GitHub存储库中.

该应用程序包含两个端点-GET端点列出了redis的留言簿条目,并将其呈现为HTML。 POST端点在redis中将新条目添加到留言簿列表中。就是所有-没有Dockerfile可以管理,并且更新应用程序就像调用裂变函数更新一样简单。 

处理Kubernetes事件
裂变还支持基于Kubernetes手表的触发功能。例如,您可以设置一个函数来监视与特定标签匹配的特定命名空间中的所有pod。函数在其上下文中获取序列化对象和监视事件类型(添加/删除/更新)。

这些事件处理程序功能可用于简单监视-例如,每当将新服务添加到群集时,您都可以发送松弛消息。还有更复杂的用例,例如通过观看Kubernetes的第三方资源来编写自定义控制器。

现状和路线图

裂变目前处于早期阶段(2017年1月)。尚未准备好用于生产。我们正在寻找早期采用者和反馈。

裂变的前景如何?我们正在努力使Kubernetes上的FaaS更加方便,易于使用并且易于集成。在接下来的几个月中,我们正在努力增加对单元测试,与Git集成,功能监视和日志聚合的支持。我们还在与其他事件源进行集成。

创建更多的语言环境也在努力之中。今天支持NodeJS和Python。 Klavs Madsen提供了对C#.NET的初步支持。

您可以在GitHub上找到我们当前的路线图 问题专案.

参与其中

裂变是开源的,由 Platform9系统。检查我们 的GitHub,如果您想与我们聊天,请加入我们的闲暇频道。我们也在Twitter上 @fissionio.

-Soam Vasani,Platform9 Systems软件工程师