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

頭圖.png

做者 | 周正喜  阿里雲技術專家  愛好雲原生,深度參與 OAM 社區node

你們都知道,應用開放模型 Open Application Model(OAM) 將應用的工做負載(Workload)分爲三種 —— 核心型、標準型和擴展型,這三者的主要區別在於一個 OAM 平臺對於具體某一類工做負載進行實現的自由度不一樣。其中,OAM 社區中目前惟一一個核心工做負載是 Containerized Workload,它用來描述一個基於容器的工做負載,能夠理解爲是 Kubernetes Deployment 的簡化版(去掉了 PodSecurityPolicy 等大量與業務研發無關的字段)。git

不過,不少讀者可能會有疑問:對於 Kubernetes 內置的工做負載 OAM 是否還能直接支持呢?github

答案固然是確定的,並且這是 OAM 做爲 Kubernetes 原生的應用定義模型的默認能力。web

下面,本文就以 Deployment 爲例,介紹如何使用 OAM 基於 Kubernetes 的內置工做負載來定義和管理雲原生應用。docker

示例準備

基於 GitHub FoodTrucks (舊金山美味街邊小吃地圖應用)項目,構建鏡像  zzxwill/foodtrucks-web:0.1.1,加上依賴的 Elasticsearch 鏡像,在默認狀況下,它的 Deployment 描述文件  food-truck-deployment.yaml 以下所示:api

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 集羣驗證一下。app

部署這個應用

在 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 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的公衆號。」
相關文章
相關標籤/搜索