作者
徐迪,騰訊云容器技術專家,
汝英哲,騰訊云高級產品經理,
摘要
在做多集群應用分發的時候,經常會遇到以下的差異化問題,比如:
- 在分發的資源上全部打上統一的標簽,比如
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 專案開源進行時,請關注 https://github.com/clusternet/clusternet 點贊支持,歡迎加入我們一起貢獻更多的功能,
相關鏈接
[1] https://github.com/clusternet/clusternet
[2] https://github.com/clusternet/kubectl-clusternet
[3] https://krew.sigs.k8s.io/plugins/
關于我們
更多關于云原生的案例和知識,可關注同名【騰訊云原生】公眾號~
福利:
①公眾號后臺回復【手冊】,可獲得《騰訊云原生路線圖手冊》&《騰訊云原生最佳實踐》~
②公眾號后臺回復【系列】,可獲得《15個系列100+篇超實用云原生原創干貨合集》,包含Kubernetes 降本增效、K8s 性能優化實踐、最佳實踐等系列,
【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/330042.html
標籤:其他

