这篇文章已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Fission:Kubernetes 的无服务器函数即服务
Fission 是一个构建在 Kubernetes 上的函数即服务 (FaaS) / 无服务器函数框架。
Fission 允许您轻松地从函数在 Kubernetes 上创建 HTTP 服务。它在源代码级别工作,并抽象出容器镜像(在大多数情况下)。它还简化了 Kubernetes 的学习曲线,使您能够在不了解太多 Kubernetes 的情况下创建有用的服务。
要使用 Fission,您只需创建函数并使用 CLI 添加它们。您可以将函数与 HTTP 路由、Kubernetes 事件或其他触发器关联。Fission 目前支持 NodeJS 和 Python。
当触发器触发时,会调用函数,并且它们仅在运行时才消耗 CPU 和内存。空闲函数不消耗任何资源,除了存储。
为什么要在 Kubernetes 上创建一个 FaaS 框架?
我们认为需要一个可以在各种基础设施(包括公共云和本地基础设施)上运行的 FaaS 框架。接下来,我们必须决定是从头开始构建它,还是在现有编排系统的基础上构建它。很快就清楚我们不应该从头开始构建它 -- 我们最终将不得不重新发明集群管理、调度、网络管理以及更多内容。
Kubernetes 提供了一个强大而灵活的编排系统,具有全面的 API,并由一个强大且不断壮大的社区支持。基于它构建意味着 Fission 可以将容器编排功能留给 Kubernetes,并专注于 FaaS 功能。
我们不想要单独的 FaaS 集群的另一个原因是 FaaS 与其他基础设施结合使用效果最佳。例如,它可能适合小型 REST API,但它需要与其他服务协同工作以存储状态。FaaS 也非常适合作为事件处理程序,用于处理来自存储、数据库和 Kubernetes 本身的通知。Kubernetes 是所有这些服务在其上互操作的绝佳平台。
部署和使用 Fission
可以使用 kubectl create
命令安装 Fission:有关说明,请参阅项目 README。
以下是如何编写“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!
Fission 负责将函数加载到容器中,将请求路由到该容器等等。我们将在下一节中详细介绍。
Fission 如何在 Kubernetes 上实现
FaaS 框架的核心必须 (1) 将函数转换为服务,以及 (2) 管理这些服务的生命周期。
有很多方法可以实现这些目标,每种方法都有不同的权衡。框架应该在源代码级别运行,还是在 Docker 镜像级别运行(或介于两者之间的级别,例如“buildpack”)?函数首次运行时可接受的开销是多少?此处做出的选择会影响平台的灵活性、易用性、资源使用和成本,当然还有性能。
打包、源代码和镜像
我们的目标之一是让 Fission 对新用户来说非常容易使用。我们选择在
源代码级别运行,以便用户可以避免处理容器镜像构建、将镜像推送到注册表、管理注册表凭据、镜像版本控制等等。
但是,容器镜像是打包应用程序的最灵活方式。例如,纯粹的源代码级别接口不允许用户打包二进制依赖项。
因此,Fission 采用混合方法 -- 包含函数动态加载器的容器镜像。这种方法允许大多数用户纯粹在源代码级别使用 Fission,但允许他们在需要时自定义容器镜像。
这些镜像(在 Fission 中称为“环境镜像”)包含语言的运行时(例如 NodeJS 或 Python)、一组常用依赖项以及函数的动态加载器。如果这些依赖项对于用户正在编写的函数来说足够,则无需重建镜像。否则,可以修改依赖项列表,并重建镜像。
这些环境镜像只是 Fission 中特定于语言的部分。它们为框架的其余部分提供统一的接口。此设计使 Fission 易于扩展到更多语言。
冷启动性能
无服务器函数的目标之一是函数仅在运行时才使用 CPU/内存资源。这优化了函数的资源成本,但代价是来自空闲状态的启动时存在一些性能开销(“冷启动”开销)。
冷启动开销在许多用例中都很重要。特别是,对于在交互式用例中使用的函数(例如 Web 或移动应用程序,用户正在等待操作完成),几秒钟的冷启动延迟是不可接受的。
为了优化冷启动开销,Fission 为每个环境维护一个正在运行的容器池。当收到函数请求时,Fission 不必部署新容器 -- 它只是选择一个已经运行的容器,将函数复制到容器中,动态加载该函数,并将请求路由到该实例。此过程的开销对于 NodeJS 和 Python 函数大约需要 100 毫秒。
Fission 如何在 Kubernetes 上工作
Fission 被设计为一组微服务。一个控制器跟踪函数、HTTP
路由、事件触发器和环境镜像。一个池管理器管理空闲环境容器池、将函数加载到这些容器中以及在函数实例空闲时杀死它们。路由器接收 HTTP 请求并将它们路由到函数实例,必要时从池管理器请求实例。
控制器提供 fission API。所有其他组件都监视控制器的更新。路由器以 LoadBalancer 或 NodePort 类型的 Kubernetes 服务公开,具体取决于 Kubernetes 集群的托管位置。
当路由器收到请求时,它会查找缓存以查看此请求是否已有一个应路由到的服务。如果没有,它会查找该函数以将请求映射到该函数,并向 poolmgr 请求一个实例。poolmgr 有一个空闲 pod 池;它选择一个,将函数加载到其中(通过向 pod 中的 sidecar 容器发送请求),并将 pod 的地址返回给路由器。路由器会将请求代理到此 pod。pod 会被缓存以供后续请求使用,如果它已空闲几分钟,则会被杀死。
(目前,Fission 将一个函数映射到一个容器;计划在以后的版本中实现自动缩放到多个实例。还计划重用函数 pod 来托管多个函数,以用于隔离不是必需的情况。)
Fission 的用例
机器人、Webhook、REST API
Fission 是制作小型 REST API、实现 webhook 以及为 Slack 或其他服务编写聊天机器人的一个很好的框架。
作为简单 REST API 的示例,我们制作了一个小型留言簿应用程序,该应用程序使用函数来读取和写入留言簿,并与 redis 实例一起工作以跟踪状态。您可以在 Fission GitHub 存储库中找到该应用程序。
该应用程序包含两个端点 -- GET 端点从 redis 中列出留言簿条目,并将它们呈现为 HTML。POST 端点将新条目添加到 redis 中的留言簿列表。这就是全部 -- 没有要管理的 Dockerfile,更新应用程序就像调用 fission function update 一样简单。
处理 Kubernetes 事件
Fission 还支持根据 Kubernetes 监视触发函数。例如,您可以设置一个函数来监视某个命名空间中所有与特定标签匹配的 pod。该函数在其上下文中获取序列化对象和监视事件类型(已添加/已删除/已更新)。
这些事件处理程序函数可用于简单的监控 -- 例如,您可以在向集群添加新服务时发送一条 Slack 消息。还有更复杂的用例,例如通过监视 Kubernetes 的第三方资源来编写自定义控制器。
状态和路线图
Fission 目前处于早期 alpha 版本(2017 年 1 月)。它尚未准备好用于生产环境。我们正在寻找早期采用者和反馈。
Fission 的未来是什么?我们正在努力使 Kubernetes 上的 FaaS 更加方便、易于使用且更易于集成。在未来几个月内,我们将努力添加对单元测试、与 Git 集成、函数监控和日志聚合的支持。我们还致力于与其他事件源集成。
创建更多语言环境也在进行中。目前支持 NodeJS 和 Python。Klavs Madsen 提供了对 C# .NET 的初步支持。
您可以在我们的 GitHub issues 和 projects 中找到我们当前的路线图。
参与其中
Fission 是开源的,由 Platform9 Systems 公开开发。请在 GitHub 上查看我们的项目,如果您想与我们聊天,请加入我们的 Slack 频道。我们也在 Twitter 上,账号是 @fissionio。
- 下载 Kubernetes
- 在 GitHub 上参与 Kubernetes 项目
- 在 Stack Overflow 上发布问题(或回答问题)
- 在 Slack 上与社区联系
- 在 Twitter 上关注我们 @Kubernetesio 以获取最新更新