KubeVela

KubeVela

KubeVela 是一个基于 Go 语言开发的云原生平台级开源项目,这套内核系统诞生自 2019 年年底阿里云联合微软共同推出的 Open Application Model(简称 OAM:https://oam.dev/)模型基于 Kubernetes 的实现。KubeVela 是一个面向平台构建者的、简单易用但又高度可扩展的云原生平台构建引擎。

具体来说,KubeVela 的目标是让任何平台团队都能够以 Kubernetes 原生的方式,快速、高效的打造出适合不同业务场景的、能够直面用户的云原生平台出来。比如:构建应用 PaaS、数据库 PaaS、AI PaaS 或者持续交付系统等等。

KubeVela “关注点分离”的工作流

在设计上,KubeVela 对平台团队暴露了两大核心 API,包括:

  • 能力模板:“能力”在 KubeVela 中,指能够组成一个完整应用的原子化功能,比如 StatefulSet 和 Ingress 就属于两种不同的“能力”。KubeVela 允许平台团队通过定义各种能力“模板”的方式,在 Kubernetes 中预置各种各样的能力。
  • 部署环境模板:与“能力”类似,应用的部署环境在 KubeVela 中通过“环境”模板来进行预定义和初始化,比如“测试集群”和“生产集群”,就属于两种“环境”。

而作为平台的用户,比如业务团队,他们只需要通过平台团队提供的环境模板来“一键”初始化自己预期的部署集群,然后把自己需要的能力模板“组装”成一个完整的应用,就可以直接向任何 Kubernetes 集群进行应用交付和运维了。

由于上述这些能力和环境,都通过“模板”的方式进行了抽象,所以对于业务团队来说,它们并不需要学习完整的 Kubernetes 概念与细节,只需要了解上述模板暴露出来的参数,就可以无缝的使用 Kubernetes 来完成自己要做的事情。而具体通过模板暴露出哪些可配置项、背后的模板怎么渲染、渲染成什么样 Kubernetes 对象,则完全全在平台团队的掌控之中,并且可以随时调节和修改。

快速构建抽象

构建“抽象”,是任何一个云原生平台的最基础、也必然会提供的功能。我们知道,Kubernetes 暴露出来的是一套声明式 API,而所谓抽象,其实就是一个平台在这些声明式 API 的基础上,为用户暴露出来的可操作项和可配置项。作为平台团队,我们之所以要提供“抽象”,其最终目的都是为了简化用户的使用心智,让业务团队只关注他们关心的事情,避免引入大量与业务无关的平台层细节让用户“望而却步”。可以说,提供“抽象”,是任何一个平台团队落地 Kubernetes 等系统级开源项目的第一步。

业界最常见的抽象方式,是给用户提供一个图形界面来进行操作(比如 Console 或者 Dashboard),这些图形界面的共同点,就是仅允许用户填写某些特定的字段参数,从而实现简化用户心智的目的。那么,作为平台团队,我们又是怎么来决定给用户暴露哪些可配置参数呢?这就涉及到了“抽象”的三种基础模式(更复杂的情况都是对这三种模式的进一步组合):

  • 组合抽象,这种模式常见于我们把 2 个原子能力组合成为一个能力提供,比如我们在实际开发 Console 时,经常会把 K8s Deployment 和 Service 进行“组合”,暴露出一个 Web Service 的概念来让用户可以在一个表单里同时定义容器镜像和暴露端口。

  • 拆分抽象,这种模式常见于我们希望在使用流程上把一个对象上的字段分开成几个表单来进行分步骤填写,从而解耦部署时与运维时的配置。比如一个 Pod 里面的多个容器,我希望在第一个表单里让用户填写业务容器,在另一个表单让运维填写 Sidecar 容器。再比如 ArgoRollout 这个对象,我会希望一个表单让用户填写容器镜像,另一个表单让运维填写灰度策略。

  • 转换抽象,这种模式通常用于改个名字,或者说去掉一些无关的概念,比如 Knative Revision 跟 Deployment 本质上是一一对应的,但是里面类似 LabelSelector 这种用户不需要关心的字段在 Knative 就会直接去掉了。

常见抽象模式

上述几种抽象的模式,在业界的很多平台级项目和产品中都有体现。但另一方面,如何正确的设计抽象,以及如何确保抽象能够满足业务方用户的使用需求和习惯,其实是一个非常具备挑战性的问题。这里的关键点在于,无论是图形化界面,还是 CRD Operator,这些“抽象”一旦上线,对它的修改就非常困难。可是另一方面,业务方用户的需求,又几乎不可能是一成不变的(实际情况甚至是“一天一个样”)。