雲邊協同下的統一應用管理:基於 OpenYurt 和 KubeVela 的解決方案
作者:喬中沛(伊靈)
背景
隨著萬物互聯場景的逐漸普及,邊緣裝置的算力也不斷增強,如何藉助雲端計算的優勢滿足複雜多樣化的邊緣應用場景,讓雲原生技術延伸到端和邊緣成為了新的技術挑戰,“雲邊協同”正在逐漸成為新的技術焦點。本文將圍繞 CNCF 的兩大開源專案 KubeVela 和 OpenYurt,以一個實際的 Helm 應用交付的場景,為大家介紹雲邊協同的解決方案。
OpenYurt 專注於以無侵入的方式將 Kubernetes 擴充套件到邊緣計算領域。OpenYurt 依託原生 Kubernetes 的容器編排、排程能力,將邊緣算力納入到 Kubernetes 基礎設施中統一管理,提供了諸如邊緣自治、高效運維通道、邊緣單元化管理、邊緣流量拓撲、安全容器、邊緣 Serverless/FaaS、異構資源支援等能力。簡而言之,OpenYurt 以 Kubernetes 原生的方式為雲邊協同構建了統一的基礎設施。
KubeVela 孵化於 OAM 模型,專注於幫助企業構建統一的應用交付和管理能力,為業務開發者遮蔽底層基礎設施複雜度,提供靈活的擴充套件能力,並提供開箱即用的微服務容器管理、雲資源管理、版本化和灰度釋出、擴縮容、可觀測性、資源依賴編排和資料傳遞、多叢集、CI 對接、GitOps 等特性。最大化的提升開發者自助式應用管理的研發效能,提升也滿足平臺長期演進的擴充套件性訴求。
OpenYurt 與 KubeVela 結合能解決什麼問題?
如上所述,OpenYurt 滿足了邊緣節點的接入,讓使用者可以通過操作原生 Kubernetes 的方式管理邊緣節點。邊緣節點通常用來表示距離使用者更近的計算資源,比如某個就近機房中的虛擬機器或物理伺服器等,通過 OpenYurt 加入後,這些邊緣節點會轉化為 Kubernetes 中可以使用的節點(Node)。OpenYurt 用節點池(NodePool)來描述同一地域的一組邊緣節點。在滿足了基本的資源管理後,針對應用如何編排部署到一個叢集中的不同節點池,我們通常會有如下核心需求:
1. 統一配置: 如果對每一份要下發的資源做手動修改,需要很多人工介入,非常容易出錯和遺漏。我們需要統一的方式來做引數配置,不僅可以方便地做批量管理操作,還可以對接安全和審計,滿足企業風險控制與合規需求。
2. 差異部署: 部署到不同節點池的工作負載有大部分屬性相同,然而總有個性化的配置差異。關鍵在於如何設定和節點選擇相關的引數,例如 NodeSelector
可以指示 Kubernetes 排程器將工作負載排程到不同的節點池。
3. 可擴充套件性: 雲原生生態繁榮,無論是工作負載種類還是不同的運維功能都在不斷增長,為了更靈活地滿足業務需求,我們需要整體的應用架構是可擴充套件的,能夠充分享受雲原生生態的紅利。
而 KubeVela 在應用層與 OpenYurt 可以很好的互補,滿足上述三個核心需求。接下來,我們結合實際的操作流程來展示這些功能點。
將應用部署到邊緣
我們將以Ingress控制器為例,展示如何使用KubeVela 將應用程式部署到邊緣。在這種情況下,我們希望將 Nginx Ingress 控制器部署到多個節點池中,以實現通過邊緣 Ingress 訪問指定節點池提供的服務,某個 Ingress 僅能由所在節點池的 Ingress 控制器處理。
示意圖的叢集中有兩個節點池:北京和上海,他們之間的網路不互通。我們希望再其中每個節點池都部署一個 Nginx Ingress Controller,並作為各自節點池的網路流量入口。一個靠近北京的客戶端,可以通過訪問北京節點池的 Ingress Controller,訪問北京節點池內提供的服務,且不會訪問到上海節點池提供的服務。
Demo 的基礎環境
我們將使用 Kubernetes 叢集模擬邊緣場景。群集有 3 個節點,它們的角色分別是:
- 節點 1:master 節點,雲端節點
- 節點 2:worker 節點,邊緣節點,在節點池
beijing
中 - 節點 3:worker 節點,邊緣節點,在節點池
shanghai
中
準備工作
1. 安裝 YurtAppManager
YurtAppManager 是 OpenYurt 的核心元件。它提供節點池 CRD 和控制器。OpenYurt 中還有其他元件,但在本教程中我們只需要 YurtAppManager.
git clone https://github.com/openyurtio/yurt-app-managercd yurt-app-manager && helm install yurt-app-manager -n kube-system ./charts/yurt-app-manager/
2.安裝KubeVela,啟用 FluxCD 外掛。
安裝 Vela 命令列工具,並在叢集中安裝 KubeVela。
curl -fsSl https://kubevela.net/script/install.sh | bash
vela install
在本案例中,為了複用社群提供的成熟的 Helm Chart,我們用 Helm 型別的元件來安裝 Nginx Ingress Controller。在微核心設計的 KubeVela 中,Helm 型別的元件是由 FluxCD 外掛提供的,下面啟用 FluxCD 外掛 [ 1] 。
vela addon enable fluxcd
3. 準備節點池
建立兩個節點池:北京節點池和上海節點池。在實際的邊緣場景中,以地域劃分節點池是常見的模式。不同分組的節點間往往存在網路不互通、資源不共享、資源異構、應用獨立等明顯的隔離屬性。這也是節點池概念的由來。在 OpenYurt 中,通過節點池、服務拓撲等功能幫助使用者處理上述問題。今天的例子中我們將使用節點池來描述和管理節點。
kubectl apply -f - <<EOF
apiVersion: apps.openyurt.io/v1beta1
kind: NodePool
metadata:
name: beijing
spec:
type: Edge
annotations:
apps.openyurt.io/example: test-beijing
taints:
- key: apps.openyurt.io/example
value: beijing
effect: NoSchedule
---
apiVersion: apps.openyurt.io/v1beta1
kind: NodePool
metadata:
name: shanghai
spec:
type: Edge
annotations:
apps.openyurt.io/example: test-shanghai
taints:
- key: apps.openyurt.io/example
value: shanghai
effect: NoSchedule
EOF
將邊緣節點加入到各自的節點池,邊緣節點的加入方式可以參考 OpenYurt 節點加入的方式。
kubectl label node <node1> apps.openyurt.io/desired-nodepool=beijing
kubectl label node <node2> apps.openyurt.io/desired-nodepool=shanghai
kubectl get nodepool
預期輸出
NAME TYPE READYNODES NOTREADYNODES AGE
beijing Edge 1 0 6m2s
shanghai Edge 1 0 6m1s
批量部署邊緣應用
在我們深入細節之前,讓我們看看 KubeVela 是如何描述部署到邊緣的應用的。通過下面這個應用,我們可以將 Nginx Ingress Controller 部署多份到各自的邊緣節點池。使用同一個應用來統一配置 Nginx Ingress 可以消除重複,降低管理負擔,也方便後續對叢集內的元件統一進行釋出運維等常見操作。
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: edge-ingress
spec:
components:
- name: ingress-nginx
type: helm
properties:
chart: ingress-nginx
url: https://kubernetes.github.io/ingress-nginx
repoType: helm
version: 4.3.0
values:
controller:
service:
type: NodePort
admissionWebhooks:
enabled: false
traits:
- type: edge-nginx
policies:
- name: replication
type: replication
properties:
selector: [ "ingress-nginx" ]
keys: [ "beijing","shanghai" ]
workflow:
steps:
- name: deploy
type: deploy
properties:
policies: ["replication"]
一個 KubeVela Application 有 3 個部分:
-
一個
helm
型別元件。它描述了我們想要安裝到叢集的 Helm 包版本。此外,我們給這個元件附加了一個運維特徵(trait)edge-nginx
。我們稍後將展示這個運維特徵的具體情況,現在你可以將其視為一個包含不同節點池的屬性的補丁。 -
一個
replication
(元件分裂)策略。它描述瞭如何將元件複製到不同的節點池。該selector
欄位用於選擇需要複製的元件。它的keys
欄位將把一個元件轉換為具有不同 key 的兩個元件。(“beijing”和“shanghai”)
3. deploy
工作流步驟。它描述瞭如何部署應用程式。它指定 replication
策略執行復制工作的策略。
注意:
- 如果你希望此應用程式正常工作,請先在叢集下發在下文介紹的
edge-ingress
特性。deploy
是一個 KubeVela 內建的工作流程步驟。它還可以在多叢集場景 [2 ] 中與override
、topology
策略一起使用 。
現在,我們可以將應用下發到叢集。
vela up -f app.yaml
檢查應用狀態和 KubeVela 建立的資源。
vela status edge-ingress --tree --detail
預期輸出
CLUSTER NAMESPACE RESOURCE STATUS APPLY_TIME DETAIL
local ─── default─┬─ HelmRelease/ingress-nginx-beijing updated 2022-11-02 12:00:24 Ready: True Status: Release reconciliation succeeded Age: 153m
├─ HelmRelease/ingress-nginx-shanghai updated 2022-11-02 12:00:24 Ready: True Status: Release reconciliation succeeded Age: 153m
└─ HelmRepository/ingress-nginx updated 2022-11-02 12:00:24 URL: https://kubernetes.github.io/ingress-nginx Age: 153m
Ready: True
Status: stored artifact for revision '7bce426c58aee962d479ca84e5c
fc6931c19c8995e31638668cb958d4a3486c2'
Vela CLI 不僅可以站在較高層次統一彙集展示應用健康狀態,當需要的時候,Vela CLI 也可以幫助你穿透應用,直達底層工作負載,並提供豐富的觀測和 Debug 能力,例如,你可以通過 vela logs
把列印應用的日誌;可以通過 vela port-forward
把部署應用的埠轉發到本地;可以通過 vela exec
命令,深入到邊緣的容器中執行 Shell 命令排查問題。
如果你想更直觀地瞭解應用去情況,KubeVela 官方還提供了 Web 控制檯外掛 VelaUX。啟用 VelaUX 外掛 [3 ] ,你可以檢視更詳細的資源拓撲。
vela addon enable velaux
訪問 VelaUX 的資源拓撲頁面。
正如你所看到的,KubeVela 建立了兩個 HelmRelease
資源,把 Nginx Ingress Controller 的 Helm Chart 交付到兩個節點池。 HelmRelease
資源被上述 FluxCD 外掛處理並在叢集兩個節點池中分別安裝了 Nginx Ingress。通過以下命令,檢查是否在北京節點池中建立了 Ingress Controller 的 Pod,上海節點池同理。
$ kubectl get node -l apps.openyurt.io/nodepool=beijing
NAME STATUS ROLES AGE VERSION
iz0xi0r2pe51he3z8pz1ekz Ready <none> 23h v1.24.7+k3s1
$ kubectl get pod ingress-nginx-beijing-controller-c4c7cbf64-xthlp -oyaml|grep iz0xi0r2pe51he3z8pz1ekz
nodeName: iz0xi0r2pe51he3z8pz1ekz
差異化部署
KubeVela 應用交付過程中如何實現了同一個元件的差異化部署?讓我們繼續深入瞭解支撐應用的 Trait(運維特徵)和 Policy(應用策略)。上文提到我們在工作流中使用了 KubeVela 內建的元件分裂(replication) Policy,給 ingress-nginx 元件附加了一個自定義的 edge-nginx Trait
。
-
元件分裂 Policy 將元件拆為兩個元件,帶有不同的
context.replicaKey
。 -
edge-nginx
Trait 使用不同的context.replicaKey
,將帶有不同配置值的 Helm Chart 交付到叢集中。讓兩個 Nginx Ingress Controller 執行在不同的節點池,監聽具有不同 ingressClass 的 Ingress 資源。具體的方式是 Patch 了 Helm Chart 的 Values 配置,修改了和節點選擇、親和性以及 ingressClass 相關的欄位。 -
在 Patch 不同欄位時,使用了不同的 Patch 策略 [4 ] (PatchStrategy),例如使用
retainKeys
策略能夠覆蓋原本的值,使用jsonMergePatch
策略則會和原本的值合併。
"edge-nginx": {
type: "trait"
annotations: {}
attributes: {
podDisruptive: true
appliesToWorkloads: ["helm"]
}
}
template: {
patch: {
// +patchStrategy=retainKeys
metadata: {
name: "(context.name)-(context.replicaKey)"
}
// +patchStrategy=jsonMergePatch
spec: values: {
ingressClassByName: true
controller: {
ingressClassResource: {
name: "nginx-" + context.replicaKey
controllerValue: "openyurt.io/" + context.replicaKey
}
_selector
}
defaultBackend: {
_selector
}
}
}
_selector: {
tolerations: [
{
key: "apps.openyurt.io/example"
operator: "Equal"
value: context.replicaKey
},
]
nodeSelector: {
"apps.openyurt.io/nodepool": context.replicaKey
}
}
parameter: null
}
讓更多型別的應用走向邊緣
可以看到,為了將 Nginx Ingress 部署到不同節點池,我們僅自定義了一個四十餘行的 Trait 並充分利用了 KubeVela 內建的能力。在雲原生生態愈加繁榮和雲邊協同的趨勢下,更多的應用都可能走向邊緣部署。當新場景中需要一個新的應用部署在邊緣節點池時,也無需煩惱,因為在 KubeVela 的幫助下,仿照該模式擴展出一個新的邊緣應用部署 Trait 也很容易,無需編寫程式碼。
例如,我們希望將 K8s 社群近期的演進熱點 Gateway API [5 ] 的實現也部署到邊緣,通過 Gateway API 增強邊緣節點池暴露服務的表達能力、擴充套件性,在邊緣節點使用基於角色的網路 API 等。對於這種場景,我們也可以基於上述擴充套件方式輕鬆完成部署任務,只需要定義如下的一個新 Trait。
"gateway-nginx": {
type: "trait"
annotations: {}
attributes: {
podDisruptive: true
appliesToWorkloads: ["helm"]
}
}
template: {
patch: {
// +patchStrategy=retainKeys
metadata: {
name: "(context.name)-(context.replicaKey)"
}
// +patchStrategy=jsonMergePatch
spec: values: {
_selector
fullnameOverride: "nginx-gateway-nginx-" + context.replicaKey
gatewayClass: {
name: "nginx" + context.replicaKey
controllerName: "k8s-gateway-nginx.nginx.org/nginx-gateway-nginx-controller-" + context.replicaKey
}
}
}
_selector: {
tolerations: [
{
key: "apps.openyurt.io/example"
operator: "Equal"
value: context.replicaKey
},
]
nodeSelector: {
"apps.openyurt.io/nodepool": context.replicaKey
}
}
parameter: null
}
這個 Trait 和前文提到的部署 Nginx Ingress 使用的 Trait 非常相似,其中,我們也同樣對 Nginx Gateway Chart 的 Values 做了一些相似的 Patch,包括節點選擇、親和性、資源名稱。和前文 Trait 的區別是該 Trait 指定了 gatewayClass 而非 IngressClass。該案例的 Trait 和應用檔案詳見 GitHub 倉庫 [6 ] 。通過自定義這樣一個 Trait,我們就給叢集擴充套件了部署一種新應用到邊緣的能力。
如果我們無法預知未來邊緣計算的發展帶來的更多應用部署需求,至少我們可以通過這種更容易擴充套件的方式不斷適應新的場景。
KubeVela 如何解決了邊緣部署難題
回顧 KubeVela 是如何解決文章開始提出的關鍵問題的。
1. 統一配置: 我們使用一個元件來描述要部署的 ingress-nginx Helm Chart 的通用的屬性例如 Helm 倉庫、Chart 名稱、版本等統一配置。
2. 屬性差異: KubeVela 使用了一個使用者自定義的運維特徵定義,它描述下發到不同的節點池的 Helm 配置差異。該運維特徵可以重複用於部署相同的 Helm Chart。
3. 可擴充套件性: KubeVela 可以為常見的工作負載(如 Deployment/StatefulSet)或其他打包方式(如 Helm/Kustomize/...)以可程式設計的方式進行擴充套件,只需若干行的程式碼,即可將一種新應用推向邊緣場景。
這些得益於 KubeVela 在應用交付和管理領域提供的強大功能,KubeVela 除了能在單個叢集內部解決應用的定義、交付、運維和可觀測問題,還原生支援了多叢集模式的應用釋出和管理。目前適合邊緣計算場景的 Kubernetes 部署模式並無定式,無論單叢集+邊緣節點池的架構,還是多邊緣叢集架構,KubeVela 都能勝任其中的應用管理任務。
在 OpenYurt 和 KubeVela 的配合下,雲邊應用以統一方式部署,共享相同的抽象、運維、可觀測能力,避免了在不同場景中割裂的體驗。並且雲端應用和邊端應用都得以使用 KubeVela 以外掛形式不斷整合的雲原生生態的優秀實踐。未來 KubeVela 社群還將不斷豐富開箱即用的系統外掛,持續交付更好用、更易用的應用交付和管理能力。
如果想了解更多應用部署、管理的能力,可以閱讀 KubeVela 官方文件 [7 ] ,想要了解 KubeVela 社群的最新動態,歡迎來到 KubeVela 社群 [8 ] (釘釘群 23310022)參與討論!若你對 OpenYurt 感興趣,也歡迎來到 OpenYurt 社群(釘釘群 31993519)參與討論。
您也可以通過如下材料瞭解更多關於 KubeVela 以及 OAM 專案的細節:
- 專案程式碼庫:https://github.com/kubevela/kubevela 歡迎 Star/Watch/Fork!
- 專案官方主頁與文件:kubevela.io ,從 1.1 版本開始,已提供中文、英文文件,更多語言文件歡迎開發者進行翻譯。
- 專案釘釘群:23310022;Slack:CNCF #kubevela Channel
- 加入微信群:請先新增以下 maintainer 微訊號,表明進入 KubeVela 使用者群:
戳此處 :檢視 KubeVela 專案官網!!
相關連結
[1] FluxCD 外掛
https://kubevela.net/zh/docs/reference/addons/fluxcd
[2] 多叢集場景
https://kubevela.net/docs/case-studies/multi-cluster
[3] 啟用 VelaUX 外掛
https://kubevela.net/zh/docs/reference/addons/velaux
[4] Patch 策略
https://kubevela.net/zh/docs/platform-engineers/traits/patch-trait#patch-strategy
[5] Gateway API
https://gateway-api.sigs.k8s.io/
[6] GitHub 倉庫
https://github.com/chivalryq/yurt-vela-example/tree/main/gateway-nginx
[7] KubeVela 官方文件
[8] KubeVela 社群
- 從 JDK 9 到 19,我們幫您提煉了和雲原生場景有關的能力列表(上)
- 統一觀測丨如何使用Prometheus 實現效能壓測指標可觀測
- CNStack 2.0:雲原生的技術中臺
- 全景剖析阿里雲容器網路資料鏈路(五):Terway ENI-Trunking
- 全景剖析阿里雲容器網路資料鏈路(四):Terway IPVLAN EBPF
- 全景剖析阿里雲容器網路資料鏈路(三):Terway ENIIP
- 談談我工作中的23個設計模式
- 雲邊協同下的統一應用管理:基於 OpenYurt 和 KubeVela 的解決方案
- OpenKruise v1.3:新增自定義 Pod Probe 探針能力與大規模叢集效能顯著提升
- Koordinator v0.7: 為任務排程領域注入新活力
- 傳統大型國企雲原生轉型,如何解決彈性、運維和團隊協同等問題
- Dubbo 3 易用性升級之 Dubbo 官網大改版
- 阿里雲容器服務 ACK 產品技術動態(202208)
- RocketMQ Streams在雲安全及 IoT 場景下的大規模最佳實踐
- RocketMQ 5.0:無狀態代理模式的探索與實踐
- Apache RocketMQ 5.0 在Stream場景的儲存增強
- 快手 RocketMQ 高效能實踐
- RocketMQ DLedger架構在小米的大規模實踐
- 定時任務報警通知解決方案詳解
- Dubbo Mesh 總體技術架構方案