32

YAML 程序员眼中的 OAM

 4 years ago
source link: https://www.tuicool.com/articles/AbyYzm2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

OAM 的内容还是比较简单的,尝试用(Holy)YAML 对应用程序进行描述,其中核心组件包含了几个:

  • 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 就是在锁定横行的环境下,利用更高层次的抽象来打破旧锁定,造就新锁定的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK