译者注: 本文篇幅较长,有助于了解 FaaS 和 OpenFaaS。作者分别从开发人员和运维人员的视角来了解 OpenFaaS,对了解新的技术是个很好的方式。

本文翻译自 Ivan Velichko 的 OpenFaaS - Run Containerized Functions On Your Own Terms。


长期以来,无服务器(serverless) 对我来说无非就是 AWS Lambda 的代名词。Lambda 提供了一种方便的途径,可以将任意代码附加到平台事件(云实例的状态变更、DynamoDB 记录的更新或新的 SNS 消息)中。但是,我时不时会想到某个逻辑,但其又没大到足以有自己的服务,同时有不适合任何现有服务的范围。因此,我经常将其放入函数中,以便日后使用 CLI 命令或者 HTTP 调用来调用它。

几年前,我来开了 AWS,自那以后,我一直怀念部署无服务器功能的便利性。因此,当我得知 OpenFaaS 项目时惊喜万分。它将在 Kubernetes 集群上部署函数变得简单,甚至仅需要 Containerd 就可以部署到虚拟机上。

有兴趣?那么继续!

无服务器与 FaaS

无服务器 已成为一个流行词,目前其实际含义扔不够清晰。

许多现代平台被视为 无服务器 平台。在 AWS Fargate 或 GCP Cloud Run 上部署容器化服务?无服务器!在 Heroku 上运行应用程序?也可能是无服务器的。

同时,我更喜欢将 FaaS 视为一种具体的设计模式。按照 FaaS 范式,可以部署代码片段(响应某些外部时间执行的函数)。这些函数与事件驱动程序中的回调类似,但是是运行在其他人的的服务器上。由于操作的是函数而不是服务器,顾名思义 FaaS 是无服务器的。

source

OpenFaaS 项目旨在将 Kubernetes 集群或者独立的虚拟机等低级基础设施转化为管理无服务器函数的高级平台。

站在开发人员的角度,这样一个平台看起来是真的无服务器的 -- 你只需要知道特定的 CLI/UI/API 来处理 函数 抽象。但站在运维的角度,需要了解 OpenFaaS 如何使用 服务器 来运行这些函数。

就我而言,我经常既是开发又是运维,下面我将尝试从二者展开说明。然而,我认为在评估 UX 时,我们应该明确区分它们。

开发人员眼中的 OpenFaaS

OpenFaaS 创建于 2016 年,现在网上也有大量的教程。这里不会重复介绍,但可以通过以下链接了解:

  • How to deploy OpenFaaS
  • Create Functions
  • Build Functions
  • Writing a Node.js function - step-by-step guide

相反,我将描述我所理解的 OpenFaaS。我希望有助于一些需要评估该技术是否解决其问题的人,以及那些希望更有效地使用该技术的人。

函数运行时

在进入正式编码之前,有必要了解下其未来的执行环境(又名运行时)。或者,简单说:

  • 如何启动函数
  • 如何组织 I/O 操作
  • 如何重置 / 终止函数
  • 如何隔离函数和调用

OpenFaaS 自带多个运行时模式,这些模式针对不同的场景定制。因此,不同的场景下上述问题的答案会略有不同。

OpenFaaS 函数在容器中运行,并且每个容器必须遵守简单的约定 :它作为监听在预设端口(默认为 8080)上的 HTTP 服务器,临时存储并且是无状态的。

然而,OpenFaaS 通过 函数 watchdog(译者注:watchdog 不做翻译)模式避免了用户编写此类服务器。函数 watchdog 是一种轻量级 HTTP 服务器,可以感知如何执行实际函数业务逻辑。因此,安装在容器中的所有内容加上作为入口点的 watchdog,就构成了函数的运行时环境。

经典 watchdog

最简单的开始,或者又是被称为经典 watchdog:

这种模式下,watchdog 启动了监听在 8080 端口的轻量级 HTTP 服务器,每个进来的请求都会:

  • 读取请求头和请求体
  • fork 或者 exec 包含实际函数的可执行文件
  • 将请求头和请求体写入到函数进程的 stdin
  • 等待函数进程的退出(或者超市)
  • 读取函数进程的 stdoutstderr
  • 在 HTTP 响应中将去读的字节发送回调用方

上述逻辑类似于传统的 通用网关接口(CGI)。一方面,每次函数调用都启动单独的进程看起来不够高效,而另一方面,它确实超级方便,因为 任何使用 stdio 流进行 I/O 处理的程序(包括最喜欢的 CLI 工具)都可以部署为 OpenFaaS 函数

提起隔离,我们有必要区分下函数调用

  • OpenFaaS 中的不同函数始终分布在不同的容器中
  • 一个函数可以有一个或多个容器 —— 取决于缩放选项
  • 同一函数的独立调用可能会最终进入同一个容器
  • 同一函数的独立调用将始终使用不同的进程进行

反向代理 watchdog

注意:使用 OpenFaaS 官方术语,本节讨论在 HTTP 模式下运行的 of-watchdog。但我个人认为称之为反向代理 watchdog 更加形象。

如果 经典 运行时类似于 CGI,那么这个运行时模式类似于后来的 FastCGI。运行时希望在 watchdog 后面有一个长期运行的 HTTP 服务器,而不是每次函数调用时创建新的进程。这本质上是 将 watchdog 组件变成反向代理:

当容器启动时,反向代理 watchdog 也会创建一个监听在 8080 端口的轻量级 HTTP 服务器。然而,与 经典 watchdog 不同的是反向代理watchdog 只创建一次函数的进程,并将其当成(长期运行的)上游服务器。然后,函数调用转变成到该上游的 HTTP 请求。

然而,反向代理模式并不为了取代经典模式。经典模式的强项在于其函数的编写非常简单。这也是没有 HTTP 服务器的代码的唯一选择。比如使用 Cobol、bash 或者 PowerShell 脚本等等编写的函数。

何时该使用反向代理运行时模式: