从微服务到 Serverless:OAM 模型如何统一应用描述与交付

应用描述方式五花八门——Docker Compose、Helm Chart、K8s YAML、Terraform——OAM 试图用一个统一的模型解决应用定义的碎片化问题。

YAML 地狱:每个 K8s 用户的切肤之痛

部署一个微服务到 Kubernetes 需要多少 YAML?

一个 Deployment、一个 Service、一个 Ingress、一个 ConfigMap、一个 HPA、若干 Secret。六个微服务就是六套。三套环境(dev/staging/prod)乘以六就是十八套。每套还有几十个字段要填——replicasresources.limitslivenessProbereadinessProbenodeSelectortolerationsaffinitysecurityContext……

这还没算上 Helm values.yaml、Kustomize overlay、Terraform tfvars。同一个应用的"定义"散落在四五种格式里,每种格式有自己的语法、自己的模板引擎、自己的生态。开发者写一份 Docker Compose 跑本地开发,SRE 写一份 Helm Chart 做线上部署,DBA 再写一份 Terraform 管基础设施。同一个应用被描述了三四遍,每遍还不一定对得上。

这就是应用定义的碎片化问题。OAM 试图给出一个统一答案。

OAM 是什么:三个核心概念

OAM(Open Application Model)是 2019 年由微软和阿里云联合提出的开放规范,目标是:用一套标准化的模型描述应用,让应用的定义与底层运行平台解耦。

OAM 的核心只有三个概念:

Component(组件):应用的基本构建块。一个微服务是一个 Component,一个数据库是一个 Component,一个消息队列也是一个 Component。Component 定义的是"这个工作负载是什么"——镜像、端口、参数——而不关心它跑在哪里。

Trait(特征):挂载在 Component 上的运维策略。自动扩缩容是一个 Trait,Ingress 路由是一个 Trait,日志采集也是一个 Trait。Trait 回答的是"这个组件怎么运行"——副本数、流量策略、监控配置。

Scope(作用域):组件的分组和边界。同一个应用里的多个 Component 可以共享一个网络域(Network Scope),也可以归属同一个健康检查域(Health Scope)。Scope 解决的是"这些组件之间的关系是什么"。

三个概念加起来,就够描述绝大多数云原生应用了。

为什么重要:开发者和运维的权责分离

OAM 的设计哲学里有一条关键原则:应用开发者不应该关心基础设施细节,基础设施运维者不应该被迫理解业务逻辑。

在 K8s 的现实里,这条原则几乎不存在。开发者要么被迫学习 K8s YAML 的全部细节,要么把定义权完全交给 SRE 然后等排期。OAM 把这条边界画清楚了:

  • 开发者负责定义 Component:我的服务用什么镜像、监听什么端口、需要什么环境变量
  • 运维者负责绑定 Trait:这个 Component 需要几个副本、走什么 Ingress、配什么 HPA 策略

双方各写各的 YAML,通过 Component 名字关联。开发者不需要知道 Trait 的实现细节,运维者不需要知道业务代码的逻辑。这种关注点分离在 Helm Chart 里是做不到的——一个 values.yaml 里同时混杂了业务参数和运维配置,谁改谁紧张。

架构拆解:从 Component 到 ApplicationConfiguration

OAM 的资源模型在 K8s 上通过 CRD 实现。一个完整的 OAM 应用由以下资源组成:

1
2
3
4
5
6
7
ComponentDefinition       # 定义组件类型(如 webservice、worker、task)
Component                  # 具体的组件实例(引用 ComponentDefinition)
TraitDefinition            # 定义运维能力(如 ingress、scaler、annotations)
ApplicationConfiguration   # 将 Component 和 Trait 组装在一起

一个实际的 OAM 定义大概长这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: my-app
spec:
  components:
    - name: backend
      type: webservice
      properties:
        image: myregistry/backend:v2.1
        port: 8080
        cpu: "0.5"
        memory: "512Mi"
      traits:
        - type: autoscaler
          properties:
            min: 2
            max: 10
            cpu-utilization: 70
        - type: ingress
          properties:
            domain: api.example.com
            path: /v1
    - name: frontend
      type: webservice
      properties:
        image: myregistry/frontend:v2.1
        port: 3000
      traits:
        - type: ingress
          properties:
            domain: www.example.com
            path: /

注意这里没有任何 K8s 原生资源——没有 Deployment、没有 Service、没有 Ingress 的直接定义。OAM 运行时(如 KubeVela)负责将这些高级抽象翻译成底层的 K8s 资源。开发者写的 YAML 从 200 行缩减到 30 行,而且每一行都是业务语义,不是基础设施细节。

横向对比:四种应用描述方式

维度Docker ComposeHelmOAMTerraform
定位本地多容器编排K8s 包管理器应用定义模型基础设施编排
抽象层次容器级别K8s 资源级别应用级别资源级别
模板机制无(纯 YAML)Go Template无(声明式 CRD)HCL
平台绑定DockerKubernetes平台无关云厂商 API
角色分离弱(values 混杂)强(Component/Trait)不适用
可移植性差(K8s only)中等
生态成熟度

Docker Compose 是本地开发的事实标准,但它只能跑在单机 Docker 上。Helm 是 K8s 生态最成熟的包管理方案,但它的模板系统复杂到需要专门学习,而且 values.yaml 经常膨胀到上千行。Terraform 管基础设施很强,但它不关心应用本身。

OAM 填补的空隙是:一个平台无关的应用定义层,向上对接开发者的业务意图,向下适配各种运行平台(K8s、ECS、Serverless、边缘节点)。它不是要替代 Helm 或 Terraform,而是在它们之上提供一个统一的应用描述接口。

落地现状:谁在用,怎么用

OAM 最成熟的实现是 KubeVela,由阿里云主导开发,已经是 CNCF 孵化项目。在国内的落地场景主要集中在:

多环境交付:同一份 OAM 应用定义,通过切换 Trait 绑定,分别部署到 dev/staging/prod。开发者只维护一份 Component 定义,环境差异由运维者在 Trait 层控制。

PaaS 平台构建:很多企业用 KubeVela 搭建内部 PaaS。开发者在 UI 上选择组件类型、填写参数,平台自动生成 OAM 定义并部署。底层的 K8s 细节对开发者完全透明。

混合云部署:OAM 的平台无关性在混合云场景里有天然优势。同一个应用定义可以同时部署到公有云 K8s 和私有云 ECS,只需要适配不同的 Trait 实现。

不过也要说实话:OAM 的社区活跃度相比 Helm 和 Terraform 还有差距。大多数团队依然选择直接写 K8s YAML 或用 Helm,OAM 更多出现在中大型企业的平台工程实践中。

缺失的抽象层

云原生技术栈从底向上已经非常成熟:容器运行时(containerd)、编排引擎(K8s)、服务网格(Istio)、可观测性(Prometheus/Grafana)。但在"应用"这一层,始终没有一个标准化的描述模型。

OAM 试图成为这一层。它的价值不在于替代现有工具,而在于提供一个稳定的抽象接口——让应用定义不再跟特定平台、特定模板引擎绑定。当底层平台从 K8s 迁移到 Serverless,或者从公有云切换到边缘计算,应用定义本身不需要重写。

从 SOA 到微服务到 Serverless,架构范式一直在变,但"如何描述一个应用"这个问题始终没有被很好地回答。OAM 是目前最接近答案的尝试。它不一定能赢,但方向是对的。

广告
广告位预留中 (728x90)