天天看點

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

作者:阿裡開發者
作者:孫健波(天元)

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接管後的工作負載就已經生成出了 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
示範效果如下:           

如上述指令就會通過“接管” 模式管理 "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           

示範效果如下:

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

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 等工具做資源的同步。

剩餘60%,完整内容請點選下方連結檢視:

https://developer.aliyun.com/article/1180121?utm_content=g_1000369869

版權聲明:本文内容由阿裡雲實名注冊使用者自發貢獻,版權歸原作者所有,阿裡雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿裡雲開發者社群使用者服務協定》和《阿裡雲開發者社群知識産權保護指引》。如果您發現本社群中有涉嫌抄襲的内容,填寫侵權投訴表單進行舉報,一經查實,本社群将立刻删除涉嫌侵權内容。

繼續閱讀