天天看點

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

大家都知道,應用開放模型 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 可以通過浏覽器檢視效果:

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

定義 Component 與 Workload

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

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

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

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

接下來,我們就将上述 OAM Component 送出到 Kubernetes 叢集驗證一下。

部署這個應用

在 OAM 中,我們需要編寫一個應用配置 ApplicationConfiguration 來組織所有的 OAM Component。由于隻有一個 Component,本例中的 sample-applicationconfiguration.yaml 非常簡單,如下所示:

apiVersion: core.oam.dev/v1alpha2

kind: ApplicationConfiguration

name: example-deployment-appconfig

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 可以執行成功。

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

繼續檢視 deployments,并設定端口轉發:

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

通過

http://127.0.0.1:5000

就可以在舊金山美味街邊小吃地圖裡找到漢堡包的店了:

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 内置 Workload示例準備定義 Component 與 Workload部署這個應用什麼時候使用 Deployment ?為什麼使用 OAM Component 來定義應用?

什麼時候使用 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 實作架構還将幫你解決了依賴管理、版本控制、灰階釋出等一系列難題。這些我們将在後續的文章中為大家介紹。

本文轉自<阿裡巴巴雲原生技術圈>——阿裡巴巴雲原生小助手

繼續閱讀