作者:
劉洋(炎尋) EDAS-OAM 架構與開發負責人
鄧洪超 OAM spec maintainer
孫健波(天元) OAM spec maintainer
随着以 K8s 為主的雲原生基礎架構遍地生根,越來越多的團隊開始基于 K8s 搭建持續部署、自助式釋出體驗的應用管理平台。然而,在 K8s 傳遞和管理應用方面,目前還缺乏一個統一的标準,這最終促使我們與微軟聯合推出了首個雲原生應用标準定義與架構模型 - OAM。本文作者将從基本概念以及各個子產品的封裝設計與用法等角度出發來詳細解讀 OAM。
OAM 主要有三個特點:
- 開發和運維關注點分離:開發者關注業務邏輯,運維人員關注運維能力,讓不同角色更專注于領域知識和能力;
- 平台無關與高可擴充:應用定義與平台實作解耦,應用描述支援跨平台實作和可擴充性;
- 子產品化應用部署和運維特征:應用部署和運維能力可以描述成高層抽象子產品,開發和運維可以自由組合和支援子產品化實作。
OAM 綜合考慮了在公有雲、私有雲以及邊緣雲上應用傳遞的解決方案,提出了通用的模型,讓各平台可以在統一的高層抽象上透出應用部署和運維能力,解決跨平台的應用傳遞問題。同時,OAM 以标準化的方式溝通和連接配接應用開發者、運維人員、應用基礎設施,讓雲原生應用傳遞和管理流程更加連貫、一緻。
角色分類
OAM 将應用相關的人員劃分為 3 個角色:
- 應用開發:關注應用代碼開發和運作配置,是應用代碼的領域專家,應用開發完成後打包(比如鏡像)交給應用運維;
- 應用運維:關注配置和運作應用執行個體的生命周期,比如灰階釋出、監控、報警等操作,是應用運維專家;
- 平台運維:關注應用運作平台的能力和穩定性,是底層(比如 Kubernetes 運維/優化,OS 等)的領域專家。
核心概念
OAM 包含以下核心概念:
服務元件(Component Schematics)
應用開發使用服務元件來聲明應用的屬性(配置項),運維人員定義這些屬性之後就能按照元件聲明得到運作的元件執行個體,元件聲明包含以下資訊:
- 工作負載類型(Workload type):表明該元件運作時的工作負載依賴;
- 中繼資料(Metadata):面向元件使用者的一些描述性資訊;
- 資源需求(Resource requirements):元件運作的最小資源需求,比如最小記憶體,CPU 和檔案挂載需求;
- 參數(Parameters):可以被運維人員配置的參數;
- 工作負載定義(Workload definition):工作負載運作的一些定義,比如可運作包定義(ICO images, Function等)。
應用邊界(Application Scopes)
運維人員使用應用邊界将元件組成松耦合的應用,可以賦予這組元件一些共用的屬性和依賴,應用邊界聲明包含以下資訊:
- 中繼資料(Metadata):面向應用邊界使用者的一些描述性資訊。
- 類型(Type):邊界類型,不同類型提供不同的能力;
- 參數(Parameters):可以被運維人員配置的參數。
運維特征(Traits)
運維人員使用運維特征賦予元件執行個體特定的運維能力,比如自動擴縮容,一個 Trait 可能僅限特定的工作負載類型,它們代表了系統運維方面的特性,而不是開發的特性,比如開發者知道自己的元件是否可以擴縮容,但是運維可以決定是手動擴縮容還是自動擴縮容,特征聲明包含以下資訊:
- 中繼資料(Metadata):面向特征使用者的一些描述性資訊;
- 适用工作負載清單(Applies-to list):該特征可以應用的工作負載清單;
- 屬性(Properties):可以被運維人員配置的屬性。
工作負載類型和配置(Workload types and configurations)
描述特定工作負載的底層運作時,平台需要能夠提供對應工作負載的運作時,工作負載聲明包含以下資訊:
- 中繼資料(Metadata):面向工作負載使用者的一些描述性資訊;
- 工作負載設定(Workload Setting):可以被運維人員配置的設定。
應用配置(Application configuration)
運維人員使用應用配置将元件、特征和應用邊界的組合在一起執行個體化部署,應用配置聲明包含以下資訊:
- 中繼資料(Metadata):面向應用配置使用者的一些描述性資訊;
- 參數覆寫(Parameter overrides):可以了解為變量定義,可以被元件、特征、應用邊界的參數引用;
- 元件設定(Component):構成應用的全部元件都在這裡設定;
- 綁定元件的運維特征配置(Trait Configuration):綁定的特征清單及其參數。
OAM 認為:
一個雲原生應用由一組互相關聯但又離散獨立的元件構成,這些元件執行個體化在合适的運作時上,由配置來控制行為并共同協作提供統一的功能。
更加具體的說:
一個 Application 由一組 Components 構成,每個 Component 的運作時由 Workload 描述,每個 Component 可以施加 Traits 來擷取額外的運維能力,同時我們可以使用 Application scopes 将 Components 劃分到 1 或者多個應用邊界中,便于統一做配置、限制、管理。
整體的運作模式如下所示:

元件、運維特征、應用邊界通過應用配置(Application Configuration)執行個體化,然後再通過 OAM 的實作層翻譯為真實的資源。
怎麼用?
使用 OAM 來管理雲原生應用,其核心主要是圍繞着“四個概念,一個動作”。
四個概念
- 應用元件(包含對工作負載的依賴聲明);【開發人員關心】
- 工作負載;【平台關心】
- 運維特征;【平台關心】
- 應用邊界;【平台關心】
一個動作
- 下發應用配置;【運維人員關心】
下發應用配置之後 OAM 平台将會執行個體化四個概念得到運作的應用。
一個 OAM 平台在對外提供 OAM 應用管理界面時,一定是預先已經準備好了“運維特征,應用邊界”供運維人員使用,準備好了“工作負載”供開發者使用,同時開發者準備“元件”供運維人員使用。是以角色劃分就很明了:
- 開發者提供元件,使用平台的工作負載;
- 運維人員關注一個動作執行個體化四個概念;
- 平台方需要提供工作負載,運維特征,應用邊界,并且托管使用者的應用元件;
例子
如何使用上面“四個概念,一個動作”來部署一個 OAM 應用呢?
我們假想一個場景,使用者的應用有兩個元件:frontend 和 backend,其中 frontend 元件需要域名通路、自動擴縮容能力,并且 frontend 要通路 backend,兩者應該在同一個 vpc 内,基于這個場景我們需要有:
- 開發者建立 2 個元件
frontend 的 workload 類型是 Server 容器服務(OAM 平台提供該工作負載):
apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: frontend
annotations:
version: v1.0.0
description: "A simple webserver"
spec:
workloadType: core.oam.dev/v1.Server
parameters:
- name: message
description: The message to display in the web app.
type: string
value: "Hello from my app, too"
containers:
- name: web
env:
- name: MESSAGE
fromParam: message
image:
name: example/charybdis-single:latest
backend 的 workload 是 Cassandra(OAM 平台提供該工作負載):
apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: backend
annotations:
version: v1.0.0
description: "Cassandra database"
spec:
workloadType: data.oam.dev/v1.Cassandra
parameters:
- name: maxStalenessPrefix
description: Max stale requests.
type: int
value: 100000
- name: defaultConsistencyLevel
description: The default consistency level
type: string
value: "Eventual"
workloadSettings:
- name: maxStalenessPrefix
fromParam: maxStalenessPrefix
- name: defaultConsistencyLevel
fromParam: defaultConsistencyLevel
- OAM 平台提供 Ingress Trait
apiVersion: core.oam.dev/v1alpha1
kind: Trait
metadata:
name: Ingress
spec:
type: core.oam.dev/v1beta1.Ingress
appliesTo:
- core.oam.dev/v1alpha1.Server
parameters:
properties: |
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"host": {
"type": "string",
"description": "ingress hosts",
},
"path": {
"type": "string",
"description": "ingress path",
}
}
}
- OAM 平台提供網絡應用邊界
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationScope
metadata:
name: network
annotations:
version: v1.0.0
description: "network boundary that a group components reside in"
spec:
type: core.oam.dev/v1.NetworkScope
allowComponentOverlap: false
parameters:
- name: network-id
description: The id of the network, e.g. vpc-id, VNet name.
type: string
required: Y
- name: subnet-ids
description: >
A comma separated list of IDs of the subnets within the network. For example, "vsw-123" or ""vsw-123,vsw-456".
There could be more than one subnet because there is a limit in the number of IPs in a subnet.
If IPs are taken up, operators need to add another subnet into this network.
type: string
required: Y
- name: internet-gateway-type
description: The type of the gateway, options are 'public', 'nat'. Empty string means no gateway.
type: string
required: N
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-ids
value: "my-subnet1, my-subnet2"
- 應用運維部署整個應用
使用應用配置将上面的元件、邊界、特征組合起來即可部署一個應用,這個由應用的運維人員提供:
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
通過以上完整的使用流程我們可以看到:應用配置是真正部署應用的起點,在使用該配置的時候,對應的元件、應用邊界、特征都要提前部署好,運維人員隻需做一個組合即可。
服務元件(Component Schematic)
服務元件的意義是讓開發者聲明離散執行單元的運作時特性,可以用 JSON/YAML 格式來表示,其聲明遵循 Kubernetes API 規範,差別在于:
- 定義字段是 Kubernetes 的子集,因為 OAM 是更高的抽象;
- OAM Spec 的底層運作時可以不是 Kubernetes
下面我們來看看具體的元件聲明如何定義。
定義
頂層屬性
屬性 | 類型 | 必填 | 預設值 | 描述 |
---|---|---|---|---|
apiVersion | string | Y | 特定oam spec版本,比如core.oam.dev/v1 | |
kind | 類型,對于元件來說就是 ComponentSchematic | |||
metadata | Metadata | 元件中繼資料 | ||
spec | Spec | 元件特定的定義屬性 |
name | ||||
labels | map[string]string | N | k/v對作為元件的lebels | |
annotations | k/v對作為元件的描述資訊 |
parameters | []Parameter | 元件的可配置項 | ||
workloadType | 簡明語義化的元件運作時描述,以K8s為例就是指定底層使用StatefulSet還是Deployment這樣 | |||
osType | linux | 元件容器運作時依賴的作業系統類型,可選值: - linux - windows | ||
arch | amd64 | 元件容器運作時依賴的CPU架構,可選值: - i386 - amd64 - arm - arm64 | ||
containers | []Container | 實作元件的OCI容器們 | ||
workloadSettings | []WorkloadSettings | 需要傳給工作負載運作時的非容器配置聲明 |
上面的 workloadType 後面會有詳細說明,這裡簡要來說就是開發者可以指定該 field 告訴運作時該元件如何被執行。工作負載命名的規範是 GROUP/VERSION.KIND,和 K8s 資源類型坐标一緻,比如:
- core.oam.dev/v1alpha1.Singleton
core.oam.dev 表示是 oam 内置的分組,oam 内置的表示任何 OAM 實作都支援該類型的工作負載,v1alpha1 表示依舊是 alpha 狀态,類型是 Singleton,這表示運作時應該隻運作一個元件執行個體,無論誰提供。
- alibabacloud.com/v1.Function
alibabacloud.com 表示該對象是一個營運商特定的實作,不一定所有平台都實作,版本 v1 表示實作已經穩定,類型是 Function 表示運作時是 Alibaba Functions 提供的。
- streams.oam.io/v1beta2.Kafka
表示該對象是一個第三方組織實作,不一定所有平台都實作,版本 v1beta2 表示實作已經趨于穩定,類型是 Kafka 表示運作時是開源元件 Kafka 提供的。
工作負載主要分為兩類:
- 核心工作負載類型
屬于 core.oam.dev 分組,所有對象都需要 oam 平台實作,都是容器運作時,該 Spec 目前定義了如下核心工作負載類型:
名字 | 是否對外提供服務 | 是否可以多副本運作 | 是否常駐 | |
---|---|---|---|---|
Server | core.oam.dev/v1alpha1.Server | |||
Singleton Server | core.oam.dev/v1alpha1.SingletonServer | |||
Worker | core.oam.dev/v1alpha1.Worker | |||
Singleton | core.oam.dev/v1alpha1.SingletonWorker | |||
Task | core.oam.dev/v1alpha1.Task | |||
Singleton Task | core.oam.dev/v1alpha1.SingletonTask |
- Server:定義了容器運作時可以運作 0 或多個容器執行個體,該工作負載提供了備援的可擴縮容的多副本常駐服務,在 K8s 平台可以使用 Deployment 或者 Statefulset 加上 Service 來實作;
- Singleton Server:定義了容器運作時隻能運作一個容器執行個體,該工作負載提供了無法備援的單副本常駐服務,在 K8s 平台可以使用副本為 1 的 Statefulset 加上 Service 來實作;
- Worker:定義了容器運作時可以運作 0 或多個容器執行個體,該工作負載提供了備援的可擴縮容的多副本常駐執行個體但是不提供服務,在 K8s 平台可以使用 Deployment 或者 Statefulset 來實作;
- Singleton Worker:定義了容器運作時隻能運作一個容器執行個體,該工作負載提供了無法備援的單副本常駐執行個體但是不提供服務,在 K8s 平台可以使用副本為 1 的 Statefulset 來實作;
- Task:定義了非常駐可備援的容器運作時,運作完就退出,可以賦予擴縮容特性,在 K8s 平台可以使用 Job 來實作;
- Singleton Task:定義了非常駐非備援的容器運作時,運作完就退出,在 K8s 平台可以使用 completions=1 的 Job 來實作。
核心工作負載必須給定 container 部分,實作核心工作負載的 OAM 平台必須不依賴 workloadSettings。
- 擴充工作負載類型
擴充工作負載類型是平台運作時特定的,由各個 OAM 平台自定提供,目前版本的 Spec 不支援使用者自定義工作負載類型,隻能是平台方提供,擴充工作負載可以使用非容器運作時,workloadSettings 的目的就是為了擴充工作負載類型的配置。
工作負載的定義是包羅萬象的,他允許任何部署的服務作為工作負載,無論是容器化還是虛拟機,基于此,我們可以将緩存,資料庫,消息隊列都作為工作負載,如果元件指定的工作負載在平台沒有提供,應該快速失敗将資訊傳回給使用者。
除了 WorkloadType,可以看到元件 Spec 内嵌了 3 種結構體,下面來看看它們的定義:
1.Parameter
定義了該元件的所有可配置項,其定義如下:
description | 元件的簡短描述 | |||
type | 參數類型,JSON定義的boolean, number, ... | |||
required | boolean | false | 參數值是否必須提供 | |
default | 同上面的type | 參數的預設值 |
2.Container
容器名字,在元件内必須唯一 | ||||
iamge | 鏡像位址 | |||
resources | Resources | 鏡像運作最小資源需求 | ||
env | []Env | 環境變量 | ||
ports | []Port | 暴露端口 | ||
livenessProde | HealthProbe | 健康狀态檢查指令 | ||
readinessProbe | 流量可服務狀态檢查指令 | |||
cmd | []string | 容器運作入口 | ||
args | 容器運作參數 | |||
config | []ConfigFile | 容器内可以通路的配置檔案 | ||
imagePullSecrets | 拉取容器的憑證 |
其中 Resources 的定義如下:
cpu | CPU | 容器運作所需的cpu資源 | ||
memory | Memory | 容器運作所需的memory資源 | ||
gpu | GPU | 容器運作所需的gpu資源 | ||
volumes | []Volume | 容器運作所需的存儲資源 | ||
extended | []ExtendedResource | 容器運作所需的外部資源 |
其中 CPU/Memory/GPU 都是數值型,不贅述,Volume 的定義如下:
資料卷的名字,引用的時候使用 | ||||
mountPath | 實際在檔案系統的挂載路徑 | |||
accessMode | RW | 通路模式,RW或RO | ||
sharingPolicy | Exclusive | 挂載共享政策,Exclusive或者Shared | ||
disk | Disk | 該資料卷使用底層磁盤資源的屬性 |
Disk 指定存儲是否需要持久化,最小的空間需求,定義如下:
最小磁盤大小需求 | ||||
ephemeral | 是否需要挂載外部磁盤 |
ExtendedResource 描述特定實作的資源需求,比如 OAM 運作時平台可能提供特殊的硬體,這個字段允許容器聲明需要這個特定的 offering:
需要的條件 | ||||
資源名字,比如GV.K |
Env,Port,HealthProbe 和 K8s 類似,這裡不再贅述。
3.WorkloadSetting
工作負載的附加配置,用于非容器運作時(當然,也可以用于容器運作時工作負載的附加字段)。
參數名 | ||||
參數類型,用于實作的hint | ||||
value | any | 參數值,如果沒有fromParam則用該值 | ||
fromParam | 參數引用,覆寫value |
這組配置會傳給運作時,一個運作時可以傳回錯誤,如果特定的限制沒有滿足,比如:
- 丢失了期望的 k/v 對;
- 不認識的 k/v 對;
使用核心工作負載 Server 的元件聲明
apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: frontend
annotations:
version: v1.0.0
description: >
Sample component schematic that describes the administrative interface for our Twitter bot.
spec:
workloadType: core.oam.dev/v1alpha1.Server
osType: linux
parameters:
- name: username
description: Basic auth username for accessing the administrative interface
type: string
required: true
- name: password
description: Basic auth password for accessing the administrative interface
type: string
required: true
- name: backend-address
description: Host name or IP of the backend
type: string
required: true
containers:
- name: my-twitter-bot-frontend
image:
name: example/my-twitter-bot-frontend:1.0.0
digest: sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b
resources:
cpu:
required: 1.0
memory:
required: 100MB
ports:
- name: http
value: 8080
env:
- name: USERNAME
fromParam: 'username'
- name: PASSWORD
fromParam: 'password'
- name: BACKEND_ADDRESS
fromParam: 'backend-address'
livenessProbe:
httpGet:
port: 8080
path: /healthz
readinessProbe:
httpGet:
port: 8080
path: /healthz
使用擴充工作負載的元件聲明
apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: alibabacloudFunctions
annotations:
version: v1.0.0
description: "Extended workflow example"
spec:
workloadType: alibabacloud.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
總結
元件聲明是由開發者或者 OAM 平台給出,透出應用運作的可配置項、依賴的平台和工作負載,可以看成是一個聲明了運作環境的函數定義,運維人員填寫函數參數之後,元件就會按照聲明的功能運作起來。
應用邊界(Application scopes)
應用邊界通過提供不同形式的應用邊界以及共有的分組行為來将元件組成邏輯的應用,應用邊界具備以下通用的特征:
- 應用邊界應該描述該組元件執行個體的共有行為和中繼資料;
- 一個元件可以同時部署到多個不同類型的應用邊界中;
- 應用邊界類型可以決定元件是否可以部署到多個相同的應用邊界類型執行個體;
- 應用邊界可以用于不同元件分組以及不同 infra 能力之間的連接配接機制,比如 networking 或者外部能力(如驗證服務);
下圖說明了元件可以屬于多個重疊的應用分組,最終建立出不同的應用邊界。
上圖有兩種應用邊界類型:Network 與 Health,有四個元件分布在不同的應用邊界執行個體中:
- A、B、C 三個元件部署到了相同的 Health scope,該 scope 會收集所有屬于這個邊界的元件狀态和資訊,可以給 Traits 或者其他元件使用;
- 元件 A 和 B、C、D 的網絡邊界是隔離的,這允許 infra 運維提供不同的 SDN 設定,控制不同分組的流量流入/流出規則;
主要是有兩種應用邊界類型:
- 核心應用邊界類型
- 擴充應用邊界類型
定義基本運作時行為的分組結構,它們擁有如下特征:
- 必須是 core.oam.dev 命名空間;
- 必須被全部實作;
- 核心工作負載類型執行個體必須部署到所有核心應用邊界類型執行個體中;
- 運作時必須為每種應用邊界類型提供預設的應用邊界執行個體;
- 運作時如果元件執行個體沒有指定特定的應用邊界,必須将該元件執行個體部署到預設應用邊界執行個體上;
目前 Spec 定義的應用邊界類型有:
Name | Type | Description |
---|---|---|
Network | core.oam.dev/v1alpha1.Network | 該邊界将元件組織到一個子網邊界并且定義統一的運作時網絡模型,以及infra網絡描述的定義和規則 |
Health | core.oam.dev/v1alpha1.Health | 該邊界将元件組織到一個聚合的健康組中,資訊可以用于復原和更新 |
對于運作時來說是 optional 的,可以自定義。
apiVersion,kind,metadata 和前面元件一緻,不贅述,主要描述 Spec:
應用邊界類型 | ||||
allowComponentOverlap | bool | 決定是否允許一個元件同時出現在多個該類型應用邊界執行個體中 | ||
邊界的可配置參數 |
Network scope(core)
用于将元件劃分到一個網絡或者 SDN 中,網絡本身必須被 infra 定義和運維,也可以被流量管理 Traits 查詢,用于發現 service mesh 的可發現邊界或者 API 網關的 API 邊界:
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationScope
metadata:
name: network
annotations:
version: v1.0.0
description: "network boundary that a group components reside in"
spec:
type: core.oam.dev/v1.NetworkScope
allowComponentOverlap: false
parameters:
- name: network-id
description: The id of the network, e.g. vpc-id, VNet name.
type: string
required: Y
- name: subnet-id
description: The id of the subnet within the network.
type: string
required: Y
- name: internet-gateway-type
description: The type of the gateway, options are 'public', 'nat'. Empty string means no gateway.
type: string
required: N
Health scope(core)
用于聚合元件的健康狀态,可以設計的參數有健康門檻值(超過該門檻值的元件不健康則認為整個邊界不健康),健康邊界執行個體本身不會用健康狀态做任何操作,它隻是分組健康聚合器,其資訊可以被查詢并用于其他地方,比如:
- 應用的變更 Traits 可以監控健康狀态來決定何時復原;
- 監控 Traits 可以監控健康狀态來觸發報警。
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: probe-endpoint
description: The endpoint to probe from the components, e.g. '/v1/health'.
type: string
required: true
- name: probe-timeout
description: The amount of time in seconds to wait when receiving a response before marked failure.
type: integer
required: false
- name: probe-interval
description: The amount of time in seconds between probing tries.
type: integer
required: false
- name: failure-rate-threshold
description: If the rate of failure of total probe results is above this threshold, declared 'failed'.
type: double
required: false
- name: healthy-rate-threshold
description: If the rate of healthy of total probe results is above this threshold, declared 'healthy'.
type: double
required: false
- name: health-threshold-percentage
description: The % of healthy components required to upgrade scope
type: double
required: false
- 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
resource quota scope(extended)
限制分組内所有元件的資源使用總量上限。
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationScope
metadata:
name: myResourceQuotas
annotations:
version: v1.0.0
description: "The production configuration for Corp CMS"
spec:
type: resources.oam.dev/v1.ResourceQuotaScope
allowComponentOverlap: false
parameters:
- name: CPU
description: maximum CPU to be consumed by this scope
type: double
required: Y
- name: Memory
description: maximum memory to be consumed by this scope
type: double
required: Y
應用邊界聲明由 OAM 平台提供,透出應用邊界執行個體運作的可配置項,可以看成是一個函數定義,運維人員或者平台填寫函數參數之後,應用邊界就會按照聲明的功能運作起來,對該邊界内的元件們起作用。
應用特征(Traits)
OAM Spec 的實作平台應該提供 Traits 給元件工作負載增強運維操作,一個 Trait 是一種自由的運作時,增強工作負載提供額外的功能,比如流量路由規則、自動擴縮容規則、更新政策等,這讓應用運維具備根據需求配置元件,不需要開發者參與的能力。一個獨立的 Trait 可以綁定 1 或多個工作負載類型,它可以聲明哪些工作負載類型才能使用該Trait。
規則
- 目前并沒有機制來顯示約定元件的多個 Traits 組合,也就是一個元件應用了 Trait A 無法要求 Trait B 必須應用于該元件,如果在運作時發生存在 Trait A 但是 Trait B 不存在,應該标記 Trait A 失敗;
- Traits 應該按照定義的順序施加到元件上;
- 應用部署隻有當所有元件和其 Traits 都正常運作起來才能标記為部署成功;
- OAM 平台應該支援元件施加多個 Traits,這些 Traits 可能是相同的類型;
- OAM 對 Trait 的實作沒有任何限制,Trait 一般作用于應用的安裝和更新時;
分類
目前 Traits 主要分為三類:
- Core Traits: core Traits 屬于 core.oam.dev 分組,是一些必要的運維特征,所有 OAM 平台必須實作;
- Standard Traits: standard Traits 屬于 standard.oam.dev 分組裡面,是一些常用的運維特征,推薦 OAM 平台實作;
- Extensions Traits: extension Traits 是自定義 Traits,其分組也是自定義,是平台特定的運維特征(通常是特定 OAM 平台差異性)的展現。
appliesTo | ["*"] | 該Trait可以應用的工作負載類型 | ||
properties | []Properties | Trait的可配置參數,使用JSON Schema來表達。 |
Manual Scaler(core)
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: |
{
"$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,隻有一個參數就是 replicaCount。
應用特征聲明由 OAM 平台提供,透出應用特征的可配置項,标明了可作用于的工作負載,可以看成函數定義,運維人員或者平台填寫實參之後,應用特征就會按照聲明的功能運作起來,對綁定的元件起作用。
應用配置(Application Configuration)
應用配置主要是描述應用如何被部署的,一個元件可以部署到任意的運作時,我們稱一個元件的一次部署為執行個體,每次元件部署的時候必須有應用配置。
應用配置由應用運維管理,提供目前元件執行個體的資訊:
- 特定元件的基本資訊:名字、版本、描述;
- 元件及其相關元件定義 parameters 的指派;
- 元件要施加的 Trait 以及 Trait 的配置。
概念
執行個體與更新(Instances and upgrades)
一個執行個體是元件的可追溯部署,當元件部署時建立,後續該元件的更新都是修改該執行個體,復原/重新部署都屬于更新,執行個體都會有名字友善引用。當一個執行個體首次建立時,處于初始發行 (release) 狀态,每次更新操作之後,一個新的發行就會建立。
發行(Releases)
任何對元件本身或者其配置的變更都會建立一個新的發行,一個發行就是應用配置以及它對元件、應用特征、應用邊界的定義,當一個發行被部署,對應的元件、應用特征和應用邊界也會被部署。
基于該定義,平台需要保證以下變更語義:
- 如果新的發行包含了舊發行不存在的元件,平台需要建立該元件;
- 如果新的發行不包含舊發行存在的元件,平台需要删除該元件;
- 應用特征和應用邊界與元件的變更語義一緻。
運作時與應用配置(Runtime and Application Configuration)
一個元件可以部署到多個不同的運作時,在每個運作時中應用配置的執行個體與應用配置之間是 1:1 的關系,應用配置由應用運維管理,包含 3 個主要部分:
- 參數:運維人員在部署時可以定義的參數;
- 應用邊界清單:一組應用邊界清單,每個應用邊界定義對應的參數;
- 元件執行個體定義:定義一個元件執行個體如何部署,這個定義本身有 3 個部分:
- 元件參數的定義;
- Traits 清單:每個 Trait 定義對應的參數;
- 應用邊界清單:該元件應該部署到的應用邊界清單。
variables | []Variable | 可以在參數值和屬性中引用的變量 | ||
scopes | []Scope | 應用邊界定義 | ||
components | []Component | 元件執行個體定義 |
variables 就是一個 k/v 對,一個集中的地方定義運維的變量,在運維配置的其他地方都可以用 fromVariable(VARNAME) 引用:
變量名字 | ||||
标量值 |
scopes 定義該運維配置将要建立的應用邊界,其定義為:
應用邊界名字 | ||||
應用邊界的GROUP/VERSION.KIND | ||||
Properties | 覆寫邊界的參數 |
components 是元件執行個體定義,而不是元件定義:
componentName | 元件名 | |||
instanceName | 元件執行個體名 | |||
parameterValues | []ParameterValue | 覆寫元件的參數 | ||
Traits | []Trait | 指定元件執行個體綁定的Traits | ||
applicationScopes | 指定元件運作的應用邊界 |
Trait 在這裡的定義是:
Trait執行個體名 | ||||
覆寫Trait的參數 |
apiVersion: core.oam.dev/v1alpha1
kind: ApplicationConfiguration
metadata:
name: my-app-deployment
annotations:
version: v1.0.0
description: "Description of this deployment"
spec:
variables:
- name: VAR_NAME
value: SUPPLIED_VALUE
scopes:
- name: core.oam.dev/v1alpha1.Network
parameterValues:
- name: PARAM_NAME
value: SUPPLIED_VALUE
components:
- componentName: my-web-app-component
instanceName: my-app-frontent
parameterValues:
- name: PARAMETER_NAME
value: SUPPLIED_VALUE
- name: ANOTHER_PARAMETER
value: "[fromVariable(VAR_NAME)]"
traits:
- name: Ingress
properties:
CUSTOM_OBJECT:
DATA: "[fromVariable(VAR_NAME)]"
應用配置定義由運維人員或者 OAM 平台提供,描述應用的部署,可以看成是一個函數調用,運維人員或者 OAM 平台填寫實參之後,調用之前定義的元件、應用特征、應用邊界等函數,這些執行個體一起作用對外提供應用服務。
工作負載類型(Workload Types)
Workload 類型和 Trait 一樣由平台提供,是以使用者可以檢視平台提供哪些工作負載,對于平台使用者來說工作負載類型無法擴充,隻能由平台開發者擴充提供,是以平台一定不允許使用者建立自定義的工作負載類型。
apiVersion,kind,metadata 和前面元件類似,不贅述,這裡主要描述 Spec,定義元件如何使用工作負載類型,除此之外暴露了底層工作負載運作時的可配置參數:
group | 該工作負載類型所屬的group | |||
names | Names | 該工作負載類型的關聯名字資訊 | ||
settings | []Setting | 該工作負載的設定選項 |
Names 就是描述了對應類型的不同形式名字引用:
工作負載類型的正确引用名字,比如Singleton | ||||
singular | 單數形式的可讀名字,比如singleton | |||
plural | 複數形式的可讀名字,比如singletons |
Setting 描述工作負載可配置部分,類似前面元件的 Parameters,都是 schema:
配置名,每個workload類型必須唯一 | ||||
配置說明 | ||||
配置類型 | ||||
是否必須提供 | ||||
indicated by type |
價值
通過上面的介紹,我們了解了 OAM Spec 裡面的基本概念和定義,以及如何使用它們來描述應用傳遞和運維流程。然而,OAM 能給我們帶來什麼樣的價值呢?我們評判一個好的架構體系,不僅是因為它在技術上更先進,更主要的是它能夠解決一些實際問題,為使用者帶來價值。是以,接下來我們将總結一下這方面的内容。
OAM 的價值要從下往上三個層面來說起。
1. 從基礎設施層面
基礎設施,指的是像 K8s 這類的提供基礎服務能力與抽象的一層服務體系。拿 K8s 來說,它提供了許多種類的基礎服務和強大的擴充能力來靈活擴充其他基礎服務。
但是,使用基礎設施的運維人員很快就發現 K8s 存在一個問題:缺乏統一的機制來注冊和管理自定義擴充能力。這些擴充能力的表達方式不夠統一,有些是 CRD、有些是 annotation、有些是 Config...
這種亂象使得基礎設施使用者不知道平台上都提供了哪些能力,不知道怎麼使用這些能力,更不知道這些能力互相之間的相容組合關系。
OAM 提供了抽象(如 Workload/Trait 等)來統一定義和管理這些能力。有了 OAM,各平台實作就有了統一的标準規範去透出公共的或差異化的能力:公共的基礎服務像容器部署、監控、日志、灰階釋出;差異化的、進階複雜的能力像 CronHPA(周期性定時變化的強化版 HPA)。
2. 從應用運維者層面
應用運維,指的是像給應用加上網絡接入、複雜均衡、彈性伸縮、甚至是建站等運維操作。但是,運維的一個痛點就是原來這些能力并不是跨平台的:這導緻在不同平台、不同環境下去部署和運維應用的操作,是不互通和不相容的。
上面這個問題,是客戶應用、尤其是傳統 ERP 應用上雲的一大阻礙。我們做 OAM 的一個初衷,就是通過一套标準定義,讓不同的平台實作也通過統一的方式透出。我們希望:哪怕一個應用不是生在雲上、長在雲上,也能夠趕上這趟通往雲原生未來的列車,擁抱雲帶來的變化和紅利!
OAM 提供的抽象和模型,是我們通往統一、标準的應用架構的強有力工具。這些标準能力以後都會通過 OAM 輸出,讓運維人員輕易去實作跨平台部署。
3. 從應用開發者層面
應用開發,指的就是業務邏輯開發,這是業務産生價值的核心位置。
也正因如此,我們希望,應用開發者能夠專注于業務開發,而不需要關心運維細節。但是,K8s 提供的 API,并沒有很好地分離開發和運維的關注點,開發和運維之間需要來回溝通以避免産生誤解和沖突。
OAM 分離了開發和運維的關注點,很好地解決了以上問題,讓整個釋出流程更加連貫、高效。
下一步
目前,OAM 已經在阿裡雲 EDAS 等多個項目中進行了數月的内部落地嘗試。我們希望通過一套統一、标準的應用定義體系,承載雲應用管理項目産品與外部資源關系的高效管理體驗,并将這種體驗統一帶給了基于 Function、ECS、Kubernetes 等不同運作時的應用管理流程;通過應用特征系統,将多個阿裡雲獨有的能力進行了子產品化,大大提高了阿裡雲基礎設施能力的傳遞效率。
經過了前一段努力的鋪墊,我們也慢慢明确了接下來的工作方向:
- 将接入更多的雲産品服務,為使用者将跨平台應用傳遞的能力最大化;
- 提供 OAM framework 等工具和架構,幫助新的 OAM 平台開發者去快速、簡單地搭建 OAM 服務,接入 OAM 标準;
- 推動開源生态建設,以标準化的方式幫助“應用”高效和高品質地傳遞到任何平台上去。
社群共建
為了能夠讓社群更加高效、健康的運轉下去,我們非常期待得到您的回報,并與大家密切協作,針對 Kubernetes 和任意雲環境打造一個簡單、可移植、可複用的應用模型。參與方式:
- 通過 Gitter 直接參與讨論: https://gitter.im/oam-dev/ ;
- 選擇釘釘掃碼進入 OAM 項目中文讨論群。
(釘釘掃碼加入交流群)
歡迎你與我們一起共建這個全新的應用管理生态!
“ 阿裡巴巴雲原生微信公衆号(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公衆号。”
更多相關資訊,請關注
“阿裡巴巴雲原生”。