資安

OAM 深入解讀:使用 OAM 定義與管理 Kubernetes 內置 Workload

image.png

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

image.png

定義 Component 與 Workload

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

image.png

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

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

image.png

繼續查看 deployments,並設置端口轉發:

image.png

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

image.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 實現框架還將幫你解決了依賴管理、版本控制、灰度發佈等一系列難題。這些我們將在後續的文章中為大家介紹。

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

Leave a Reply

Your email address will not be published. Required fields are marked *