云原生平台 Kyma 上创建的 Lambda Function 的技术实现细节介绍

在企业级开发应用进入云原生开发时代之后,Serverless 架构这个词也频繁出没于各大技术媒体里。
Serverless 的字面意思容易给人以 不再需要服务器了
的误解。
站在整个企业的角度上讲,ABAP Netweaver 的 SICF 开发模式,和 Serverless 架构几乎没有任何联系,两者区别很大:一个是需要在部署于企业本地的服务器上编写函数代码,另一个则是直接在云服务提供商提供的平台上编写代码。
然而,从只需要专心搬砖的程序员个体视角出发,两者也有一些相似之处:程序员都不需要关注自己编写的代码在服务器端如何存储, 也不用操心这些函数在何时被调用。
当然,技术总是在向前发展的,运行在现代云服务提供商基于 Serverless 架构平台之上的函数,和运行在 ABAP Netweaver 服务器上的 SICF 服务相比,就像一个含着金钥匙出生的富二代,天生就具备云原生应用的一些基本特质,比如高可用性,弹性伸缩,按需装载,动态计费等等。
SAP 近些年来在云原生开发领域进行了巨大的持续投入,自然少不了基于 Serverless 架构的解决方案,其中一个典型例子就是 SAP Kyma 上的 Lambda Function.
SAP Kyma Serverless 的实现基于 Kubeless,一个 Kubernetes 原生支持的 Serverless 框架,实现了运行于 Kubernetes 之上资源的自动伸缩,API 路由,监控和排错等功能。

借助 Kubeless 提供的命令行接口,我们可以在 Kyma 上创建和部署具备 Serverless 特性的 Lambda Function.
kubeless 命令行接口提供的 CRUD 操作:

当然也可以在 Kyma 提供的浏览器控制台里进行创建工作。
如下图所示,我创建了一个 Hello World 级别的 Lambda Function,执行的逻辑是简单的把传入的字符串尾部加上一个后缀,函数基于 nodejs8 实现。

我们试试通过 HTTPS 协议触发这个 Lambda Function.

这个 HTTPS-endpoint 就是将来我们调用这个 Lambda Function 的 url.

这个 Lambda Function 的认证由 dex 完成,一个基于 openID 的开源认证框架。

在 Kyma 提供的函数测试控制台里,发送一个请求,得到添加了后缀的字符串,简单易懂。

当我们创建了一个 Lambda Function,背后发生了什么?虽然名称为 Serverless,但是这些函数物理上总得运行于服务器上某种容器内,这种容器就是 Kubernetes 的 pod,Jerry 之前强调过,SAP Kubernetes 基于 Kubernetes,因此 Kubernetes 支持的命令,SAP Kyma 也完全支持。
命令行查看刚刚创建的函数:
kubeless function list -n ctu-demo

使用命令行查看这个函数的明细:
kubectl describe function zjerry-lambda -n ctu-demoDeployment 和 ReplicationSet:

水平自动伸缩的实现:

Lambda Function 这个概念是 SAP Kyma 基于 Kubernetes 的 Custom Resource Definitions(CRD)机制创建的一种自定义资源,而上图显示的这些函数属性都是 Kubernetes 里资源支持的原生属性。
在 Kyma 的控制台里能找到 Lambda Function 创建后,Kyma 后台自动生成的对应资源:

Pod,即 Lambda Function 代码的运行环境:

同样的,使用 kubectl describe pod 命令可以查看这个 pod 的明细,找到里面包含的 docker ID 和 docker 镜像 ID.

前面提到 SAP Kyma 的 Lambda Function 采取 dex 进行认证,如果想在编程语言里显式调用,需要提供相应的 token.
在 Kyma 的控制台里拿到 token,

传到 Postman 的 Authorization 头部字段里,得到期望的响应。
下面介绍如何在 Kyma 控制台里扩展新的 UI.
方法是创建一个新的 resource,类型为 ClusterMicroFrontend.使用命令行 kubectl get ClusterMicroFrontend 查看这些 UI 扩展:


最后自定义的 UI 出现在 Kyma console 的这个位置:

下面我们详细分析 Kyma Lambda Function 的技术实现细节。
我在 Kyma 上创建了一个名为 zjerry-lambda 的函数,基于 nodejs8:

可以直接在 Kyma 的测试控制台里调用这个 Lambda Function:

Serverless 的字面意思,不是暗示我们没有服务器了吗?那么这段函数代码到底运行在哪里的?
因为 SAP Kyma 是基于 Kubernetes 的,因此我们还是可以通过 Kubernetes 提供的一些工具,来探索 SAP Kyma 上 Lambda Function 运行原理的一些蛛丝马迹。
首先找到 zjerry-lambda 函数创建后,对应生成的 pod,把名字抄下来:zjerry-lambda-86668f75d4-pfbk6

使用 kubectl 的交互式参数-ti,进入这个 pod 内部:
kubectl exec -ti zjerry-lambda-86668f75d4-pfbk6 -n ctu-demo -- /bin/sh

进入之后,查看进程列表,发现了 node kubeless 这个进程,Jerry 顿时觉得有点眉目了:

看样子,SAP Kyma 的 Lambda Function 是通过一个 node 进程执行的。查看一下这个 pod 里都有哪些文件:

打开 kubeless.js 看看里面的内容:

如果您是一位 nodejs 开发人员,看到上面 Jerry 高亮的红色内容,一定会恍然大悟。SAP Kyma 的 Lambda Function,其实运行在对应的 Kubernetes pod 里启动的 express 应用框架上。Express 的依赖定义在 pod 内部的 package.json 里:

而待执行的 Lambda Function 逻辑,通过环境变量 FUNC_HANDLER 进行注入,在 Jerry 这个例子里,函数体名称为 main:


在 Lambda Function 的 Serverless 框架,即 kubeless.js 运行时,会从 pod 内部的 kubeless 这个文件夹里,找到应用开发人员编写的 Lambda Function,加载并运行。大家可以看到,Jerry 红色高亮的位于 pod 内部的 handler.js, 其内容就是 Kyma 控制台里编写的函数体。

至此,SAP Kyma 的 Lambda Function 实现,在 Jerry 眼中没有任何神秘可言了。回到 Serverless 这个术语本身,并不意味着整个场景里不再需要服务器的参与,而是服务器的这个关注点,在 Serverless 架构下,已经从应用开发人员的视角中隐藏起来罢了。
总结
本文首先介绍了在云原生平台 Kyma 上创建 Lambda Function 的详细步骤,接着深入分析了 Kyma Lambda Function 的实现原理,希望对希望了解 Lambda Function 幕后实现细节的云原生开发人员有所帮助。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/b63718358d879781458e2f0cc】。文章转载请联系作者。
评论