作者 | 鄧洪超 阿里雲容器平台軟件工程師
導讀:Open Application Model(OAM)是阿里雲聯合微軟等國際頂級技術團隊聯合發布的開放應用模型技術。旨在通過全新的應用定義、運維、分發與交付模型,推動應用管理技術向“輕運維”的方向邁進,全力開啟下一代雲原生 DevOps 的技術革命。本《開放應用模型操作指南》系列文章,將為廣大技術人員(研發、運維、基礎設施工程師)提供接地氣的、體系化的 OAM 操作和接入指南。
前言
自 OAM 標准推出以來,越來越多的平台和服務開始接入 OAM 標准,朝着 BaaS (Backend as a service) 化的方向邁進。在阿里巴巴集團,我們見證了 EDAS、內部中間件交付平台等以 OAM 的方式打造和推出應用交付和運維產品。並且,ROS、PolarDB 等以開放的姿態逐步接入 OAM 作為跨平台集成方案。
隨着跟終端用戶和平台提供方的交流日益增多,我們也同時更加清楚地了解到在 OAM 集成各個平台和服務的時候還是有一些不一致、不標准的地方。舉些例子,DB 等資源創建起來后連接信息該如何暴露,已有的資源定義該如何模型化成 OAM,什么應該作為 Workload?什么應該作為 Trait 等等。這些問題在不同團隊的解決方式是類似卻有些許差異的,不僅造成重復勞作,實踐經驗也缺乏進一步沉淀。
我們希望用戶去使用和接入 OAM,能夠有一個統一的、清晰的流程和架構。這就是本文嘗試去闡述問題、提供解法的地方。
什么人適合讀這篇文章?
這篇文章主要面向服務集成方,他們希望自己的服務能夠通過 OAM 去被使用。這包括:
- 服務提供方。比如監控服務 ARMS、日志服務 SLS、分布式追蹤服務等;
- 平台提供方。比如 EDAS、中間件交付平台、ROS、DBaaS 等,一個平台往往包含很多服務。
用 OAM 描述雲資源/服務
如果你有一個服務,怎樣才能以雲原生的方式暴露呢?答案就是在 Kubernetes 上提供該服務。而 OAM,正是幫助大家更好地在 K8s 上描述服務能力、實現擴平台集成的一種標准。
1. 歸類 OAM 類型
首先,服務的能力需要歸類為 OAM 類型中的某一種。這里有三種類型:
類型 | 定義 | 例子 |
---|---|---|
Workload | 能單獨跑起來、單獨使用的服務需要定義的類型。 | DB (MySQL)、MQ (Kafka)、Cache (Redis)、Service Mesh |
Trait | 跟運維相關的服務需要定義的類型。 | Ingress、Monitoring、Logging、服務發現、灰度發布 |
Scope | 囊括一組服務組件的邊界。目前僅適用少數場景。 | 網絡邊界 (VPC、Firewall、Gateway)、健康邊界 (互相關聯的組件的整體健康檢測) |
服務提供方需要將己方服務歸類為上述一種。這樣能夠在平台上清楚地表達自己的目的,更好地被集成和使用。
2. 編寫 OAM 定義
我們通常在把一個服務歸類為一種 OAM 類型之后,就會去編寫這個服務的 OAM 定義。這包括兩部分:
- 編寫 OAM 定義里面的通用元數據;
- 編寫服務自定義的 API。
服務自定義的 API 是用來描述服務對外提供的能力的 API。在這方面,我們選擇使用 JSON Schema 來作為 API 描述語言,因為它是一種開放、標准的方式,在工程領域為大家所熟知。
下面,我們就分別以 Workload 和 Trait 為例,結合注釋來詳解如何去編寫服務的 OAM 定義。
OAM Workload 例子
apiVersion: oam.dev/v1alpha1
kind: WorkloadType
metadata:
name: rds
spec:
group: alibaba.io/v1
names: [RDS]
# 下面用 JSON schema 描述服務能力
settings: |
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"storageType"
],
"properties": {
"storageType": {
"type": "string",
"description": "The type of storage for RDS instance"
}
}
}
OAM Trait 例子
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
# 下面用 JSON schema 描述運維能力
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
}
}
}
3. 實現 OAM Operator
在定義了 OAM API 之后,我們還需要有實現層能讓這個 spec “跑”起來。這里我們推薦實現 K8s Operator 來作為這個 OAM API 的服務。Operator 具體細節有很多文章介紹,這里不再贅述。
阿里巴巴雲原生應用團隊實現並開源了 OAM framework(oam-go-sdk)來幫助大家簡化【構建 API + 實現 Operator】。
大家如果在實現 OAM Operator 過程中有什么問題,歡迎聯系我們。可以在上游提 issue 或者釘釘發消息。
服務的暴露與消費
OAM 能給大家帶來的一個重要好處就是能夠橫向聯通不同平台之間的服務能力。這里我們介紹下如何實現。
在集成服務的時候,通常要做兩件事情:
- 服務提供方需要暴露服務信息,比如 DB 連接信息寫到 CMDB;
- 服務信息需要提供給用戶應用去消費,比如將 DB 連接信息自動注入到(消費者)應用的環境變量。
當前現狀是,OAM 對接的項目往往都有自己的一套系統暴露和消費服務的方式。下面我們舉些例子:
- Service Broker 將服務信息寫入到 CRD 實例狀態中,然后通過工作流讀取並寫入應用環境變量;
- ROS 在 DB 模板執行完后有 outputs 屬性包含服務信息,然后作為用戶應用模板的參數入參;
- CrossPlane 在多家雲廠商上提供統一的 MySQL Resource 定義,然后通過將 connection 信息寫入 secret 並掛載到用戶應用文件系統里。
除了上面的例子,我們還有很多其他或大或小的服務暴露與消費的例子。現在這里有一個問題,那就是不同的項目之間,沒有統一的服務暴露與消費方式,導致不同的平台之間無法互通。在這里,我們希望定義一個統一的接口,讓不同平台不同服務在接入 OAM 以后能夠互通,更簡單地透出服務能力賦能雲用戶。
解決思路
針對上述問題,我們接下來描述下解決思路:
-
OAM Runtime 解析 AppConfig,發現一個 Component (微服務應用) 需要消費另一個 Component (雲服務) 。於是 Runtime 需要安排好 Component 之間的創建順序;
-
首先,OAM Runtime 創建雲服務 Workload Component,並將相應的服務信息暴露到一個 spec 指定名字的 secret 里面去;
-
然后,OAM Runtime 創建微服務應用 Component,並將 spec 聲明的消費內容通過名字相關聯,並將 secret(通過 env、file 等方式)注入到應用中去。
整體架構圖如下:
示例
下面我們通過舉例來說明整個過程。
通過 CrossPlane 創建一個 CloudSQL Component:
apiVersion: oam.dev/v1alpha1
kind: Component
metadata:
name: mysql
spec:
workloadType: database.cloud.io/v1beta1.CloudSQL
expose:
name: mysql-connection
... # 其他一些參數輸入
上面我們看到 expose 字段聲明了暴露信息的名字,這樣做是為了讓消費者能關聯。具體如何暴露與消費服務信息,則是由 Runtime 層來實現。在這里,創建完 MySQL Workload 實例之后,MySQL 連接信息會被寫入到一個 mysql-connection
secret 里面去。
另一個應用 Web Component 則如下面定義所示來消費 MySQL:
apiVersion: oam.dev/v1alpha1
kind: Component
metadata:
name: web
spec:
workloadType: Server
consume:
- name: mysql-connection
as: env # 注入到環境變量當中。也可以設置為 file,則會注入到本地文件當中
總結
在這篇文章里,我們主要針對雲服務提供方講了如何用 OAM 描述服務能力、定義和實現相應的 OAM Runtime、以及如何通過 OAM 集成不同平台的服務。
目前,OAM 還處於一個早期階段,阿里巴巴團隊正在上游貢獻和維護這套技術,希望這篇文章能給大家對於 OAM 以及如何接入雲服務有更多的了解。如果大家有什么問題或者反饋,也非常歡迎跟我們在上游或者釘釘聯系。
參與方式:
- 釘釘掃碼進入 OAM 項目中文討論群
- 通過 Gitter 直接參與討論:https://gitter.im/oam-dev/
期待大家的參與!
“阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”