作者:
霍秉杰:KubeSphere 可观测性、边缘计算和 Serverless 团队负责人,Fluent Operator 和 OpenFunction 项目的创始人,还是多个可观测性开源项目包括 Kube-Events、Notification Manager 等的作者,热爱云原生技术,并贡献过 Keda、Prometheus Operator、Thanos、Loki 和 Falco 等知名开源项目。
王翼飞:青云科技资深软件工程师,负责开发和维护 OpenFunction 项目。专注于 Serverless 领域的研发,对 Knative、Dapr、Keda 等开源项目有深入的了解和实践经验。
来源:2023 上海 KubeCon 分享,公众号后台回复关键词
KubeCon-2023
即可获取 PPT 下载链接。
本文主要包括以下几个部分:
什么是 Serverless?加州大学伯克利分校在论文 《A Berkeley View on Serverless Computing》给出了明确定义:Serverless computing = FaaS + BaaS。
对于函数计算平台,函数是不可或缺的,即 FaaS 是主体。同时,FaaS 也需要和后端的 BaaS 服务产生联系,所以丰富的后端服务是函数的重要依托。
云厂商通常提供托管的函数计算(FaaS)和各类后端中间件服务,这样就会把开发者锁定在自己的云平台之上。
现阶段我们也看到,有一些公司因为云上的成本过高,想要下云或者从一个云迁移到另一个云也就是跨云迁移。如果其函数绑定在云的 BaaS 服务上,则不利于跨云的迁移。所以,跨云迁移之后如何去处理各个云厂商 BaaS 服务接口的差异,成了目前较大的挑战。
从另一个角度看,一个 FaaS 平台通常需要支持多种语言,也会利用到众多后端服务。举例来讲,5 种语言需要和 10 种后端服务对接,那么这样做就会有 5×10 即 50 种实现, 还是比较复杂的。
如何解决上述问题呢?我们可以引入 Dapr 来简化函数与众多后端服务的交互。
Dapr 是一个分布式应用的运行时,能够把分布式应用的能力抽象成一个个 Building Block。
举几个例子来讲,一般的分布式应用程序都有 service 之间的相互调用,所以会有一个 service 的 Building Block;通常也会有 publish、subscribe 这样的模式,所以也会有一个 publish and subscribe
的 Building Block;此外还会有一些输入输出,所以有一个 Binding Building Block;当然还有其他的,可参考上图。
这些 Building Block 会由一系列的 components 支撑,比如 PubSub Brokers 可以支持各种云上的 MQ、AWS sqs 或者一些开源的中间件如 Redis、Kafka;Bindings 也会支持一些云上的存储和开源组件如 Kafka、MySQL、Redis。
所以 Dapr 就能解决上文提到的问题。FaaS 平台的每一种语言,只需要和 Dapr 交互,Dapr 的 API 再和构成每一个 Building Block 的 component 交互,通过 Dapr 去处理与众多后端服务的交互,这样就把复杂度从 N × M 降为了 N × 1.
另外 Dapr 解耦了 FaaS 平台与各云厂商的 BaaS,做到了云厂商中立,解决了跨云迁移的问题。
OpenFunction 是青云科技在 2022 年初开源的,在 2022 年 4 月成为了 CNCF 的 Sandbox 项目。
上图是 OpenFunction 的架构图,总体分为:Build,Function,Serving 和 Events 几个部分。
EventBus 利用 Dapr 的能力解耦了 EventBus 与底层具体 Message Broker 的绑定,你可以对接各种各样的 MQ。
OpenFunction Gateway 是 OpenFunction 0.7.0 增加的新特性,是基于 Kubernetes Gateway API 来实现的。之所以选择 Kubernetes Gateway API,是因为其 CRD 和其下游实现是解耦的,用户可以选择自己喜欢的 Gateway 实现,比如 APISIX、Istio、Contour 等;另外 Kubernetes Gateway API 也提供了一些新的特性,比如 HTTP 流量的分发、跨 Namespace routing 功能。
在之前 OpenFunction 需要把流量转发到 Knative 的 Gateway,然后再路由到 Knative 的 Revision,链路比较长。有了 OpenFunction Gateway,可以直接把流量转发到 Knative 的 Revision。也就是说可以不再依赖 Knative 网络相关的组件,整个流量转发的链路也会变短。
通过 Knative Gateway 访问同步函数需指定⼀个由随机串组成的 service url,不可预测且对⽤户不友好。
通过 OpenFunction Gateway 访问同步函数,可通过函数名及 namespace ⽣成函数访问 url。另外还可以通过 Gateway 的 Service 加上 Function 的 namespace 和 name 来进行 path-based 的访问,也可以基于 OpenFunction Gateway 的 IP 加上 Host 相关的 Headers 来进行 host-based 访问。
如果我们想在集群外部访问集群内部的 Function,我们可以在 OpenFunction Gateway 上面配置 domain 相关的字段,配置成 magic DNS,这样我们就可以直接在集群外部通过域名来访问集群内部的 Function。
冷启动优化一直是 FaaS 平台的难点。
之前我们采用的是 Dapr sidecar 模式,但是会影响 Function 启动的时间。函数很小的情况下,Dapr sidecar 的 container 启动时间以及 Dapr plant 初始化所需要的时间,比 Function 启动时间更长。
我们设计了 Dapr Proxy 模式,就是让所有 Function 的 pod 共享一个 Dapr sidecar。如果我们将 Function 扩容到很大的值,副本数较多,那么 sidecar 也会造成大量的资源开销,采用这个模式将有效避免这种情况。
接下来我们还有一个基于 Pool 的冷启动优化的计划。上文中提到的 Proxy 模式,对 Function 启动时间的优化是有限的。所以我们考虑采用 Pool 的方式来优化冷启动。
引入一个预创建的 Pod Pool,在有调用请求时,可以根据请求的相关信息判断要调用哪个 Function,然后对这个 Function 的 code 热加载,将其变成针对某个 Function 的 Pod,后续的流量就可以直接进入到这个特定的 Function Pod,这个过程不需要 K8s Pod 调度创建等逻辑的参与,所以这个方式对冷启动的时间优化是非常显著的。
在 OpenFunction 1.0.0 中,我们支持 WasmEdge 作为 Wasm 运行时。WebAssembly 作为 FaaS 平台运行时,具有很多优势,比如启动时间短、镜像体积小、安全性比较高。另外 WasmEdge 对 HTTP 支持也比较好。
但是目前 Wasm Function 访问后端服务有一个问题,因为 WebAssembly 程序访问 API 是受限的,所以也需要通过 Dapr 提供相对统一的方式来完成对后端服务的访问。
目前 Dapr、Rust、SDK 以及 Dapr WasmEdge 等相关的项目,还不够成熟,所以我们暂时还没有集成。后续相关生态成熟之后,再进行集成。
下面介绍一个将 OpenFunction 用在自动驾驶领域的案例,来自 OpenFunction 的社区用户——驭势科技。
简单来讲,自动驾驶就是车端会上传很多传感器的数据到云端,云端再对这些数据进行处理。
上图是云端的架构图。举例来说,车端的 MQTT Broker 将云端的数据传到云端的 MQ 上,运维人员会创建多种异步函数和同步函数来处理这些数据。MQTT topic 的数据会由一个函数处理,其他数据由另外一个函数处理,处理完的数据分别存到了不同的后端服务里,因为业务比较多,所以可能是不同的团队去去实现的,那么就需要用不同的语言去实现。
驭势科技还有一个比较高阶的使用例子。
车端上传 MQTT 的数据,通过异步函数从 MQTT 的数据提取出 Metrics,再将其发送到 Prometheus 的 Pushgateway,这种方式相当于将车端的数据变成了 Metrics 再存储下来。
欢迎各位小伙伴参与社区!
同步函数:https://github.com/OpenFunction/samples/tree/main/functions/knative/with-output-binding
异步函数:https://github.com/OpenFunction/samples/tree/main/functions/async/bindings/kafka-input
Keda HTTP Engine: https://github.com/OpenFunction/OpenFunction/blob/main/config/samples/function-kedahttp-sample-serving.yaml
Wasm 函数: https://github.com/OpenFunction/samples/tree/main/functions/knative/wasmedge/http-server
Redis state store:
Serverless Applications:
本文由博客一文多发平台 OpenWrite 发布!