作者: 殷达
背景
最近,云原生计算基金会 CNCF 下的 App Delivery TAG (应用交付领域小组)发布了《CNCF 平台工程白皮书》,KubeVela 被纳入“统一 API 层”项目。
原文下载链接:
回溯 2019 年,Kubernetes 逐渐成为部署和管理基础设施的事实标准。越来越多的平台工程师开始在 Kubernetes 之上构建平台,并向最终用户提供服务。容器化部署和声明式 API 大大降低了复杂系统操作的难度。
然而,当集群中存在数千个工作负载和相关资源时,操作人员很难识别逻辑关系,并根据其内部关系进行准确且符合业务需要的管理。
同时,像 Helm 或 Kustomize 这样的工具已经探索了 打包和交付 Kubernetes 资源的解决方案。这些已被证明是非常有效的,显然 Helm Chart 现在是在 Kubernetes 中打包和分发制品最受欢迎的方式。
另一方面,各种项目也开始定义应用程序。这些尝试不仅是简单地打包资源,而是从自上而下的视角寻求解决方案。与将离散的对象分组以更方便使用相比,应用程序旨在弥合业务应用的研发者和基础设施之间的认知差距。开放应用模型 Open Application Model(OAM)[1]及其对 KubeVela 的实现正是从这里开始。
Pic 1. OAM is proposed to bridge the gap between app developers and the use of underlying infrastructures
应用程序模型的诞生
由微软和阿里云支持的开放应用程序模型(OAM),其目标是为云原生应用程序应该是什么样子提供一个理论模型。它最初被设计为不与 Kubernetes 绑定,并且倾向于为操作应用程序提供统一的接口。OAM 提出了组件和特性的概念,以对应用程序架构进行抽象。这对于原生 Kubernetes 用户来说是一个很大的变革,但这是有原因的。
在 Kubernetes 中,Deployment 或 Service 等资源侧重于实现。每种资源类型都提供特定的功能。一些低级功能,(如运行容器),会转到 Pod 等基本单元。一些更高级别功能,例如容器编排,处理回滚的功能,(例如 Deployment 或 StatefulSet),则是建立在较低级别的功能之上的。毫无疑问,“为平台构建者服务的平台”这个定位获得了巨大的成功。但对于应用开发人员来说,社区正在迫使他们成为 Kubernetes 专家才能使事情正常运行。此外,对低级资源的肤浅理解实际上可能导致不正确操作带来的显著风险。
组件
OAM 切入的视角与传统的解决方案显著不同。应用程序的真正组成是什么?应用程序开发人员需要什么?
运行应用程序的东西。对于应用程序来说,这绝对是最核心的部分。在 Kubernetes 中,它可以是 Deployment、Pods 或其他东西。在 Kubernetes 之外,它可以是 Docker 容器、虚拟机或云执行引擎。99.9% 的应用程序开发人员创建程序并运行它。OAM 将运行应用程序的整个内容定义为组件。它不仅仅是一组资源。没有组件,你将无法知道应用程序的用途。
apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: webserver-demo spec: components: - name: hello-world type: webserver # claim to deploy webserver component definition properties: # setting parameter values image: crccheck/hello-world port: 8000 # this port will be automatically exposed to public env: - name: "foo" value: "bar" cpu: "100m"
Pic 2. Example of a component inside an OAM application
随着微服务变得越来越普遍,许多应用程序开发人员开始将庞大的单体程序分解为小的部分。OAM 的定义中的每个可运行的部分都可以建模为一个组件,作为一个整体,它们共同组成了一个完整的 OAM 应用程序。它们的内部逻辑关系也在组件中绘制。
特性
要使应用程序正常运行,还需要其他一些东西。例如,在 Kubernetes 中,我们有 Service、ConfigMap、PersistentVolumeClaim 和许多其他资源,它们为 Deployment 提供特定的功能。但是这些资源是为了满足某些技术需求而创建的,而不是以目的为导向的。ConfigMap 为Kubernetes 用户提供了一种存储配置数据的方法,但要让容器使用该配置,用户需要在 Deployment 中添加卷部分并设置容器参数或环境变量。
如果我们再次改变视角,考虑应用程序开发人员在使用这些资源时真正想要做什么,我们可能会得出这样一个结论即许多资源都是为应用程序组件提供额外功能。创建 Service 或 Ingress 对象是为应用程序提供访问而创建的。PersistentVolumeClaim 和 Deployment 中的卷部分是为提供存储而创建的。 第三方对象(如 Prometheus 中的ServiceMonitor)用于提供观察规则。这些提供功能的辅助资源和修改在 OAM 中被定义为特性。
这些特性 Trait 不能独立工作。这些功能附加到组件并用作装饰。没有它,应用程序的主要目的不会改变,但会不完整。
apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: my-example-app spec: components: - name: publicweb type: web-ui properties: # properties targeting component parameters. image: example/web-ui:v1.0.2@sha256:verytrustworthyhash param_1: "enabled" # param_1 is defined on the web-ui component traits: - type: ingress # ingress trait providing a public endpoint for the publicweb component of the application. properties: # properties are defined by the trait CRD spec. This example assumes path and port. path: / port: 8080 - name: backend type: company/test-backend # test-backend is referenced from other namespace properties: debug: "true" # debug is a parameter defined in the test-backend component. traits: - type: scaler # scaler trait to specify the number of replicas for the backend component properties: replicas: 4
Pic 3. Example of an OAM application containing two components with traits attached
更多
除了 Component 和 Trait 之外,还有其他东西可以从不同的层面为应用程序工作。
每个应用程序可能包含多个原子功能单元,即 Component(组件),每个 Component 可以由多个 Trait 修饰。如果我们想定义一些与运行 Component 没有明确一对一关系的应用程序级别的行为或策略,需要更多的应用程序定义。
截至目前,OAM 还没有对这部分建模提出决定性的解决方案。已经提出了包括 Scope、Policy、Workflow、Scope 在内的一些概念,用于定义应用程序的使用范围。Policy 用于描述常见的策略和行为。Workflow 侧重于应用程序的交付方面。其中一些已被 KubeVela 采用,KubeVela 是基于 Kubernetes 的 OAM 实现之一,在模型的演进上可以帮助我们通过实践来驱动设计。
从理论到实践
开放应用模型(Open Application Model)的规范从概念上为那些希望从应用开发人员的角度对应用程序和构建平台进行建模的平台构建者们提供指导。在过去的几年中,包括 KubeVela、Crossplane、Verrazzano 和 Intuit 在内的采用者都做了各种尝试。尽管 OAM 规范被提出为与基础架构无关,但到目前为止,目前大部分的(功能)实现都是基于 Kubernetes 作为控制平面。
回顾历史,我们得出的结论是,在 Kubernetes 上进行应用程序建模尤为重要。在将 OAM 规范应用于 Kubernetes 时,KubeVela 做了很多工作来解决各种细节上的技术问题。这些问题又可以分为三个不同的方向:抽象、交付和管理。
抽象
OAM 中的组件定义了应用程序的运行实例。不同类型的组件适用于不同类型的运行实例。在 Kubernetes 中,它对应于不同的工作负载实现,如 Deployment 或 StatefulSet。KubeVela 将这些类型声明为 ComponentDefinition,并为可扩展性解决方案引入 CUE。CUE 用于模板化 Kubernetes 资源,因此平台构建者可以进行任意的自定义操作。
Pic 4. KubeVela leverages CUE for templating Component and Trait
在 Trait 这层,抽象的方法与 Component 类似,也就是用 TraitDefinition 来声明不同类型。与 Component 的主要区别之一是,某些类型的 Trait 需要对 Component Definition 所抽象的资源进行修改。例如,为了暴露端口,我们需要同时添加 Service 对象并在 Deployment 规范中暴露端口。CUE 本身并没有提供这样的方法,但是KubeVela 会以某种方式对 CUE 进行扩展来实现了这一功能。除静态渲染外,KubeVela 的抽象层还有运行时感知能力。这意味着渲染逻辑可以根据运行环境进行更改,就像它当前运行的 Kubernetes 版本一样。当 KubeVela 用作跨集群的统一控制平面时,这一点尤其有用。
Pic 5. In traditional system, application developer needs to deal with version upgrades across clusters
总之,与 Helm Chart 使用的 Go Template 或通过 Kustomization 做配置简化类似,KubeVela 中抽象层的实现在功能上是完整包含的。另一方面,KubeVela 将这些抽象基础建立在 ComponentDefinitions 和 TraitDefinitions 之上,以便更好地实现重用。与直接使用 Helm Chart 对整个应用程序进行模板化相比,这为平台构建者提供了更精细的选择。这反过来又为平台工程师和业务研发人员之间的职责划分提供了更清晰的界限:平台工程师负责 X-Definitions,业务研发负责应用程序。
Pic 6. KubeVela leaves the abstraction implementation to platform engineers and lets app developers to use predefined types of Components and Traits to compose Applications
交付
抽象层主要解决构建、打包和分发应用的问题。在交付应用程序并将它们作为统一的整体时,情况会变得更加复杂。应用程序作为一个整体,在 KubeVela 中,被视为是交付的基本单元。一个应用程序内部不同组件之间的关系可以决定如何交付这些组件,这些关系会在 dependsOn 字段中指示。
除了资源调度外,应用程序的交付有时还涉及更多,比如对生产环境的高风险交付进行人工审核、在自动交付完成时通知、跨多集群进行差异化交付等。为了让用户能够自定义交付过程,KubeVela 在应用程序模型中添加了 Workflow,其中 WorkflowStepDefinition 利用 CUE 定义原子执行单元。
Pic 7. KubeVela provides a consistent, programmable, declarative workflow to orchestrate app delivery process
一些用户可能会遇到多个关联应用程序进行交付的情况,KubeVela 甚至为此提供了更高级别的解决方案,称为 Pipeline。同时,应用程序模型是否应该与交付一起设计,也是一个有争议的问题。像 Tekton、Argo Workflow 这样的独立交付工具已经发展了多年。其他 CI 工具如 Jenkins 或 GitHub Actions 也在不断发展以支持各种交付场景。KubeVela 在将应用程序模型和交付流程结合在一起方面迈出了极为前瞻性的一步,因为它认为这种方法是将应用程序模型投入到生产使用的最佳实践。但是OAM 规范并没有急于添加工作流等内容,因为对于理论建模的答案仍需要更广泛的讨论。
管理
应用程序模型不仅用于交付,声明式 API 面向终态的能力也同样适用。因此,在实践中,应用程序模型也被用于 KubeVela 的一致性对比。KubeVela 确保在交付过程成功完成后不会偏离期望状态,这符合 Kubernetes 的最终面向状态的理念。
Pic 8. KubeVela constantly ensures there's no configuration drift for the delivered application
此外,KubeVela 还嵌入了许多其他管理操作,包括版本管理、权限控制、资源共享和垃圾回收。目前这些功能不包含在 OAM 规范中,但被认为是未来 OAM 规范的一部分。
总体而言,为了满足在 Kubernetes 上应用程序使用的各种需求,KubeVela 一直在 OAM 规范之外做不断的尝试,并探索更多可能的应用操作方式。
如果您对更多的技术细节感兴趣,请参阅此博客[2]。
未来
很多人质疑为什么 OAM 的 Github 仓库似乎不活跃了。对于主要关心生产实践和模型使用的人来说,答案是,KubeVela 作为 OAM 的 实现 一直在高速发展,采纳 KubeVela 的用户一直在增加,并且 KubeVela 刚刚成为一个 CNCF 孵化项目,这也意味着 OAM 模型的采纳者一直在快速增加。
至于理论模型,KubeVela 仍在等待来自工业生产实践的更多反馈和证据,我们不希望过快的对规范引入变更导致规范的稳定性出现问题。我们的计划是 KubeVela 的实践被广泛采用并逐渐稳定后,再向 OAM 规范提出其额外附加的概念,如工作流程或策略。我们希望在 CNCF基金会的帮助下越来越多的人能加入社区,使在现代化应用的部署和运维变得更容易、更高效、更可靠。
最后做个预告,在 4 月 17 日至 21 日即将举办的 KubeCon + CloudNativeCon Europe 2023 中,将有三场围绕 KubeVela 的话题分享,欢迎大家提前锁定,了解 KubeVela 最新的技术升级、社区动态和企业实践:
(*TimeZone:Europe/Amsterdam)
- Wednesday, April 19 • 15:25 - 16:00 :Building a Platform Engineering Fabric with the Kube API at Autodesk - Jesse Sanford & Greg Haynes, Autodesk
- Thursday, April 20 • 16:30 - 18:00 :Tutorial: Deploying Cloud-Native Applications Using Kubevela and OAM - Daniel Higuero, Napptive
- Friday April 21 • 11:00 - 11:35 :Challenges of Modern Application Delivery: A Retrospection of KubeVela Highlight Technologies - Jianbo Sun & Da Yin, Alibaba Cloud
您可以通过如下材料了解更多关于 KubeVela 以及 OAM 项目的细节:
- 项目代码库:https://github.com/kubevela/kubevela欢迎 Star/Watch/Fork!
- 项目官方主页与文档:kubevela.io ,从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢迎开发者进行翻译。
- 项目钉钉群:23310022;Slack:CNCF #kubevela Channel
- 加入微信群:请先添加以下 maintainer 微信号,表明进入 KubeVela 用户群:
相关链接:
[1] Open Application Model(OAM)
[2] 此博客
https://kubevela.net/blog/2022/11/29/retro-2022
点击此处查看 KubeVela 项目官网