使用 OAM 定義與管理 Kubernetes 內置 Workload

頭圖.png

作者 | 周正喜  阿里雲技術專家  愛好雲原生,深度參與 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 可以通過瀏覽器查看效果:

1.png

定義 Component 與 Workload

在 OAM 中, 一個應用是由多個 Component(組件)構成的,而一個 Component 裏的核心字段,就是 Workload(工作負載)。

2.png

所以說,像 Kubernetes Deployment、StatefulSet 等內置的工作負載,其實天生就可以被定義爲 OAM Component 中的 Workload。比如下面這個 sample-deployment-component.yaml 文件,可以看到,.spec.workload 的內容,就是一個 Deployment,也就是 food-truck-deployment.yaml 裏定義的 Deployment。

3.png

接下來,我們就將上述 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 就可以在舊金山美味街邊小喫地圖裏找到漢堡包的店了:

4.png

什麼時候使用 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 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公衆號。”

上雲就看雲棲號:更多雲資訊,上雲案例,最佳實踐,產品入門,訪問:https://yqh.aliyun.com/

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章