Serverless 利用引擎(SAE)是一款底层基于 Kubernetes,实现了 Serverless 架构与微服务架构联合的云产品。作为一款一直迭代的云产品,在疾速倒退的过程中也遇到了许多挑战。如何在蓬勃发展的云原生时代中解决这些挑战,并进行牢靠疾速的云架构降级?SAE 团队和 KubeVela 社区针对这些挑战发展了严密单干,并给出了云原生下的开源可复制解决方案——KubeVela Workflow。
本文将具体介绍 SAE 应用 KubeVela Workflow 进行架构降级的解决方案,并对多个实际场景进行一一解读。
Serverless 时代下的挑战
Serverless 利用引擎(SAE)是面向业务利用架构、微服务架构的一站式利用托管平台,是一款底层基于 Kubernetes,实现了 Serverless 架构与微服务架构联合的云产品。
如上架构图,SAE 的用户能够将多种不同类型的业务利用托管在 SAE 之上。而在 SAE 底层,则会通过 JAVA 业务层解决相干的业务逻辑,以及与 Kubernetes 资源进行交互。在最底层,则依附高可用,免运维,按需付费的弹性资源池。
在这个架构下,SAE 次要依靠其 JAVA 业务层为用户提供性能。这样的架构在帮忙用户一键式部署利用的同时,也带来了不少挑战。
在 Serverless 继续倒退的当下,SAE 次要遇到了三大挑战:
- SAE 外部的工程师在开发运维的过程中,存在着一些简单且非标准化的运维流程。如何自动化这些简单的操作,从而升高人力的耗费?
- 随着业务倒退,SAE 的利用公布性能受到了大量用户的青眼。用户增长的同时也带来了效率的挑战,在面对大量用户高并发的场景下,如何优化已有的公布性能并晋升效率?
- 在 Serverless 继续落地于企业的当下,各大厂商都在一直将产品体系 Serverless 化。在这样的浪潮下,SAE 应该如何在疾速对接外部 Serverless 能力,在上线新性能的同时,升高开发成本?
纵观上述三个挑战,不难看出,SAE 须要某种编排引擎来降级公布性能,对接外部能力以及自动化运维操作。
而这个编排引擎须要满足以下条件来解决这些挑战:
- 高可扩大。对于这个编排引擎来说,流程中的节点须要具备高可扩展性,只有这样,能力将本来非标准化且简单的操作节点化,从而和编排引擎的流程控制能力联合在一起,施展出 1+1 > 2 的成果,从而升高人力的耗费。
- 轻量高效。这种编排引擎必须高效,且生产可用。这样能力满足 SAE 在大规模用户场景下的高并发需要。
- 强对接和流程控制能力。这个编排引擎须要可能疾速业务的原子性能,把本来串联上下游能力的胶水代码转换成编排引擎中的流程,从而升高开发成本。
基于下面这些挑战和思考,SAE 和 KubeVela 社区进行了深度单干,并推出了 KubeVela Workflow 这个我的项目作为编排引擎。
为什么要用 Kubevela Workflow?
得益于云原生蓬勃的生态倒退,社区中曾经有许多成熟的工作流我的项目,如 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/v1alpha1
kind: WorkflowRun
metadata:
name: build-push-image
namespace: default
spec:
workflowSpec:
steps:
- name: build-push
type: build-push-image
properties:
context:
git: github.com/FogDong/simple-web-demo
branch: main
image: fogdong/simple-web-demo:v1
credentials:
image:
name: image-secret
在这样一种架构下,步骤的形象给步骤自身带来了有限可能性。当你须要在流程中新增一个节点时,你不再须要将业务代码进行“编译 - 构建 - 打包”后用 Pod 来执行逻辑,只须要批改步骤定义中的配置代码,再加上工作流引擎自身的编排控制能力,就可能实现新性能的对接。
而这也是 SAE 中应用 KubeVela Workflow 的基石,在可扩大的根底之上,能力充沛借助和施展生态的力量,减速产品的降级。
应用案例
接下来,咱们来深刻 SAE 中应用 KubeVela Workflow 的场景,从案例中进行更深层的了解
案例 1:自动化运维操作
第一个场景,是 SAE 外部的运维工程师的一个自动化运维场景。在 SAE 外部有这样一个场景,咱们会编写并更新一些根底镜像,并且须要将这些镜像预热到多个不同 Region 的集群中,通过镜像预热,来给应用这些根底镜像的用户更好的体验。
本来的操作流程非常复杂,不仅波及到了应用 ACR 的镜像构建,多个区域的镜像推送,还须要制作镜像缓存的模板,并且将这些镜像缓存推送到不同 Region 的集群当中。这里的 Region 包含上海,美西,深圳,新加坡等等。这些操作是非标准化,且十分耗时的。因为当一个运维须要在本地推送这些镜像到国外的集群当中时,很有可能因为网络带宽的问题而失败。因而,他须要将精力扩散到这些本来能够自动化的操作上。
而这也是一个非常适合 KubeVela Workflow 的场景:这些操作外面的每一个步骤,都能够通过可编程的形式转换成工作流里的步骤,从而能够在编排这些步骤的同时,达到可复用的成果。同时,KubeVela Workflow 也提供了一个可视化的 Dashboard,运维人员只须要配置一次流水线模板,之后就能够通过触发执行,或者在每次触发执行时传入特定的运行时参数,来实现流程的自动化。
在这里,简化版的步骤如下:
- 应用 HTTP 申请步骤类型,通过申请 ACR 的服务来构建镜像,并通过参数传递将镜像 ID 传递给下一个步骤。在该步骤定义中,须要期待 ACR 的服务构建结束后,才完结以后步骤的执行。
- 如果第一步构建失败了,则进行该镜像的错误处理。
- 如果第一步构建胜利了,则应用 HTTP 申请步骤来调用镜像缓存构建的服务,并同时将服务的日志作为以后的步骤起源。这里能够间接在 UI 中查看步骤的日志以排查问题.
- 应用一个步骤组,在外面别离应用下发资源类型的步骤来进行上海集群和美西集群的镜像预热:这里会应用 KubeVela Workflow 的多集群管控能力,间接在多集群中下发 ImagePullJob 工作负载,进行镜像预热。
下面这个流程中,如果不应用 KubeVela Workflow,你可能须要写一段业务代码,来串联多个服务和集群。以最初一步,往多集群中下发 ImagePullJob 工作负载为例:你不仅须要治理多集群的配置,还须要 Watch 工作负载(CRD)的状态,直到工作负载的状态变成 Ready,才持续下一步。而这个流程其实对应了一个简略的 Kubernetes Operator 的 Reconcile 逻辑:先是创立或者更新一个资源,如果这个资源的状态合乎了预期,则完结此次 Reconcile,如果不合乎,则持续期待。
难道咱们运维操作中每新增一种资源的治理,就须要实现一个 Operator 吗?有没有什么轻便的办法,能够将咱们从简单的 Operator 开发中解放出来呢?
正是因为 KubeVela Workflow 中步骤的可编程性,可能齐全笼罩 SAE 场景中的这些运维操作和资源管理,才可能帮忙工程师们升高人力的耗费。相似下面的逻辑,对应到 KubeVela Workflow 的步骤定义中则非常简单,不论是什么相似的资源(或者是一个 HTTP 接口的申请),都能够用相似的步骤模板笼罩:
template: {
// 第一步:从指定集群中读取资源
read: op.#Read & {
value: {
apiVersion: parameter.apiVersion
kind: parameter.kind
metadata: {
name: parameter.name
namespace: parameter.namespace
}
}
cluster: parameter.cluster
}
// 第二步:直到资源状态 Ready,才完结期待,否则步骤会始终期待
wait: op.#ConditionalWait & {continue: read.value.status != _|_ && read.value.status.phase == "Ready"}
// 第三步(可选):如果资源 Ready 了,那么...
// 其余逻辑...
// 定义好的参数,用户在应用该步骤类型时须要传入
parameter: {
apiVersion: string
kind: string
name: string
namespace: *context.namespace | string
cluster: *"" | string
}
}
对应到以后这个场景就是:
- 第一步:读取指定集群(如:上海集群)中的 ImagePullJob 状态。
- 第二步:如果 ImagePullJob Ready,镜像曾经预热结束,则以后步骤胜利,执行下一个步骤。
- 第三步:当 ImagePullJob Ready 后,清理集群中的 ImagePullJob。
通过这样自定义的形式,不过后续在运维场景下新增了多少 Region 的集群或是新类型的资源,都能够先将集群的 KubeConfig 纳管到 KubeVela Workflow 的管控中后,再应用曾经定义好的步骤类型,通过传入不同的集群名或者资源类型,来达到一个简便版的 Kubernetes Operator Reconcile 的过程,从而极大地升高开发成本。
案例 2:优化已有的公布流程
在自动化外部的运维操作之外,降级本来 SAE 的产品架构,从而晋升产品的价值和用户的公布效率,也是 SAE 抉择 KubeVela Workflow 的重要起因。
原有架构
在 SAE 的公布场景中,一次发布会对应一系列的工作,如:初始化环境,构建镜像,分批公布等等。这一系列工作对应下图中的 SAE Tasks。
在 SAE 本来的架构中,这些工作会被有序地扔给 JAVA Executor 来进行理论的业务逻辑,比方,往 Kubernetes 中下发资源,以及与 MySQL 数据库进行当前任务的状态同步,等等。
在以后的工作实现后,JAVA Executor 会从 SAE 本来的编排引擎中获取下一个工作,同时,这个编排引擎也会一直地将新工作放到最开始的工作列表中。
而这个老架构中最大的问题就在于轮询调用,JAVA Executor 会每隔一秒从 SAE 的工作列表中进行获取,查看是否有新工作;同时,JAVA Executor 下发了 Kubernetes 资源后,也会每隔一秒尝试从集群中获取资源的状态。
SAE 原有的业务架构并不是 Kubernetes 生态中的控制器模式,而是轮询的业务模式,如果将编排引擎层降级为事件监听的控制器模式,就能更好地对接整个 Kubernetes 生态,同时晋升效率。
然而在本来的架构中,业务的逻辑耦合较深。如果应用的是传统的以容器为根底下发的云原生工作流的话,SAE 就须要将本来的业务逻辑打包成镜像,保护并更新一大堆镜像制品,这并不是一条可继续倒退的路线。咱们心愿降级后的工作流引擎,可能轻量地对接 SAE 的工作编排,业务执行层以及 Kubernetes 集群。
新架构
在借助了 KubeVela Workflow 的高可扩展性后,SAE 的工程师既不须要将原有的能力从新打包成镜像,也不须要进行大规模的批改。
新的流程如上图:SAE 产品侧创立了公布单之后,业务侧会将模型写入数据库,进行模型转换,生成一条 KubeVele Workflow,这里对应到右侧的 YAML。
同时,SAE 本来的 JAVA Executor 将本来的业务能力提供成微服务 API。KubeVela Workflow 在执行时,每个步骤都是 IaC 化的,底层实现是 CUE 语言。这些步骤有的会去调用 SAE 的业务微服务 API,有的则会间接与底层 Kubernetes 资源进行交付。而步骤间也能够进行数据传递。如果调用出错了,能够通过步骤的条件判断,来进行错误处理。
这样一种优化,不仅可扩大,充沛复用 K8S 生态,工作流流程和原子能力均可扩大,并且面向终态。这种可扩大和流程管制的相结合,可能笼罩本来的业务性能,并且缩小开发量。同时,状态的更新从分支级提早升高到毫秒级,麻利且原生,不仅具备了 YAML 级的形容能力,还能将开发效率从 1d 晋升到 1h。
案例 3:疾速上线新性能
除了自动化运维和降级本来的架构,KubeVela Workflow 还能提供什么?
步骤的可复用性和与其余生态的易对接性,在降级之外,给 SAE 带来了额定的惊喜:从编写业务代码变为编排不同步骤,从而疾速上线产品的新性能!
SAE 积淀了大量的 JAVA 根底,并且反对了丰盛的性能,如:反对 JAVA 微服务的单批公布,分批公布,以及金丝雀公布等等。但随着客户增多,一些客户提出了新的需要,他们心愿能有多语言南北流量的灰度公布能力。
在云原生蓬勃的生态下,灰度公布这块也有许多成熟的开源产品,比方 Kruise Rollout。SAE 的工程师调研后发现,能够应用 Kruise Rollout 来实现灰度公布的能力,同时,配合上阿里云的外部的 ingress controller,ALB,来进行不同流量的切分。
这样一种计划就积淀成了下面这张架构图,SAE 下发一条 KubeVela Workflow,Workflow 中的步骤将同时对接阿里云的 ALB,开源的 Kruise Rollout 以及 SAE 本人的业务组件,并在步骤中实现对批次的治理,从而实现性能的疾速上线。
事实上,应用了 KubeVela Workflow 后,上线这个性能就不再须要编写新的业务代码,只须要编写一个更新灰度批次的步骤类型。
因为步骤类型的可编程性,咱们能够轻松在定义中应用不同的更新策略来更新 Rollout 对象的公布批次以及对应下发集群。并且,在工作流中,每个步骤的步骤类型都是可复用的。这也意味着,当你开发新步骤类型时,你也在为下一次,下下次的新性能上线打下了根底。这种复用,能够让你迅速地积淀性能,极大缩小了开发成本。
有了这种高效的编排能力,咱们就能进行疾速变更,在通用变更的根底上,如果某客户须要开启性能,能够迅速进行自定义变更。
总结
在 SAE 进行了 KubeVela 架构降级后,不仅晋升了公布效率,同时,也升高了开发成本。能够在底层依赖 Serverless 基础设施的劣势之上,充分发挥产品在利用托管上的劣势。
并且,KubeVela Workflow 在 SAE 中的架构降级计划,也是一个可复制的开源解决方案。社区曾经内置提供了 50+ 的步骤类型,包含构建、推送镜像,镜像扫描,多集群部署,应用 Terraform 治理基础设施,条件期待,音讯告诉等,可能帮你轻松买通 CICD 的全链路。
你还能够参考以下文档来获取更多应用场景:
买通 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 我的项目的细节:
- 我的项目代码库:http://github.com/oam-dev/kubevela
欢送 Star/Watch/Fork! - 我的项目官方主页与文档:http://kubevela.io
从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢送开发者进行翻译。
作者:董天欣(雾雾)
原文链接
本文为阿里云原创内容,未经容许不得转载。