作者:于磊春,中国移动云能力中心软件开发工程师,专注于云原生领域。
01
概述
云原生的理解:云原生继承于云计算,其中“原生”二字代表了从云计算(原生家庭)中继承了大部分的云计算的属性,在继承过程中也出现了类似于遗传学上的基因的碱基变化,这种核心变化主要体现在计算方式的改变,从之前的虚拟机、物理机变成了“容器”为核心的workload的计算方式,因此,对于不同的云计算环境能够具有较好的“亲和性”,目前已大步迈进云原生时代。
云原生时代下,云原生应用与日俱增,大名鼎鼎的k8s也是“容器”编排的利器,但是k8s未能提供以一个“应用”为约束的模型标准,我们在k8s上部署一个应用,承载这个应用的基础k8s资源有deployment、service、ingress、configmap等不同的组成部分,对于应用需要创建和管理(资源)的yaml文件对象,虽然可以使用helm charts来进行统一打包管理,但是helm charts不能代表这个应用的全部,如果缺少一个应用相应的依赖资源,需要对helm charts包进行添加修改,同时,k8s的接口模型过于复杂,未能突出不同用户的职责差异,OAM应运而生。
02
OAM基础介绍
OAM本质是助力构建“以应用为中心”的k8s标准规范和框架,OAM的出现,让应用构建越来越简略,实现基础设施主动匹配应用架构需要,k8s的出现本身定位是面向基础设施的,门槛相对较高,OAM的出现能够真正享受到云原生时代下平台化的红利,k8s本身不是面向开发者的一体化平台,需要在k8s上构建符合本身业务需要的paas平台来提升运维效率,同时,OAM模型助推云原生PaaS平台的发展,是一种对于不同平台和场景的逻辑进行的高级别抽象。
OAM框架优点:
(1)关注点分开,能够从应用开发、应用运维、平台基础设施提供不同视角;
(2)平台无关与高可扩展,应用定义和平台层实现解耦,应用能够支持(任意扩展、跨环境);
(3)模块化运维,可以自由组合和支持模块化实现运维。
OAM的核心思想是“职责分离”,为不同行为的用户暴露不同的接口模型,团队各司其职,所关注和使用的API模型也是因人而异,相比于复杂的K8S的API(没有职责划分),降低了很多操作成本。
OAM API演变:
名称 | v1alpha1 | v1alpha2 |
Component | ComponentSchematic | Component |
Trait | Trait | TraitDefinition |
Scope | Scope | ScopeDefinition |
Application configuration | ApplicationConfiguration | ApplicationConfiguration |
上述可以看出OAM模型对象的定义格式与k8s对象的类型字段相似,四个对象不同版本名称kind略有差异(使用时注意)。
OAM基本对象:
OAM采用“因人而异,按需管理”的思想,简化接口模型实现不同用户需求,是一个跨平台的标准,具体实现需要结合实际编排系统,当前以k8s为主,在其中的表现为CRD。
(1)应用组件(Component)--开发人员
实现应用的描述,OAM中所有模型以应用组件为基础,是OAM中基础单元,与底层无关,在k8s中启动OAM,会根据Component中的内容生成对应的Service等资源,四部分组成:
Metadata: 元信息,服务名称。
Workload type: 服务类型。
Parameters: 服务部署参数。
Containers: 容器运行时信息。
Case:
apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: alpine-forever-v1
spec:
workloadType: core.oam.dev/v1alpha1.SingletonServer
parameters:
- name: message
type: string
required: false
- name: unused_integer
type: number
required: false
default: 5678
containers:
- name: runner
image: technosophos/alpine-forever:latest
env:
- name: FOO
value: bar
fromParam: message
- name: UNUSED
value: "1234"
fromParam: unused_integer
复制
(2)Trait(TraitDefinition)--基础设施开发
应用配置(ApplicationConfiguration)中会为服务接入基础服务(Ingress网关等服务、环境变量),这些在OAM中是以trait的形式暴露,trait一般和特定服务类型绑定,从而给运维人员屏蔽了底层基础设施,三部分组成:
Metadata: 元信息,会在ApplicationConfiguration中通过名称来引用相应的trait。
AppliesTo: trait所关联的服务类型列表。
Properties: trait中依赖的配置。
Case:
apiVersion: core.oam.dev/v1alpha1
kind: Trait
metadata:
name: volume-mounter
spec:
appliesTo:
- core.oam.dev/v1alpha1.Server
- core.oam.dev/v1alpha1.SingletonServer
- core.oam.dev/v1alpha1.Worker
- core.oam.dev/v1alpha1.SingletonWorker
- core.oam.dev/v1alpha1.Task
- core.oam.dev/v1alpha1.SingletonTask
properties:
- name: volumeName
description: The name of the volume this backs. This matches the volume name declared in the ComponentSchematic.
type: string
required: true
- name: storageClass
description: The storage class that a PVC requires
type: string
required: true
复制
Trait是将通用的运维功能单独的封装起来,基础设施或中间件维护者负责将具体的业务后端用trait暴露,应用运维不需要感知业务组件,新的trait需要基础设施团队提供对应的后端,并根据OAM要求暴露给运维,目前官方有四种trait。
(3)Scope(ScopeDefinition)--基础设施开发
OAM在ApplicationConfiguration配置中通过Scope来给应用进行逻辑分组(多租户),并定义了服务运维的行为边界,一个应用可以分到多个分组中,运维可以通过Scope来聚合服务,目前官方提供了两种Scope(NetworkScope、HealthScope),Scope主要做两件事:为应用逻辑分组和为不同分组的应用执行不同的操作逻辑,三部分组成:
Metadata: 名称等元信息。
Parameters: Scope应用的参数
Type: Scope类型
Case:(以HealthScope为例)
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationScope
metadata:
name: health
spec:
allowComponentOverlap: true
parameters:
- description: The method to probe the components, e.g. 'httpGet'.
name: probe-method
required: true
type: string
- description: The endpoint to probe from the components, e.g. '/v1/health'.
name: probe-endpoint
required: true
type: string
- description: The amount of time in seconds to wait when receiving a response before
marked failure.
name: probe-timeout
required: false
type: integer
- description: The amount of time in seconds between probing tries.
name: probe-interval
required: false
type: integer
- description: If the rate of failure of total probe results is above this threshold,
declared 'failed'.
name: failure-rate-threshold
required: false
type: double
- description: If the rate of healthy of total probe results is above this threshold,
declared 'healthy'.
name: healthy-rate-threshold
required: false
type: double
- description: The % of healthy components required to upgrade scope
name: healthThresholdPercentage
required: false
type: double
- description: Comma-separated list of names of the components required to be healthy
for the scope to be health.
name: requiredHealthyComponents
required: false
type: string
type: core.oam.dev/v1alpha1.HealthScope
复制
和trait一样,scope的功能需要通过具体的业务后端实现,oam通过ApplicationScope来定义业务后端,scope也是依赖ApplicationConfiguration注入运行时数据。
(4)应用配置(ApplicationConfiguration)--运维人员
通过Component部署服务后,如何在编排平台实例化服务是由ApplicationConfiguration决定,比如Component中定义的Parameters中的参数,服务接入的基础服务、服务分组等都是由ApplicationConfiguration配置,四部分组成:
Metadata: 资源元信息。
Components: 需要实例化的Component信息,比如服务实例名。
Traits: 应用接入的trait信息。
ApplicationScope(Scope):应用分组。
Case:
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationConfiguration
metadata:
name: first-app
spec:
variables:
- name: SECTION_NUMBER
value: 3
components:
- componentName: nginx-component
instanceName: first-app-nginx
parameterValues(部署资源参数):
- name: poet
value: Eliot
- name: poem
value: The Wasteland
- name: section
value: "[fromVariable(SECTION_NUMBER)]"
traits(基础设施服务):
- name: ingress
properties:
hostname: example.com
path: /
servicePort: 80
applicationScopes(应用分组):
- my-health-scope
复制
综上,云原生应用通过OAM中的四大基础对象涵盖了从部署到运维的各项流程,大体如下:
在OAM规范下,研发和运维的关注点是完全分开的,研发和运维都是只要编写非常少的、和自己相关的一些字段,不是整个k8s的资源对象,就可以轻松发布应用,“上层抽象”带来的好处。
03
OAM工作原理及扩展介绍
很多人经过上述OAM基础介绍之后有两个疑惑?1、OAM模型定义的资源是通过什么工作机制转为k8s资源对象的?2、OAM面对用户五花八门的需求、差异的编排平台如何充分利用平台的特性,满足生产要求的?
第一个问题,OAM的工作原理,OAM spec定义了云原生应用的规范,OAM工作时通过对应的解析器,将应用定义翻译成k8s(基础设施)的资源对象,大体如下:
从上图可以看出三个层次:
*汇编层:最上层,通过工具或者人为手写出OAM规范定义汇编出云原生应用的定义,包含应用的工作负载和运维能力配置;
*转义层:汇编好的文件打包成yaml文件,有解析器(V1:Rudr V2:Crossplane)实现解析转义为k8s的或其他云服务的资源对象;
*执行层:执行经过转义的云平台上的资源对象并执行资源配置。
第二个问题,OAM提供了三个维度的扩展:WorkLoad Definitions、Trait Definition、Scope Definition,其中Trait和Scope,OAM的模型中只提供了暴露服务的API,具体还需要用户自己实现,这些主要由基础设施人员去实现,应用运维人员主要通过trait和scope实现基础服务和业务的对接工作,重点介绍WorkLoad Definitions。
WorkLoad Definitions为应用负载的描述,定义应用组件或trait时,都需要指定应用类型,应用类型是由workload definition指定,OAM平台(解析器)会将OAM定义的资源翻译为编排平台k8s的资源定义,应用类型则是决定翻译是如何进行的,应用类型也决定了服务是否对接特定的基础设施。
名称 | 类型 | 暴露地址 | 副本扩容 | 说明 |
Server | core.oam.dev/v1alpha1.server | 是 | 是 | 一般业务都属于Server,当应用属于Server时,OAM平台会为创建一个Deployment并关联k8s service |
SingletonServer | core.oam.dev/v1alpha1.SingletonServer | 是 | 否 | |
Task | core.oam.dev/v1alpha1.task | 否 | 是 | 执行脚本或程序,OAM平台会为其创建一个k8s JOb |
SingletonTask | core.oam.dev/v1alpha1.singletonTask | 否 | 否 | |
Worker | core.oam.dev/v1alpha1.worker | 否 | 是 | 一般用于不对外提供接口的守护服务,OAM平台会创建一个k8s deployment但是不关联service |
SingletonWorker | core.oam.dev/v1alpha1.singletonWorker | 否 | 否 |
以上只是列举了一部分服务类型,随着OAM不断完善,现如今已经能支持较多负载控制器的支持,场景不断丰富,OAM还支持两种扩展模式:
*直接在OAM的项目源码中增加新的服务类型;
*以插件化的方式扩展服务类型。OAM可以用户自己生成相应的应用组件和应用配置,用户需要自身实现Operator来监听CRD。
04
背景OAM与KubeVela
由CNCF应用交付领域小组、OAM社区、阿里云、微软云的OAM项目维护者共同在演讲中宣布的KubeVela开源项目正式发布,时间为2020年11月18日,它是一个简单易用且高度可扩展的平台,是基于k8s和OAM共同打造的。
KubeVela可以是一个“以应用为中心”的k8s发行版,以OAM为核心,让平台团队恶意基于Kubevela快速打造属于自己的PaaS、Serverless,甚至任何面向用户的云原生平台项目。
KubeVela里面的每一个功能,都是一个插件,作为平台团队,可以轻松的卸载和组合,打造自己需要的社区能力。
借着OAM中不同用户的角度来看KubeVela:
1、应用开发人员
应用开发者只需要编写Docker-Compose风格应用描述文件Appfile即可,不需要接触底层基础设施。
举一个应用开发人员操作KubeVela的例子
name: testapp
services:
express-server:
images: oamdev/testapp:v1
build:
docker:
file: Dockerfile
context: .
cmd: [“node”,”server.js”]
port: 8080
cpu: 0.01
route:
domain: example.com
rules:
- path: /testapp
rewirteTarget: /
dutoscale:
min: 1
max: 4
复制
上述应用开发人员主要编写20行配置文件,操作vela即可部署启动应用,并成功访问该应用。
Kubevela中存在一个巧妙设计,即Appfile是存在特殊性的,没有固定的Schema, Appfile中填写的每一个字段取决于OAM概念中的WorkLoad type和Trait,这种模块化设计使得Appfile是可扩展的。
2、平台开发人员
应用开发人员的友好体验离不开平台侧的创新性设计和实现,Kubevela不是一个简单的PaaS或者Serverless,是由一个可以由平台开发人员扩展成任意平台的云原生PaaS内核。具有三个核心能力:
(1)以应用为中心,上述Appfile的实现背后是基于之前介绍的OAM模型实现的,kubeVela让应用成为了整个平台对用户暴露的核心API。
(2)K8s原生高可扩展,Appfile是由workLoad Type和trait组成的、完全模块的对象,OAM模型的一个特点体现在任意一个k8s api资源都可以直接基于k8s的CRD发现机制注册成workload type和trait,Kubevela中每一个能力都是一个插件。
(3)简单友好高度扩展的用户侧抽象,kubevela在OAM模型中实现了集成CUE语言模板,通过此模板可以为平台工程师基于k8s api对象定义用户侧抽象提供配置工具,平台工程师可以随时修改,改动很小即可满足。
基于Kubevela,平台开发人员可以方便快捷地将任何k8s的社区能力封装抽象成一个面向用户的上层平台特性工具,应用开发者只需要学习上层抽象,简单描述一下Appfile配置文件即可一键交付。
▲ 点击上方卡片关注K8s技术圈,掌握前沿云原生技术