開放應用模型操作指南(一)| 雲服務一鍵接入 OAM 體系
作者 | 鄧洪超 阿里雲容器平臺軟體工程師
導讀: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 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”