这是 Jerry 2021 年的第 40 篇文章,也是汪子熙公众号总共第 317 篇原创文章。
Jerry 2018年曾经写过两篇文章,介绍了如何在 Kubernetes 这个容器编排平台上运行一个包含 SAP UI5 应用的 Docker 镜像。
SAP Kyma,是一个由 SAP 推进的开源的企业软件扩展平台,底层基于 Kubernetes,能以Serverless/微服务架构的方式,对 On-premise 和云应用进行扩展。
SAP Business Technology Platform (下文简称 BTP) 于 2020年开始支持 Kyma 运行环境。本文介绍如何把本地开发的 SAP UI5 应用,打包成 Docker 镜像文件,然后部署并运行在 SAP BTP Kyma 运行环境里。
首先我们在本地开发一个 SAP UI5 应用。这个应用的源代码,大家可以在 Github 下载。
这个 SAP UI5 应用的构建,采取 SAP UI5 Tool 提供的 Command Line Interface,即 @ui5/cli 完成。
使用命令行 npm run-script build, 调用 UI5 CLI 进行构建,得到生产版本的 SAP UI5 资源文件,存储在项目工程的 dist 文件夹内。稍后我们制作 Docker 镜像文件时,会使用 dist 文件夹内的资源文件。
使用命令行 npm run-script start,本地运行这个 SAP UI5 应用,界面如下:
应用显示的这三条订单数据,维护在项目工程的 orders.json 文件内。
出于演示目的,我只实现了订单列表显示功能。而订单添加,修改和删除功能,大家可以自行实现。
下面我们继续对该 SAP UI5 应用进行调整:将其订单列表的数据源,从本地 orders.json 文件, 调整成消费 SAP BTP Kyma 上运行的 Serverless Function.
登录 SAP BTP Cockpit,如今即便是 Trial 账号,也能免费启用 Kyma 运行环境。
点击 Go to Dashboard,就能进入 Kyma 控制台了:
在 dev 命名空间内,创建一个新的 Function:
Function 命名为 order-manager, 其实现技术栈选择成 Node.js 12:
在函数实现源代码的 Source 区域,将之前 SAP UI5 工程里的 orders.json 文件里的内容,拷贝到下图函数编辑器里。保存之后,Function 状态变为 RUNNING,立即可用。这体现了 Kyma Serveless 计算的优势:开发人员只需专注于函数业务逻辑的编写,无需关心函数的部署和运行环境问题。
切换到 Function Configuration 面板,点击 Expose Function,创建一个新的 API Rule,将该函数通过 HTTP 调用的方式,暴露给 Internet 上的其他消费者。
API Rule 按照下图所示进行维护,其中 Service 下拉列表里显示的,是创建 Function 时自动生成的同名 Service 资源。
API Rule 创建完毕后,点击其 Host 字段,就能通过 HTTP 的方式,调用即执行对应的 Function 了。
在浏览器里访问该超链接,能看到我们在 Function 源代码里,硬编码的三条订单数据:
对 UI5 应用做简单的调整,让其消费部署在 SAP BTP Kyma 运行环境上刚刚创建的 Function. 至此我们完成了 UI5 应用的开发,可以开始构建 Docker 镜像文件了。
新建 Dockerfile 文件,该 Docker 镜像构建具体分为两个步骤,即所谓的多阶段构建。首先,使用关键字 FROM,指定构建的基本镜像为 node:current-slim,执行 npm install 下载 SAP UI5 应用 package.json 文件里定义的依赖,然后执行 npm run-script build,生成包含该 UI5 项目生产环境版本资源文件的 dist 文件夹。考虑到运行一个 SAP UI5 应用,只需要构建出的 dist 文件夹里的资源即可,而 node:current-slim 镜像内的所有内容,与 SAP UI5 应用的运行毫无关系。因此,第10行代码,我们用 FROM 指定了一个新的镜像,即 nginx:alpine. 第11行用关键字 COPY,将前一镜像构建出的 dist 文件夹的内容,拷贝到 nginx 工作目录即 html 内,这样能大大减小最后构建出的 Docker 镜像的尺寸。
使用如下命令行构建 Docker 镜像文件:
docker build -t i042416/ui5-kyma -f docker/Dockerfile .
注意,命令行末尾的".",代表当前目录,而非命令行结束的标识符。
使用 docker push 命令,将该构建好的镜像,上传到 Docker Hub 去:
我们在本地测试一下这个构建好的 Docker 镜像。
通过命令行本地启动 Docker 容器:
docker run -p 1081:80 -d i042416/ui5-kyma
将镜像内 nginx 对应的 80 端口,映射成本地宿主机的 1081 端口,然后浏览器打开 localhost:1081 ,确保 SAP UI5 应用能够正常工作,并且检查此时加载的资源,已经是 dist 文件夹里构建好的生产系统版本的文件,即 component-preload.js:
最后一步,将该 Docker 镜像,通过 Kubernetes 规范部署到 SAP Kyma 上。可以使用 Kubernetes 提供的命令行工具 kubectl,也可使用 SAP Kyma 控制台的图形界面。
创建一个名为 deployment.yaml 的文件,里面定义一个名为 jerry-ui5-kyma 的 Deployment 资源,这是 Kubernetes 原生支持的资源类型之一。指定使用之前构建好并且上传到 Docker Hub 的镜像文件:i042416/ui5-kyma:
回到 Kyma 控制台,菜单 Deployment new workload -> Upload YAML, 选择前一步创建好的 deployment.yaml:
确保该 Deployment 处于 Running 状态:
最后基于 jerry-ui5-kyma 创建一个 API Rule,从而使其可以在 Internet 上被访问。下图高亮区域,即是被构建在 Docker 镜像里的 SAP UI5 应用,在 SAP Kyma 运行环境里被访问的 URL:
https://jerryui5kyma.c-46d70f2.kyma.shoot.live.k8s-hana.ondemand.com/
至此,我们已经逐步实现了本文开头提出的任务:
(1) 本地开发一个 SAP UI5 应用
(2) 将该 SAP UI5 应用打包成 Docker 镜像
(3) 通过 Kubernetes Deployment,将包含前一步的 Docker 镜像,部署到 SAP Kyma 上并运行。
既然 SAP Kyma 底层基于 Kubernetes,所以当然也可以使用 Kubernetes 命令行工具 kubectl,直接操纵 SAP Kyma 资源。
在 SAP Kyma 控制台右上角,点击 Get kubeconfig 下载同名配置文件。
将下载到本地的 kubeconfig.yml 文件的路径,配置成环境变量 KUBECONFIG.
执行 kubectl version 命令行,能看到 kubectl 打印出客户端和服务器端的 git 和 go 运行环境的版本号:
接下来就能使用 kubectl 命令行,查询刚才下载好的 kubeconfig.yml 文件指向的 SAP Kyma 实例上运行的各种资源了。
比如使用如下命令行,查询到 SAP UI5 应用运行的 pod 名称为:jerry-ui5-kyma-785b458ff5-zm7xt
得到 pod 名称后,使用命令行进入该 pod 默认容器,即 jerry-ui5-kyma 内部:
kubectl exec -it jerry-ui5-kyma-785b458ff5-zm7xt -n dev -- /bin/sh
进入容器内部之后,切换到目录 /usr/share/nginx/html, 这里能看到我们之前本地开发的 SAP UI5 的资源文件。 这些文件,正是由我们之前制作 Docker 镜像时编写的 Dockerfile 里的最后一行,通过 COPY 操作,从前一个 node 基准镜像,执行 npm run-script build 命令后构建而成的 UI5 生产版本的资源文件,拷贝到 nginx 镜像的 /usr/share/nginx/html 目录而生成的。
希望本文能够帮助大家,对如何开发 SAP UI5 应用,并部署和运行于 SAP Kyma 上的完整步骤,有一个直观的了解。本文提到的 SAP UI5 应用,后续还有很多可以继续增强的地方,比如实现订单添加和删除功能,并使用 Redis 进行持久化,同时将 Redis 服务也部署在 SAP Kyma 上,然后让该 UI5 应用,消费 SAP Kyma 上的 Redis 服务,而非本文介绍的 Serverless Function. 大家可以试着自行实现,或者等待本公众号后续的分享。感谢阅读。
更多阅读
更多Jerry的原创文章,尽在:"汪子熙":