
作者 | 周正喜 阿裡雲技術專家 愛好雲原生,深度參與 OAM 社群
大家都知道,應用開放模型 Open Application Model(OAM) 将應用的工作負載(Workload)分為
三種—— 核心型、标準型和擴充型,這三者的主要差別在于一個 OAM 平台對于具體某一類工作負載進行實作的自由度不同。其中,OAM 社群中目前唯一一個核心工作負載是
Containerized Workload,它用來描述一個基于容器的工作負載,可以了解為是 Kubernetes Deployment 的簡化版(去掉了 PodSecurityPolicy 等大量與業務研發無關的字段)。
不過,很多讀者可能會有疑問:對于 Kubernetes 内置的工作負載 OAM 是否還能直接支援呢?
答案當然是肯定的,而且這是 OAM 作為 Kubernetes 原生的應用定義模型的預設能力。
下面,本文就以 Deployment 為例,介紹如何使用 OAM 基于 Kubernetes 的内置工作負載來定義和管理雲原生應用。
示例準備
基于 GitHub
FoodTrucks(舊金山美味街邊小吃地圖應用)項目,建構鏡像 zzxwill/foodtrucks-web:0.1.1,加上依賴的 Elasticsearch 鏡像,在預設情況下,它的 Deployment 描述檔案
food-truck-deployment.yaml如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: food-trucks-deployment
labels:
app: food-trucks
spec:
selector:
matchLabels:
app: food-trucks
template:
metadata:
labels:
app: food-trucks
spec:
containers:
- name: food-trucks-web
image: zzxwill/foodtrucks-web:0.1.1
env:
- name: discovery.type
value: single-node
ports:
- containerPort: 5000
- name: es
image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
ports:
- containerPort: 9200
- containerPort: 9300
如果将上述 yaml 檔案送出到 Kubernetes 叢集,通過 port-forward 可以通過浏覽器檢視效果:
定義 Component 與 Workload
在 OAM 中, 一個應用是由多個 Component(元件)構成的,而一個 Component 裡的核心字段,就是 Workload(工作負載)。
是以說,像 Kubernetes Deployment、StatefulSet 等内置的工作負載,其實天生就可以被定義為 OAM Component 中的 Workload。比如下面這個
sample-deployment-component.yaml檔案,可以看到,.spec.workload 的内容,就是一個 Deployment,也就是 food-truck-deployment.yaml 裡定義的 Deployment。
接下來,我們就将上述 OAM Component 送出到 Kubernetes 叢集驗證一下。
部署這個應用
在 OAM 中,我們需要編寫一個應用配置 ApplicationConfiguration 來組織所有的 OAM Component。由于隻有一個 Component,本例中的
sample-applicationconfiguration.yaml非常簡單,如下所示:
apiVersion: core.oam.dev/v1alpha2
kind: ApplicationConfiguration
metadata:
name: example-deployment-appconfig
spec:
components:
- componentName: example-deployment
送出 OAM Component 和 ApplicationConfiguration YAML 檔案給 Kubernetes:
✗ kubectl apply -f sample-deployment-component.yaml
component.core.oam.dev/example-deployment created
✗ kubectl apply -f sample-applicationconfiguration.yaml
applicationconfiguration.core.oam.dev/example-deployment-appconfig created
不過,如果這個時候你檢視 example-deployment-appconfig 的執行情況,會發現如下報錯:
✗ kubectl describe applicationconfiguration example-deployment-appconfig
Name: example-deployment-appconfig
...
Status:
Conditions:
Message: cannot apply components: cannot apply workload "food-trucks-deployment": cannot get object: deployments.apps "food-trucks-deployment" is forbidden: User "system:serviceaccount:crossplane-system:crossplane" cannot get resource "deployments" in API group "apps" in the namespace "default"
Reason: Encountered an error during resource reconciliation
...
這是因為 OAM 的 Kubernetes 插件權限不足導緻的,是以不要忘記設定合理的 ClusterRole 和 ClusterRoleBinding。
送出如下的授權檔案
rbac.yaml,ApplicationConfiguration 可以執行成功。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: deployment-clusterrole-poc
rules:
- apiGroups:
- apps
resources:
- deployments
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oam-food-trucks
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: deployment-clusterrole-poc
subjects:
- kind: ServiceAccount
namespace: crossplane-system
name: crossplane
繼續檢視 deployments,并設定端口轉發:
✗ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
food-trucks-deployment 1/1 1 1 2m20s
✗ kubectl port-forward deployment/food-trucks-deployment 5000:5000
Forwarding from 127.0.0.1:5000 -> 5000
Forwarding from [::1]:5000 -> 5000
Handling connection for 5000
Handling connection for 5000
通過
http://127.0.0.1:5000就可以在舊金山美味街邊小吃地圖裡找到漢堡包的店了:
什麼時候使用 Deployment ?
看到這裡,大家可能會有另一個疑問,那麼我什麼時候該使用 Deployment、什麼時候該使用 ContainerizedWorkload 來作為 OAM 的工作負載呢?
其實,Deployment 和 ContainerizedWorkload 的主要差別,在于抽象程度不同。
簡單說,如果你的使用者希望看到一個極簡的、沒有一些”亂七八糟“字段的 Deployment 的話;或者,你希望對你的使用者屏蔽掉 Deployment 裡面與使用者無關的字段(比如:不想允許研發自行設定 PodSecurityPolicy),那你就應該給使用者暴露 ContainerizedWorkload。這時候,這個工作負載需要的運維操作和政策,則是由另一個 OAM 對象 Traits(運維特征) 來定義的,比如
ManualScalerTrait。這種“關注點分離”的做法,也是 OAM 提倡的最佳實踐。
反之,如果你的使用者對 Deployment 裡的各種運維、安全相關的字段并不排斥,你也不需要對使用者屏蔽掉這些字段,那你大可以直接暴露 Deployment 出去。這個工作負載需要的其他運維能力,依然可以通過 OAM Traits 來提供。
為什麼使用 OAM Component 來定義應用?
你有可能還有另外一個疑問,既然 OAM Component 裡面的 Workload 就是 Kubernetes 裡的各種 API 對象,那麼使用 OAM 模型來定義應用又有哪些好處呢?
這就要說到 OAM 帶來的好處了,相信大家在基于 Kubernetes 建構應用平台的時候,一定遇到過一系列的難題,比如依賴管理、版本控制、灰階釋出等等,另一方面,應用平台為了跟雲資源結合起來,純粹使用 K8s 原生的 Workload 是做不到的。
而通過 OAM ,你不僅可以将雲資源與應用統一描述,OAM 實作架構還将幫你解決了
依賴管理、
版本控制、灰階釋出等一系列難題。這些我們将在後續的文章中為大家介紹。
了解更多和貢獻
除了 Deployment 之外,OAM 社群還有很多 Kubernetes 内置工作負載(比如 StatefulSet)以及阿裡巴巴開源工作負載 OpenKruise 的各種執行個體,歡迎
查閱和貢獻。
為了深入參與 OAM 貢獻,也非常歡迎加入阿裡巴巴雲原生應用平台團隊。
- 工作職位:Kubernetes/Serverless/PaaS/應用傳遞等領域專家( P7-P8 )。
- 工作年限:建議 P7 三年起,P8 五年起,具體看實際能力。
- 工作地點: 國内:北京,杭州,深圳;海外:舊金山灣區、西雅圖
- 崗位包含:架構師、技術專家、全棧工程師等。
履歷立刻回複,2~3 周出結果,履歷投遞:jianbo.sjb AT alibaba-inc.com
課程推薦
為了更多開發者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿裡巴巴 Serverless 領域技術專家,打造出最适合開發者入門的 Serverless 公開課,讓你即學即用,輕松擁抱雲計算的新範式——Serverless。
點選即可免費觀看課程:
https://developer.aliyun.com/learning/roadmap/serverless“ 阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公衆号。”