4.1 函数运行时设计目标
FaaS函数运行时是在基于Nomad的边缘计算平台引入函数计算的基础,如前文所述,本文无服务器计算虚拟化构建在容器虚拟化之上。FaaS函数运行时的设计覆盖函数计算的三要素,即函数计算的构建、函数或服务定义、事件源与管理事件源如何触发函数计算的规则。设计上,尽可能在不更改Nomad现有接口或工具的情况下实现函数运行时的管理功能,故采用其上的容器工作负载。
Knative和OpenFaaS都代表着Serverless 2.0,即无厂商绑定的Serverless。由于Knative是基于云计算事实上的标准Kubernetes的,但Knative在Kubernetes和Istio众多的概念之上,又有一层抽象。这层抽象也适用于多数Serverless产品,对本文基于Nomad的边缘计算平台实现的FaaS函数运行时也具有参考和指导意义。Knative将Serverless组件分为Build、Eventing和Serving。其中Knative Build已被弃用,取而代之的是Tekton Pipeline,Eventing事件组件用于事件的管理与分发,Serving服务组件用于请求驱动的计算。
根据前述FaaS运行时选型,本文基于OpenFaaS实现基于Nomad的边缘计算平台的FaaS函数运行时,列出如下FaaS函数运行时基本功能的设计目标:
l 函数构建框架,从函数源码到构建函数镜像,以及函数模板。
l 支持事件框架。
l 管理函数(也可以粗粒度的理解为应用),创建函数、查询函数、删除函数、获取指定的函数。
l 部署函数,基于Nomad作为编排管理器部署函数,设置函数的副本数。
l 调用函数,让用户可以通过FaaS API网关调用函数,包括同步函数调用和异步函数调用。
l 自动扩缩容,以及缩容到零。
l 函数预热,从零扩容到1。
l 函数工作流程,对函数间组合关系的编排。
有关基于FaaS函数运行时整合开源项目提供函数计算服务的方案详见第六章。
4.1.1 OpenFaaS技术分析
OpenFaaS是一个构建无服务器函数的框架,架构如图4.1所示。OpenFaaS支持多种容器运行时编排器,官方支持Kubernetes和Swarm,另外社区提供了接入接口,通过实现faas-provider可以接入其他编排器,如本文FaaS-Nomad-Provider的实现。API网关(API Gateway)为函数提供外部路由,进行统一的认证,并通过Prometheus收集指标。本文在其API网关上进行定制FaaS-API-Gateway。函数监视器(Function Watchdog)是OpenFaaS的监控组件,负责启动和监控OpenFaaS的函数。OpenFaaS提供的函数构建框架是任何二进制文件都可以通过使用Watchdog变成一个函数,函数镜像构建为OCI镜像规范格式,容器运行时为Docker。
图4.1 OpenFaaS架构图
OpenFaaS支持任何语言,官方及社区提供的函数构建模板支持的语言包括了dockerfile、java、csharp、golang、python、node、ruby、php、rust、powershell、swift、lua、perl等,以及arm和x86_64架构。由于函数是通过打包成OCI镜像发布的,也保证和OpenFaaS和Knative的互操作性。此外,社区开放支持自定义语言、框架、惯用方式的函数模板。
1)API网关
OpenFaaS将FaaS运行时分成API网关、Provider接口和具体实现的Provider三个部分。API网关并不具体负载某项功能,仅起到一个基础转发、安全认证的功能。API网关有一个内置的UI,可以从函数商店部署函数、调用函数。如图4.2所示,客户端向API网关发送的操作函数的请求,实际上是转发给具体的faas-provider实现调用编排器的API完成的。外部系统对OpenFaaS的依赖,松散耦合,通过通用的HTTP协议REST接口与API网关通信。
图4.2 faas-provider示意图
2)Provider接口
faas-provider是社区开放生态提供的接口,faas-provider抽象编排器的实现细节,封装的接口有:
l 查询/创建/删除函数
l 获取指定的函数
l 设置函数副本数
l 调用函数
抽象出的Provider了解如何执行函数CRUD、伸缩和调用的知识。遵循Provider模型,任何容器编配器或其他系统都可以作为接入对象。网关组件无需被具体编排器相关的客户端依赖撑得臃肿起来,而只作为配置选项(如验证、跟踪和度量等)的中间件,这意味着可以更紧密地遵循单一责任的原则。
由API网关请求转发来的调用请求是通过Provider具体完成,Provider会转发给函数监视器,由函数监视器启动函数进程,如图4.3所示。函数监视器是无服务器函数的一个垫片,提供健康检查、优雅关闭、超时和一致的日志输出体验。OpenFaaS提供的Watchdog实现相当于一个“init进程”,为每个请求新建一个Forked进程,在官方所有的函数模板中使用。
图4.3 Provider调用函数
基于以上架构分析,本文认为OpenFaaS的框架比较简单明了,松散耦合,易于扩展和二次开发。