YAML 工程师眼中的 OAM

原文链接:https://mp.weixin.qq.com/s/X9Pt1s-CPnZwyiRShEhOEQ

在 10.17 ,阿里云和微软联袂发布了一个有意思的新东西:OAM(开放应用模型)。这个项目要解决的问题是:用一致的、定义良好的模型来对应用进行描述。

Kubernetes 达成了一个小目标:不管是什么云,上面都有 Kubernetes 的一席之地。OAM 的小目标是什么呢?

OAM 尝试用对应用程序进行描述,其中核心组件包含了几个:

Component:组件交付物

Application Scope:部署目标

Traits:运维能力

Application Configuration:应用配置

一头雾水是吧?还好每个对象都提供了代码范例,可以拿来解释。

Component
一种类似 Pod 的东西。。。

apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: admin-backend
annotations:
version: v1.0.0
description: >
Sample component schematic that describes the backend for our Twitter bot.
spec:
workloadType: core.oam.dev/v1.SingletonServer
osType: linux
parameters:

  • name: twitter-access-token-secret
    description: Twitter API access token secret
    type: string
    required: true
    containers:
  • name: my-twitter-bot-backend
    image:
    name: example/my-twitter-bot-backend:1.0.0
    digest: sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b
    resources:
    cpu:
    required: 1.0
    memory:
    required: 100MB
    volumes:
    • name: config
      mountPath: /var/lib/my-twitter-bot/conf
      accessMode: RW
      sharingPolicy: Exclusive
      ports:
    • name: http
      value: 8080
      env:
    • name: TWITTER_ACCESS_TOKEN_SECRET
      fromParam: ‘twitter-access-token-secret’
      livenessProbe:
      httpGet:
      port: 8080
      path: /healthz
      readinessProbe:
      httpGet:
      port: 8080
      path: /healthz
      很像 Kubernetes 有没有?容器、参数、资源(外部加载卷的加载方式,类似 volumeMount 也定义在资源里)、端口和环境变量都是 YAML 程序员们很熟悉的东西。最值得注意的是 workloadType,工作负载的类型可以分为核心和扩展两个大类,其中核心工作负载有一个明确要求:所有实现本规范的平台必须支持核心工作负载。

核心工作负载有几个类型:

Server:可多实例运行的,对外提供服务的守护进程。

Singleton Server:只能单实例运行的,对外提供服务的守护进程。

Worker:能够多实例运行,不对外提供服务的守护进程。

Singleton Worker:不对外提供服务,不可复制的守护进程。

Task:不对外提供服务,可复制,非守护进程(一次性)。

Singleton Task:不对外提供服务,不可复制,非守护进程(一次性)。

另外这里还有一个字段叫 ConfigFile,用于存储配置内容。

在组件模型一节的尾部,给出了下面这样的例子:

apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: azurefunction
annotations:
version: v1.0.0
description: “Extended workflow example”
spec:
workloadType: azure.com/v1.Function
parameters:

  • name: github-token
    description: GitHub API session key
    type: string
    required: true
    workloadSettings:
    • name: source
      value: git://git.example.com/function/myfunction.git
    • name: github_token
      fromParam: github-token
      这个例子展示的是扩展类型的组件:从 git 拉取代码,用于提供 Function 服务。

Trait
一种运行平台中,针对特定工作负载进行运维支撑的能力,例如下面例子中的手动伸缩,似乎 Service Mesh 也应该名列此列?

apiVersion: core.oam.dev/v1alpha1
kind: Trait
metadata:
name: ManualScaler
annotations:
version: v1.0.0
description: “Allow operators to manually scale a workloads that allow multiple replicas.”
spec:
appliesTo:
- core.oam.dev/v1alpha1.Server
- core.oam.dev/v1alpha1.Worker
- core.oam.dev/v1alpha1.Task
properties:
type: object
properties: |
{
“$schema”: “http://json-schema.org/draft-07/schema#”,
“type”: “object”,
“required”: ["replicaCount],
“properties”: {
“replicaCount”: {
“type”: “integer”,
“description”: “the target number of replicas to scale a component to.”,
“minimum”: 0
}
}
}
这里定义了一个用来做手动伸缩的 Trait,它仅适用于第一节中提到的几个可伸缩的工作负载类型。这个 Traits 仅包含一个必要字段,用于设置副本数量。

但是在 YAML 里面包 JSON 真的好吗?

Application Scopes
百撕不得其解的一个概念。通过外部设施,如网络或者健康对应用范围进行划分,把应用进行聚合。
并且在 Application Configuration 中作为一个部署目标进行实例化。

apiVersion: core.oam.dev/v1alpha1
kind: ApplicationScope
metadata:
name: health
annotations:
version: v1.0.0
description: “aggregated health state for a group of components.”
spec:
type: core.oam.dev/v1alpha1.HealthScope
allowComponentOverlap: true
parameters:
- name: probe-method
description: The method to probe the components, e.g. ‘httpGet’.
type: string
required: true

- name: required-healthy-components
description: Comma-separated list of names of the components required to be healthy for the scope to be health.
type: []string
required: false
Application Configuration
前面的几个概念中,描述了组件的定义、平台提供的运维能力、以及应用的部署范围,最终应用要运行起来,需要进行一个部署过程,部署过程除了把前面提到的对象组合起来之外,还需要加入一些配置内容。本对象就是用来完成这一功能的。

apiVersion: core.oam.dev/v1alpha1
kind: ApplicationConfiguration
metadata:
  name: my-vpc-network
 spec:
  variables:
   - name: networkName
    value: "my-vpc"
 scopes:
- name: network
  type: core.oam.dev/v1alpha1.Network
  properties:
    - name: network-id
      value: "[fromVariable(networkName)]"
    - name: subnet-id
      value: "my-subnet"

apiVersion: core.oam.dev/v1alpha1
kind: ApplicationConfiguration
metadata:
name: custom-single-app
annotations:
version: v1.0.0
description: “Customized version of single-app”
spec:
variables:
- name: message
value: “Well hello there”
- name: domainName
value: “www.example.com”
components:
- componentName: frontend
instanceName: web-front-end
parameterValues:
- name: message
value: “[fromVariable(message)]”
traits:
- name: Ingress
properties:
- name: host
value: “[fromVaraible(domainName)]”
- name: path
value: “/”
applicationScopes:
- my-vpc-network

- componentName: backend
  instanceName: database
  applicationScopes:
    - my-vpc-network

这一组文件对象完成了几个任务:

创建了一个网络类型的 Application Scope,my-vpc-network。

引用一个叫做 frontend 的组件,生成 web-front-end 对象,并赋予参数 message。

为 web-front-end 提供一个 Ingress 对象。

将两个实例部署在 my-vpc-network。

后记
这几个对象里,基本形成了一个从交付物到运维的恒源定义,并且也直接使用 Rust 实现了基于这一规范的工具。符合这个规范的应用,就能能够在支持 OAM 的平台上进行运行和运维,虽然应用自身的结构、拓扑、构建、观测还有很多元素要实现,但是这些基础元素,应该已经能够发挥很好的示范效果了。

印象里 OAM 的新闻稿里有一句话,OAM 和其他应用模型是不同的,它没有供应商锁定问题,因为它是构建在 Kubernetes 的基础之上的:Kubernetes 就是在锁定横行的环境下,利用更高层次的抽象来打破旧锁定,造就新锁定的。

转载 https://mp.weixin.qq.com/s/X9Pt1s-CPnZwyiRShEhOEQ

上一篇:开放应用模型操作指南(一)| 云服务一键接入 OAM 体系


下一篇:MySQL内核月报 2015.01-MySQL · 优化改进· 复制性能改进过程