
Serverless 应用引擎(SAE)是一款底层基于 Kubernetes,实现了 Serverless 架构与微服务架构结合的云产品。作为一款不断迭代的云产品,在快速发展的过程中也遇到了许多挑战。如何在蓬勃发展的云原生时代中解决这些挑战,并进行可靠快速的云架构升级?SAE 团队和 KubeVela 社区针对这些挑战开展了紧密合作,并给出了云原生下的开源可复制解决方案——KubeVela Workflow。
本文将详细介绍 SAE 使用 KubeVela Workflow 进行架构升级的解决方案,并对多个实践场景进行一一解读。
Serverless 应用引擎(SAE)是面向业务应用架构、微服务架构的一站式应用托管平台,是一款底层基于 Kubernetes,实现了 Serverless 架构与微服务架构结合的云产品。

如上架构图,SAE 的用户可以将多种不同类型的业务应用托管在 SAE 之上。而在 SAE 底层,则会通过 JAVA 业务层处理相关的业务逻辑,以及与 Kubernetes 资源进行交互。在最底层,则依靠高可用,免运维,按需付费的弹性资源池。
在这个架构下,SAE 主要依托其 JAVA 业务层为用户提供功能。这样的架构在帮助用户一键式部署应用的同时,也带来了不少挑战。
在 Serverless 持续发展的当下,SAE 主要遇到了三大挑战:
SAE 内部的工程师在开发运维的过程中,存在着一些复杂且非标准化的运维流程。如何自动化这些复杂的操作,从而降低人力的消耗?
随着业务发展,SAE 的应用发布功能受到了大量用户的青睐。用户增长的同时也带来了效率的挑战,在面对大量用户高并发的场景下,如何优化已有的发布功能并提升效率?
在 Serverless 持续落地于企业的当下,各大厂商都在不断将产品体系 Serverless 化。在这样的浪潮下,SAE 应该如何在快速对接内部 Serverless 能力,在上线新功能的同时,降低开发成本?
而这个编排引擎需要满足以下条件来解决这些挑战:
高可扩展。对于这个编排引擎来说,流程中的节点需要具备高可扩展性,只有这样,才能将原本非标准化且复杂的操作节点化,从而和编排引擎的流程控制能力结合在一起,发挥出 1+1 > 2 的效果,从而降低人力的消耗。
轻量高效。这种编排引擎必须高效,且生产可用。这样才能满足 SAE 在大规模用户场景下的高并发需求。
强对接和流程控制能力。这个编排引擎需要能够快速业务的原子功能,把原本串联上下游能力的胶水代码转换成编排引擎中的流程,从而降低开发成本。
得益于云原生蓬勃的生态发展,社区中已经有许多成熟的工作流项目,如 Tekton,Argo 等。在阿里云内部,也有一些编排引擎的沉淀。那么为什么要“新造一个轮子”,而不使用已有的技术呢?
因为 KubeVela Workflow 在设计上有一个非常根本的区别:工作流中的步骤面向云原生 IaC 体系设计,支持抽象封装和复用,相当于你可以直接在步骤中调用自定义函数级别的原子能力,而不仅仅是下发容器。

在 KubeVela Workflow 中,每个步骤都有一个步骤类型,而每一种步骤类型,都会对应 WorkflowStepDefinition(工作流步骤定义)这个资源。你可以使用 CUE 语言(一种 IaC 语言,是 JSON 的超集) 来编写这个步骤定义,或者直接使用社区中已经定义好的步骤类型。
CUE语言:
https://cuelang.org/
你可以简单地将步骤类型定义理解为一个函数声明,每定义一个新的步骤类型,就是在定义一个新的功能函数。函数需要一些输入参数,步骤定义也是一样的。在步骤定义中,你可以通过 parameter 字段声明这个步骤定义需要的输入参数和类型。当工作流开始运行时,工作流控制器会使用用户传入的实际参数值,执行对应步骤定义中的 CUE 代码,就如同执行你的功能函数一样。
有了这样一层步骤的抽象,就为步骤增添了极大的可能性。
如果你希望自定义步骤类型,就如同编写一个新的功能函数一样,你可以在步骤定义中直接通过 import 来引用官方代码包,从而将其他原子能力沉淀到步骤中,包括 HTTP 调用,在多集群中下发,删除,列出资源,条件等待,等等。这也意味着,通过这样一种可编程的步骤类型,你可以轻松对接任意系统。如,在 SAE 的场景下,在步骤定义中解决和内部其他原子能力(如 MSE,ACR,ALB,SLS 等等)的对接,再使用工作流的编排能力来控制流程:

如果你只希望使用定义好的步骤,那么,就如同调用一个封装好的第三方功能函数一样,你只需要关心你的输入参数,并且使用对应的步骤类型就可以了。如,一个典型的构建镜像场景。首先,指定步骤类型为 build-push-image,接着,指定你的输入参数:构建镜像的代码来源与分支,构建后镜像名称以及推送到镜像仓库需要使用的秘钥信息。
apiVersion: core.oam.dev/v1alpha1kind: WorkflowRunmetadata:name: build-push-imagenamespace: defaultspec:workflowSpec:steps:- name: build-pushtype: build-push-imageproperties:context:git: github.com/FogDong/simple-web-demobranch: mainimage: fogdong/simple-web-demo:v1credentials:image:name: image-secret
在这样一种架构下,步骤的抽象给步骤本身带来了无限可能性。当你需要在流程中新增一个节点时,你不再需要将业务代码进行“编译-构建-打包”后用 Pod 来执行逻辑,只需要修改步骤定义中的配置代码,再加上工作流引擎本身的编排控制能力,就能够完成新功能的对接。
案例 1:自动化运维操作
第一个场景,是 SAE 内部的运维工程师的一个自动化运维场景。
使用 HTTP 请求步骤类型,通过请求 ACR 的服务来构建镜像,并通过参数传递将镜像 ID 传递给下一个步骤。在该步骤定义中,需要等待 ACR 的服务构建完毕后,才结束当前步骤的执行。 如果第一步构建失败了,则进行该镜像的错误处理。 如果第一步构建成功了,则使用 HTTP 请求步骤来调用镜像缓存构建的服务,并同时将服务的日志作为当前的步骤来源。这里可以直接在 UI 中查看步骤的日志以排查问题, 使用一个步骤组,在里面分别使用下发资源类型的步骤来进行上海集群和美西集群的镜像预热:这里会使用 KubeVela Workflow 的多集群管控能力,直接在多集群中下发 ImagePullJob 工作负载,进行镜像预热。

template: {第一步:从指定集群中读取资源read: op.#Read & {value: {apiVersion: parameter.apiVersionkind: parameter.kindmetadata: {name: parameter.namenamespace: parameter.namespace}}cluster: parameter.cluster}第二步:直到资源状态 Ready,才结束等待,否则步骤会一直等待wait: op.#ConditionalWait & {continue: read.value.status != _|_ && read.value.status.phase == "Ready"}// 第三步(可选):如果资源 Ready 了,那么...// 其他逻辑...// 定义好的参数,用户在使用该步骤类型时需要传入parameter: {apiVersion: stringkind: stringname: stringnamespace: *context.namespace | stringcluster: *"" | string}}
对应到当前这个场景就是:
第一步:读取指定集群(如:上海集群)中的 ImagePullJob 状态。 第二步:如果 ImagePullJob Ready,镜像已经预热完毕,则当前步骤成功,执行下一个步骤。 第三步:当 ImagePullJob Ready 后,清理集群中的 ImagePullJob。
通过这样自定义的方式,不过后续在运维场景下新增了多少 Region 的集群或是新类型的资源,都可以先将集群的 KubeConfig 纳管到 KubeVela Workflow 的管控中后,再使用已经定义好的步骤类型,通过传入不同的集群名或者资源类型,来达到一个简便版的 Kubernetes Operator Reconcile 的过程,从而极大地降低开发成本。
案例 2:优化已有的发布流程
在自动化内部的运维操作之外,升级原本 SAE 的产品架构,从而提升产品的价值和用户的发布效率,也是 SAE 选择 KubeVela Workflow 的重要原因。
▧原有架构


▧新架构

案例 3:快速上线新功能
除了自动化运维和升级原本的架构,KubeVela Workflow 还能提供什么?


打通 CI/CD:构建镜像,推送镜像以及部署资源 https://github.com/kubevela/workflow#try-kubevela-workflow
编排多个 KubeVela Applications https://github.com/kubevela/workflow/blob/main/examples/multiple-apps.md
一键式初始化环境:通过 Terraform 拉起集群,纳入多集群管控,以及在新集群中下发资源 https://github.com/kubevela/workflow/blob/main/examples/initialize-env.md
调用指定服务,并通过数据传递将返回结果发送通知 https://github.com/kubevela/workflow/blob/main/examples/request-and-notify.md
使用不同的运行时参数来控制资源的部署 https://github.com/kubevela/workflow/blob/main/examples/run-with-template.md
您可以通过如下材料了解更多关于 KubeVela 以及 OAM 项目的细节:
项目代码库:
github.com/oam-dev/kubevela
欢迎 Star/Watch/Fork!
项目官方主页与文档:kubevela.io
从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢迎开发者进行翻译。
项目钉钉群:23310022;Slack:CNCF #kubevela Channel
加入微信群:请先添加以下 maintainer 微信号,表明进入KubeVela用户群:





