Clusternet v0.5.0 重磅發布: 全面解決多集群應用分發的差異化配置難題
作者
徐迪,騰訊雲容器技術專家。
汝英哲,騰訊雲高級產品經理。
摘要
在做多集群應用分發的時候,經常會遇到以下的差異化問題,比如:
- 在分發的資源上全部打上統一的標籤,比如
apps.my.company/deployed-by: my-platform; - 在分發到子集群的資源上標記集群的資訊,比如
apps.my.company/running-in: cluster-01; - 調整應用在每個集群中的副本數目、鏡像名稱等等,比如有一個名為
my-nginx(聲明的副本數為 3)的Deployment應用要分發到集群 cluster-01,集群 cluster-02,集群 cluster-03 中,我希望在這三個集群的副本數目分別為 3,5,7; - 在分發到集群 cluster-01 之前,調整應用在該集群中的一些配置,比如注入一個 Sidecar 容器等;
- 遇到某些特殊場景時,例如大促,動態擴容,應用灰度升級時,希望可以針對某個集群進行操作,變更範圍小,不影響到其他集群,同時出現問題的時候,可以及時回滾,恢復到變更前的狀態;
- 如果定義了多個差異化配置,相互之間出現衝突時,該如何解決;
開源 Clusternet 項目簡介
Clusternet ( Cluster Internet ) 是騰訊雲開源的兼具多集群管理和跨集群應用編排的雲原生管控項目,讓使用多集群就像上網一樣簡單。無論你的 Kubernetes 集群是運行在公有雲、私有雲、混合雲還是邊緣雲上,都擁有一致的管理/訪問體驗,利用 K8s API 集中部署和協調多集群的應用程式和服務。
Clusternet 採用 Addon 插件的方式,方便用戶一鍵安裝、運維及集成,輕鬆地管理數以百萬計的 Kubernetes 集群,讓雲計算像 Internet 一樣無所不在,自由便捷。
Clusternet 支援向不同集群分發和管理各種應用資源,包括原生 Kubernetes 各類資源(Deployment/StatefulSet/ConfigMap/Secret 等)、各類 CRD 資源,以及 HelmChart 應用等等。
Clusternet 如何解決這些差異化配置難題
Clusternet 在設計應用分發模型的時候,就充分考慮到了上述的那些場景,不希望引入過多的複雜設計,盡量減少用戶的重複定義,做到精簡化、方便配置、可擴展性強、便於變更回滾等等。
如果我們將上述的差異化問題進行歸納,大致可以歸納為以下兩類:
-
通用化配置或者全局化配置,比如對於某些資源進行無差異化的打標籤,預配置等等;
-
專屬於某個集群的配置,比如更改
Deployment在某集群對應的副本數,升級鏡像,增加 Sidecar 容器等等;
下圖是 Clusternet 的多集群應用分發模型,其中綠色的模組是需要用戶去創建的,紫色的模組是 Clusternet 內部做流轉的資源對象。Clusternet 提供了 kubectl 插件,可以通過 「kubectl clusternet apply」 命令來創建資源。歡迎閱讀 Clusternet - 新一代開源多集群管理與應用治理項目,了解圖中的相關概念。

Clusternet 資源分發模型採用松耦合的設計,用戶無須更改或重新編寫已有的資源對象,僅需要額外定義分發策略 (Subscription)和差異化配置(Localization/Globalization)即可實現多集群的應用分發。
Localization 與 Globalization
在 Clusternet 中,每個註冊的集群,都會擁有一個專屬的 namespace (命名空間),因此我們分別定義了 Localization 和 Globalization 這兩個 CRD 用於聲明差異化配置。其中 Localization 描述 namespace-scoped (命名空間作用域)的差異化配置策略,可用於對單個集群進行配置,比如 Deployment 在這個集群中的副本數目等。而 Globalization 描述 cluster-scoped (集群作用域) 的差異化配置策略,比如修改某個 HelmChart 的通用配置等。
Override 策略
Clusternet 還提供了兩種 Overide 策略:ApplyLater(默認的策略)和 ApplyNow。ApplyLater 意味著該 Localization/Globalization 的差異化配置不會立即應用到資源上,只會在隨後新創建出來的 Description 對象或者 HelmChart/Subscription/Description 等各個資源對象更新的時候才生效。而 ApplyNow 意味著會創建後即時生效,Clusternet 會將定義的差異化配置應用到所有匹配的對象中,即時下發到對應的子集群中。
Priority 優先順序
此外,兩者均支援按照 Priority(優先順序)進行管理和配置,優先順序的高低通過 0-1000 的數值來定義,值越小,優先順序越低,默認是500。在進行差異化渲染的時候,Clusternet 會按照 Globalization (低優先順序) -> Globalization (高優先順序) -> Localization (低優先順序) -> Localization (高優先順序) 的次序,依次將聲明的 Override 進行 apply。
正是藉助於這種兩階段基於優先順序(two-stage priority based)的差異化配置能力,Clusternet 可以很方便地支援面向多集群的藍綠髮布、金絲雀發布、版本升級等場景。在使用過程中, 你可以定義多個 Globalization 和 Localization 對象,並設置不同的優先順序策略。
支援 Patch 操作
Clusternet 支援兩種格式的 Override,JSON Patch (RFC 6902) 和 JSON Merge Patch (RFC 7396)。有關 JSON patch 和 JSON 合併 patch 的比較,大家可以查看 JSON Patch 和 JSON Merge Patch,也可以參照如下的典型示例。
典型示例
下面我們來看幾個典型的差異化配置場景。在如下的例子中,我們通過 Localization 對象來統一展示。這裡使用 Globalization 也是可以的,這兩者的 Spec 定義都是一樣的,唯一的區別這兩者的作用域和優先順序差別。大家在實際使用的時候,可以根據需要進行改寫。
增加/更新標籤
如果我們想給某個對象增加或者更新標籤,可以這麼定義如下的 Localization 對象。在使用的時候,請將 metadata.namespace 的值替換為真實的註冊集群的專屬 namespace。
apiVersion: apps.clusternet.io/v1alpha1
kind: Localization
metadata:
name: nginx-local-overrides-demo-label
namespace: clusternet-5l82l # 請更新這個值為對應集群的 namespace
spec:
overridePolicy: ApplyLater
# 優先順序反映著該對象的重要性,數值範圍從 0 到 1000,值越小表示優先順序越低
# 默認的值為 500.
priority: 300
feed: # 這裡表示要 override 的對象
apiVersion: apps/v1
kind: Deployment
name: my-nginx
namespace: foo
overrides: # 這裡可以定義著多個 override
- name: add-update-labels
type: MergePatch # 這裡需要指定 override 的類型
# value 可以是 yaml 格式,也可以是 json 格式。
# 如下是 json 格式的例子
value: '{"metadata":{"labels":{"deployed-in-cluster":"clusternet-5l82l"}}}'
可以在一個 Localization 對象中定義多個 overrides,在上面的例子中,我們只定義了一個名為 add-update-labels 的 override,其值為 json 格式的字元串,目的是增加或者更新一個標籤 deployed-in-cluster: clusternet-5l82l 到 spec.feed 所定義的對象中。
這裡 override 的值也可以 yaml 格式,見如下的例子。
apiVersion: apps.clusternet.io/v1alpha1
kind: Localization
metadata:
name: nginx-local-overrides-demo-label
namespace: clusternet-5l82l # 請更新這個值為對應集群的 namespace
spec:
overridePolicy: ApplyLater
# 優先順序反映著該對象的重要性,數值範圍從 0 到 1000,值越小表示優先順序越低
# 默認的值為 500.
priority: 300
feed: # 這裡表示要 override 的對象
apiVersion: apps/v1
kind: Deployment
name: my-nginx
namespace: foo
overrides: # 這裡定義著 override value
- name: add-update-labels
type: MergePatch
# value 可以是 yaml 格式,也可以是 json 格式。
# 如下是 yaml 格式的例子
value: |-
metadata:
labels:
deployed-in-cluster: clusternet-5l82l
替換鏡像及副本數目
Override 的類型也可以指定為 JSONPatch。在實際使用的時候,可以根據需要選擇一個合適的 override 類型即可。
通過如下的例子,可以將 Deployment foo/my-nginx 在 clusternet-5l82l 子集群中的副本數更改為 3,替換容器的鏡像為 nginx:1.14.0-alpine,並增加一個新的注釋 foo: bar。
apiVersion: apps.clusternet.io/v1alpha1
kind: Localization
metadata:
name: nginx-local-overrides-demo-image-replicas
namespace: clusternet-5l82l # 請更新這個值為對應集群的 namespace
spec:
overridePolicy: ApplyLater
# 優先順序反映著該對象的重要性,數值範圍從 0 到 1000,值越小表示優先順序越低
# 默認的值為 500.
priority: 400
feed: # 這裡表示要 override 的對象
apiVersion: apps/v1
kind: Deployment
name: my-nginx
namespace: foo
overrides: # 這裡定義著 override value
- name: scale-and-add-annotations
type: JSONPatch
# value 可以是 yaml 格式,也可以是 json 格式。
value: |-
- path: /spec/replicas
value: 3
op: replace
- path: "/spec/template/spec/containers/0/image"
value: "nginx:1.14.0-alpine"
op: replace
- path: /metadata/annotations
value:
foo: bar
op: add
注入 Sidecar 容器
我們還可以通過 Localization 來為 Deployment foo/my-nginx 在 clusternet-5l82l 子集群下的實例注入 Sidecar 容器,見如下的示例,
apiVersion: apps.clusternet.io/v1alpha1
kind: Localization
metadata:
name: nginx-local-overrides-demo-sidecar
namespace: clusternet-5l82l # 請更新這個值為對應集群的 namespace
spec:
overridePolicy: ApplyLater
# 優先順序反映著該對象的重要性,數值範圍從 0 到 1000,值越小表示優先順序越低
# 默認的值為 500.
priority: 600
feed: # 這裡表示要 override 的對象
apiVersion: apps/v1
kind: Deployment
name: my-nginx
namespace: foo
overrides: # 這裡定義著 override value
- name: inject-new-container
type: JSONPatch
# value 可以是 yaml 格式,也可以是 json 格式。
value: |-
- op: add
path: "/spec/template/spec/containers/1"
value:
name: "redis-container"
image: "redis:6.2.5"
通過 Localization 和 Globalization 不僅僅可以做如上的差異化配置,還有更多的場景等待著大家去發掘。
為了方便大家上手體驗一番,Clusternet 提供了例子,大家可以參照 README 中的步驟來實踐一下多集群的應用分發。
加入我們
Clusternet 項目開源進行時,請關注 //github.com/clusternet/clusternet 點贊支援,歡迎加入我們一起貢獻更多的功能。
相關鏈接
[1] //github.com/clusternet/clusternet
[2] //github.com/clusternet/kubectl-clusternet
[3] //krew.sigs.k8s.io/plugins/
關於我們
更多關於雲原生的案例和知識,可關注同名【騰訊雲原生】公眾號~
福利:
①公眾號後台回復【手冊】,可獲得《騰訊雲原生路線圖手冊》&《騰訊雲原生最佳實踐》~
②公眾號後台回復【系列】,可獲得《15個系列100+篇超實用雲原生原創乾貨合集》,包含Kubernetes 降本增效、K8s 性能優化實踐、最佳實踐等系列。
【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多乾貨!!


