KubeVela 1.7 版本解讀:接管你的已有工作負載

阿里云云原生發表於2023-04-04
作者:孫健波(天元)

KubeVela 1.7 版本已經正式釋出一段時間,在此期間 KubeVela 正式晉級成為了 CNCF 的孵化專案,開啟了一個新的里程碑。而 KubeVela 1.7 本身也是一個轉折點,由於 KubeVela 從一開始就專注於可擴充套件體系的設計,對於控制器核心功能的需求也開始逐步收斂,我們開始騰出手來更加專注於使用者體驗、易用性、以及效能。在本文中,我們將重點挑選 1.7 版本中的工作負載接管、效能最佳化等亮點功能進行介紹。

接管你的工作負載

接管已有的工作負載一直是社群裡呼聲很高的需求,其場景也非常明確,即已經存在的工作負載可以自然的遷移到 OAM 標準化體系中,被 KubeVela 的應用交付控制面統一管理,複用 VelaUX 的 UI 控制檯功能,包括社群的一系列運維特徵、工作流步驟以及豐富的外掛生態。在 1.7 版本中,我們正式釋出了該功能,在瞭解具體怎麼操作之前,讓我們先對其執行模式有個基本瞭解。

“只讀” 和 “接管” 兩種模式

為了適應不同的使用場景,KubeVela 提供了兩種模式來滿足你統一管理的需求,一種是隻讀模式,適用於內部已經有自建平臺的系統,這些系統對於存量業務依舊具有主要的控制能力,而新的基於 KubeVela 的平臺系統可以只讀式的統一觀測到這些應用。另一種是接管模式,適用於想直接做遷移的使用者,可以把已有的工作負載自動的接管到 KubeVela 體系中,並且完全統一管理。

  • “只讀”(read-only)模式顧名思義,它不會對資源有任何“寫”操作。使用只讀模式納管的工作負載,可以透過 KubeVela 的工具集(如 CLI、VelaUX)做視覺化,滿足統一檢視、可觀測方面的需求。與此同時,只讀模式下生成的納管應用被刪除時,底下的工作負載資源也不會被回收。而底層工作負載被其他控制器會人為修改時,KubeVela 也可以觀察到這些變化。
  • “接管”(take-over)模式意味著底層的工作負載會被 KubeVela 完全管理,跟其他直接透過 KubeVela 體系建立出來的工作負載一樣,工作負載的更新、刪除等生命週期將完全由 KubeVela 應用體系控制。預設情況下,其他系統對工作負載的修改也就不再生效,會被 KubeVela 面向終態的控制迴圈改回來,除非你加入了其他的管理策略(如 apply-once)。

而宣告接管模式的方法則使用 KubeVela 的策略(policy)體系,如下所示:

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: read-only
spec:
  components:
    - name: nginx
      type: webservice
      properties:
        image: nginx
  policies:
    - type: read-only
      name: read-only
      properties:
        rules:
          - selector:
              resourceTypes: ["Deployment"]

在 “read-only” 策略中,我們定義了多種只讀規則,如樣例中只讀選擇器命中的資源是 “Deployment”,那就意味著只有對 Deployment 的資源是隻讀的,我們依舊可以透過運維特徵建立和修改 “Ingress”、“Service” 等資源,而使用 “scaler” 運維特徵對 Deployment 的例項數做修改則不會生效。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: take-over
spec:
  components:
    - name: nginx-take-over
      type: k8s-objects
      properties:
        objects:
          - apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx
      traits:
        - type: scaler
          properties:
            replicas: 3
  policies:
    - type: take-over
      name: take-over
      properties:
        rules:
          - selector:
              resourceTypes: ["Deployment"]

在 “take-over” 策略中,我們也包括了一系列的選擇器,可以保證接管的資源是可控的。而上述的例子在不加 “take-over” 策略時,如果系統中已經有名為 “nginx” 的 Deployment 資源,則會執行失敗,因為資源已經存在。一方面,接管策略保證了應用建立時可以將已經存在的資源納入管理;另一方面,也可以複用之前已經存在的工作負載配置,只會將諸如 scaler 運維特徵中對例項數的修改作為配置的一部分 “patch”到原先的配置上。

使用命令列一鍵接管工作負載

在瞭解了接管模式以後,你肯定會想是否有一種簡便的方式,可以一鍵接管工作負載?沒錯,KubeVela  的命令列提供了這種簡便方式,可以將諸如 K8s 常見的資源、“Helm” 等工作負載一鍵接管,使用起來非常方便。具體而言,velaCLI 會自動去識別系統裡的資源並將其組裝成一個應用完成接管,我們在設計這個功能的核心原則是 “資源的接管不能觸發底層工作負載的重啟”。

如下所示,預設情況下,使用 vela adopt 會用 “read-only” 模式管理,只需指定要接管的原生資源型別、名稱空間及其名稱,就可以自動生成接管的 Application 物件。生成的應用 spec 跟叢集中實際的欄位嚴格一致。

$ vela adopt deployment/default/example configmap/default/example
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  labels:
    app.oam.dev/adopt: native
  name: example
  namespace: default
spec:
  components:
  - name: example.Deployment.example
    properties:
      objects:
      - apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: example
          namespace: default
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: example
          template:
            metadata:
              labels:
                app: example
            spec:
              containers:
              - image: nginx
                imagePullPolicy: Always
                name: nginx
              restartPolicy: Always
          ...
    type: k8s-objects
  - name: example.config
    properties:
      objects:
      - apiVersion: v1
        kind: ConfigMap
        metadata:
          name: example
          namespace: default
    type: k8s-objects
  policies:
  - name: read-only
    properties:
      rules:
      - selector:
          componentNames:
          - example.Deployment.example
          - example.config
    type: read-only

目前支援的預設接管型別其名稱和資源 API 對應關係如下:

  • crd: ["CustomResourceDefinition"]
  • ns: ["Namespace"]
  • workload: ["Deployment", "StatefulSet", "DaemonSet", "CloneSet"]
  • service: ["Service", "Ingress", "HTTPRoute"]
  • config: ["ConfigMap", "Secret"]
  • sa: ["ServiceAccount", "Role", "RoleBinding", "ClusterRole", "ClusterRoleBinding"]
  • operator: ["MutatingWebhookConfiguration", "ValidatingWebhookConfiguration", "APIService"]
  • storage: ["PersistentVolume", "PersistentVolumeClaim"]

如果想要把應用改成接管模式、並且直接部署到叢集中,只需增加幾個引數即可:

vela adopt deployment/default/example --mode take-over --apply

除了原生資源,vela 命令列也預設支援接管 Helm 應用建立的工作負載。

vela adopt mysql --type helm --mode take-over --apply --recycle -n default

如上述命令就會透過“接管” 模式管理 "default" 名稱空間下名為 “mysql” 的 helm release,指定 --recycle 可以在部署成功後把原來的 helm release 元資訊清理掉。

接管後的工作負載就已經生成出了 KubeVela 的 Application,所以相關的操作就已經跟 KubeVela 體系對接,你可以在 VelaUX 介面上看到接管的應用,也可以透過 vela 命令列的其他功能檢視、操作應用。

你還可以透過命令批次一鍵接管你名稱空間的全部工作負載,根據 KubeVela 的資源拓撲關係能力,系統會自動識別關聯的資源,形成一個完整的應用。對於 CRD 等自定義資源,KubeVela 也支援自定義關聯關係的規則。

vela adopt --all --apply

這個命令會預設以內建資源拓撲規則識別當前名稱空間下的資源及其關聯關係,並進行應用接管。以一個 Deployment 為例,自動接管後的應用如下,除了主工作負載 Deployment 之外,還接管了它的對應資源,包括 ConfigMap,Service 以及 Ingress。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: test2
  namespace: default
spec:
  components:
  - name: test2.Deployment.test2
    properties:
      objects:
      - apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: test2
          namespace: default
        spec:
          ...
    type: k8s-objects
  - name: test2.Service.test2
    properties:
      objects:
      - apiVersion: v1
        kind: Service
        metadata:
          name: test2
          namespace: default
        spec:
          ...
    type: k8s-objects
  - name: test2.Ingress.test2
    properties:
      objects:
      - apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:
          name: test2
          namespace: default
        spec:
          ...
    type: k8s-objects
  - name: test2.config
    properties:
      objects:
      - apiVersion: v1
        kind: ConfigMap
        metadata:
          name: record-event
          namespace: default
    type: k8s-objects
  policies:
  - name: read-only
    properties:
      rules:
      - selector:
          componentNames:
          - test2.Deployment.test2
          - test2.Service.test2
          - test2.Ingress.test2
          - test2.config
    type: read-only

演示效果如下:

 title=

如果你希望使用自定義資源拓撲關係納管自定義資源,可以使用如下命令:

vela adopt <your-crd> --all --resource-topology-rule=<your-rule-file.cue>

“接管規則”靈活定義

鑑於 KubeVela 充分可擴充套件的設計原則,資源接管面臨的工作負載、接管方式也各不相同,我們自然也設計了完全可擴充套件、可程式設計的工作負載接管方式。事實上,命令列的一鍵接管能力,也只是基於 KubeVela 可擴充套件接管規則的一種特例 [ 1] 。其核心思想是透過 CUE 定義一種配置轉換的規則,然後在執行 vela adopt 命令時指定轉換規則即可,如下所示。

vela adopt deployment/my-workload --adopt-template=my-adopt-rule.cue

這種模式僅適用於高階使用者,在這裡我們將不做過於深入的展開。如果你想了解更多細節,可以參考工作負載接管的官方文件 [ 2]

大幅效能最佳化

效能最佳化也是本次版本中的一大亮點,基於過往社群中各類使用者不同場景的實踐,我們在預設資源配額不變的情況下,將控制器的整體效能、單應用容量、應用處理吞吐量整體提升了 5 到 10 倍。 其中也包含了一些預設配置的變化,針對一些影響效能的小眾場景,做引數上的裁剪。

在單應用容量層面,由於 KubeVela 的應用可能會包含大量實際的 Kubernetes API,這往往會導致 Application 背後記錄實際資源狀態的 ResourceTracker 以及記錄版本資訊的 ApplicationRevision 物件超過 Kubernetes 單個物件的 2MB 限額。在 1.7 版本中,我們加入了 ztsd 壓縮功能並預設開啟,這直接將資源的大小壓縮了近 10 倍 [ 3] 。這也意味著單個 KubeVela Application 中能夠支援的資源容量擴大了 10 倍。

除此之外,針對一些場景如記錄應用版本、元件版本,這些版本記錄本身會由於應用數量規模的上升而等比例倍數提升,如預設記錄 10 個應用版本,則會按應用數量的十倍遞增。由於控制器本身 list-watch 的機制,這些增加的物件都會佔用控制器記憶體,會導致記憶體使用量大幅提升。而許多使用者(如使用 GitOps)可能有自己的版本管理系統,為了避免記憶體上的浪費,我們將應用版本的預設記錄上限從 10 個改成了 2 個。而對於使用場景相對小眾的元件版本,我們則預設關閉。這使得控制器整體的記憶體消耗縮小為原先的 1/3。

除此之外,還有一些引數調整包括將 Definition 的歷史版本記錄從 20 個縮小為 2 個,將 Kubernetes API 互動的限流 QPS 預設從 100 提升到 200 等等。在後續的版本中,我們將持續最佳化控制器的效能。

易用性提升

除了版本核心功能和效能提升以外,這個版本還對諸多的功能易用性進行了提升。

客戶端多環境資源渲染

dry run 是 Kubernetes 中很受歡迎的一個概念,即在資源實際生效之前,先空執行一下,校驗資源的配置是否合法。在 KubeVela 中也有這個功能,除了校驗資源是否可以執行,還能將 OAM 抽象的應用轉換為 Kubernetes 原生資源的 API,能夠在 CLI 客戶端實現從應用抽象到實際資源的轉換。而 1.7 中增加的功能,就是指定不同的檔案做 dry run,生成不同的實際資源。

如我們可以將測試和生產兩個不同環境的策略(policy)和工作流(workflow)寫成不同的檔案,分別為 "test-policy.yaml" 和 "prod-policy.yaml",這樣就可以在客戶端,對同一個應用指定不同環境的策略和工作流,生成不同的底層資源,如:

  • 測試環境執行
vela dry-run  -f app.yaml -f test-policy.yaml -f test-workflow.yaml
  • 生產環境執行
vela dry-run  -f app.yaml -f prod-policy.yaml -f prod-workflow.yaml

其中,app.yaml 中的內容如下,指定了引用一個外部的工作流:

# app.yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: first-vela-app
spec:
  components:
    - name: express-server
      type: webservice
      properties:
        image: oamdev/hello-world
        ports:
         - port: 8000
           expose: true
      traits:
        - type: scaler
          properties:
            replicas: 1
  workflow:
    ref: deploy-demo

而 prod-plicy.yaml 和 prod-workflow.yaml 的內容分別如下:

apiVersion: core.oam.dev/v1alpha1
kind: Policy
metadata:
  name: env-prod
type: topology
properties:
  clusters: ["local"]
  namespace: "prod"
---
apiVersion: core.oam.dev/v1alpha1
kind: Policy
metadata:
  name: ha
type: override
properties:
  components:
  - type: webservice
    traits:
    - type: scaler
      properties:
        replicas: 2
apiVersion: core.oam.dev/v1alpha1
kind: Workflow
metadata:
  name: deploy-demo
  namespace: default
steps:
  - type: deploy
    name: deploy-prod
    properties:
      policies: ["ha", "env-prod"]

對應的,測試環境的 YAML 檔案可以用同樣的模式修改其中的引數,這個功能非常適用於將 KubeVela 用作客戶端抽象工具的使用者,結合 Argo 等工具做資源的同步。

應用刪除功能增強

在許多特殊場景下,應用刪除一直是一個比較痛苦的體驗。在 1.7 版本中,我們加入一些簡便的方式,針對各類特殊情況,支援應用的順利刪除。

  • 在叢集失聯的特殊情況下刪除部分對應工作負載

我們提供了一個互動式刪除資源的方法,可以透過檢視叢集名稱、名稱空間、資源型別,來選擇底層工作負載,摘除叢集失聯這類特殊場景下涉及的資源。

 title=

  • 刪除應用時保留底層資源

如果只想刪除應用後設資料而底層的工作負載和配置想保留,此時可以用 --orphan 引數在刪除應用是保留下層資源。

  • 在控制器已經解除安裝的情況下刪除應用

當你已經解除安裝了 KubeVela 的控制器,但發現還有殘留應用沒刪乾淨時,你可以透過指定 --force 來刪除這些應用。

外掛安裝後自定義輸出

對於 KubeVela 外掛體系,我們新增了一個 NOTES.cue 檔案,可以允許外掛的製作者動態的輸出安裝完成後的提示。比如針對 backstage 這個外掛,其中的 NOTES.cue 檔案如下:

info: string
if !parameter.pluginOnly {
  info: """
    By default, the backstage app is strictly serving in the domain `127.0.0.1:7007`, check it by:
                
        vela port-forward addon-backstage -n vela-system
    
    You can build your own backstage app if you want to use it in other domains. 
    """
}
if parameter.pluginOnly {
  info: "You can use the endpoint of 'backstage-plugin-vela' in your own backstage app by configuring the 'vela.host', refer to example https://github.com/wonderflow/vela-backstage-demo."
}
notes: (info)

這個外掛的輸出就會根據使用者安裝外掛時使用的不同引數顯示不同內容。

工作流能力增強

在 1.7 版本中,我們支援了更多細粒度的工作流能力:

  • 支援指定某個失敗的步驟做重試
vela workflow restart <app-name> --step=<step-name>
  • 工作流的步驟名稱可以不填,由 webhook 自動生成。
  • 工作流的引數傳遞支援覆蓋已有引數。

除此之外,我們新增了一系列新的工作流步驟 [ 4] ,其中比較典型的步驟是 built-push-image,支援在工作流中構建映象並推送到映象倉庫中。在工作流步驟的執行過程中,你可以透過 vela workflow logs --step 檢視執行日誌。

VelaUX 功能增強

VelaUX 的控制檯也在 1.7 版本中做了一系列增強包括:

  • 支援更豐富的應用工作流編排能力,支援完整的工作流能力,包括子步驟、輸入輸出、超時、條件判斷、步驟依賴等功能。應用工作流狀態檢視也更全面,可以查詢歷史工作流記錄、步驟詳情、步驟的日誌和輸入輸出等資訊。
  • 支援應用版本回歸,可以檢視多版本之間應用的差異,選擇某個版本回滾。
  • 多租戶支援,對多租戶許可權做更嚴格的限制,於 Kubernetes RBAC 模型對齊。

近期的規劃

近期,KubeVela 1.8 正式版也在緊鑼密鼓的籌劃中,預計會在 3 月底正式跟大家見面,我們將在如下幾個方面進一步增強:

  • KubeVela 核心控制器的大規模效能和穩定性增強,針對控制器水平擴容提供分片(Sharding)方案,對多叢集場景下萬級別應用規模做控制器的效能最佳化和摸底,為社群提供一個全新的效能評測。
  • VelaUX 支援開箱即用的灰度釋出能力,對接可觀測外掛做釋出過程的互動。與此同時,VelaUX 形成可擴充套件框架體系,對 UI 的定製提供配置能力,支援業務自定義擴充套件和對接。
  • GitOps 工作流能力增強,支援 git 倉庫同步的應用對接 VelaUX 的完整體驗。

如果你想了解更多的規劃、成為貢獻者或者合作伙伴,可以透過參與社群溝通聯絡我們,期待你的加入!

社群溝通網址:https://github.com/kubevela/community

您可以透過如下材料瞭解更多關於 KubeVela 以及 OAM 專案的細節:

  • 專案程式碼庫:https://github.com/kubevela/kubevela 歡迎 Star/Watch/Fork!
  • 專案官方主頁與文件:kubevela.io
    從 1.1 版本開始,已提供中文、英文文件,更多語言文件歡迎開發者進行翻譯。
  • 專案釘釘群:23310022;Slack:CNCF #kubevela Channel
  • 加入微信群:請先新增以下 maintainer 微訊號,表明進入KubeVela使用者群:

 title=

相關連結:

[1] 特例

https://github.com/kubevela/kubevela/blob/master/references/cli/adopt-templates/default.cue

[2] 官方文件

https://kubevela.net/zh/docs/end-user/policies/resource-adoption

[3] 近 10 倍

https://github.com/kubevela/kubevela/pull/5090

[4] 新的工作流步驟

https://kubevela.net/docs/end-user/workflow/built-in-workflow...

點選此處檢視 KubeVela 專案官網

相關文章