作者

徐迪,腾讯云容器技术专家。
汝英哲,腾讯云高级产品经理。

摘要

在做多集群利用散发的时候,常常会遇到以下的差异化问题,比方:

  1. 在散发的资源上全部打上对立的标签,比方 apps.my.company/deployed-by: my-platform
  2. 在散发到子集群的资源上标记集群的信息,比方 apps.my.company/running-in: cluster-01
  3. 调整利用在每个集群中的正本数目、镜像名称等等,比方有一个名为 my-nginx (申明的正本数为 3)的 Deployment 利用要散发到集群 cluster-01,集群 cluster-02,集群 cluster-03 中,我心愿在这三个集群的正本数目别离为 3,5,7;
  4. 在散发到集群 cluster-01 之前,调整利用在该集群中的一些配置,比方注入一个 Sidecar 容器等;
  5. 遇到某些非凡场景时,例如大促,动静扩容,利用灰度降级时,心愿能够针对某个集群进行操作,变更范畴小,不影响到其余集群,同时呈现问题的时候,能够及时回滚,复原到变更前的状态;
  6. 如果定义了多个差异化配置,相互之间呈现抵触时,该如何解决;

开源 Clusternet 我的项目简介

Clusternet ( Cluster Internet ) 是腾讯云开源的兼具多集群治理和跨集群利用编排的云原生管控我的项目,让应用多集群就像上网一样简略。无论你的 Kubernetes 集群是运行在私有云、公有云、混合云还是边缘云上,都领有统一的治理/拜访体验,利用 K8s API 集中部署和协调多集群的应用程序和服务。

Clusternet 采纳 Addon 插件的形式,不便用户一键装置、运维及集成,轻松地治理数以百万计的 Kubernetes 集群,让云计算像 Internet 一样无所不在,自在便捷。

Clusternet 反对向不同集群散发和治理各种利用资源,包含原生 Kubernetes 各类资源(Deployment/StatefulSet/ConfigMap/Secret 等)、各类 CRD 资源,以及 HelmChart 利用等等。

Clusternet 如何解决这些差异化配置难题

Clusternet 在设计利用散发模型的时候,就充分考虑到了上述的那些场景,不心愿引入过多的简单设计,尽量减少用户的反复定义,做到精简化、不便配置、可扩展性强、便于变更回滚等等。

如果咱们将上述的差异化问题进行演绎,大抵能够演绎为以下两类:

  1. 通用化配置或者全局化配置,比方对于某些资源进行无差异化的打标签,预配置等等;
  2. 专属于某个集群的配置,比方更改 Deployment 在某集群对应的正本数,降级镜像,减少 Sidecar 容器等等;

下图是 Clusternet 的多集群利用散发模型,其中绿色的模块是须要用户去创立的,紫色的模块是 Clusternet 外部做流转的资源对象。Clusternet 提供了 kubectl 插件,能够通过 “kubectl clusternet apply” 命令来创立资源。欢送浏览 Clusternet - 新一代开源多集群治理与利用治理我的项目,理解图中的相干概念。

Clusternet 资源散发模型采纳松耦合的设计,用户毋庸更改或从新编写已有的资源对象,仅须要额定定义散发策略 (Subscription)和差异化配置(Localization/Globalization)即可实现多集群的利用散发。

Localization 与 Globalization

在 Clusternet 中,每个注册的集群,都会领有一个专属的 namespace (命名空间),因而咱们别离定义了 LocalizationGlobalization 这两个 CRD 用于申明差异化配置。其中 Localization 形容 namespace-scoped (命名空间作用域)的差异化配置策略,可用于对单个集群进行配置,比方 Deployment 在这个集群中的正本数目等。而 Globalization 形容 cluster-scoped (集群作用域) 的差异化配置策略,比方批改某个 HelmChart 的通用配置等。

Override 策略

Clusternet 还提供了两种 Overide 策略:ApplyLater(默认的策略)和 ApplyNowApplyLater 意味着该 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 能够很不便地反对面向多集群的蓝绿公布、金丝雀公布、版本升级等场景。在应用过程中, 你能够定义多个 GlobalizationLocalization 对象,并设置不同的优先级策略。

反对 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/v1alpha1kind: Localizationmetadata:  name: nginx-local-overrides-demo-label  namespace: clusternet-5l82l # 请更新这个值为对应集群的 namespacespec:  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-5l82lspec.feed 所定义的对象中。

这里 override 的值也能够 yaml 格局,见如下的例子。

apiVersion: apps.clusternet.io/v1alpha1kind: Localizationmetadata:  name: nginx-local-overrides-demo-label  namespace: clusternet-5l82l # 请更新这个值为对应集群的 namespacespec:  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-nginxclusternet-5l82l 子集群中的正本数更改为 3,替换容器的镜像为 nginx:1.14.0-alpine,并减少一个新的正文 foo: bar

apiVersion: apps.clusternet.io/v1alpha1kind: Localizationmetadata:  name: nginx-local-overrides-demo-image-replicas  namespace: clusternet-5l82l # 请更新这个值为对应集群的 namespacespec:  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-nginxclusternet-5l82l 子集群下的实例注入 Sidecar 容器,见如下的示例,

apiVersion: apps.clusternet.io/v1alpha1kind: Localizationmetadata:  name: nginx-local-overrides-demo-sidecar  namespace: clusternet-5l82l # 请更新这个值为对应集群的 namespacespec:  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"

通过 LocalizationGlobalization 不仅仅能够做如上的差异化配置,还有更多的场景期待着大家去挖掘。

为了不便大家上手体验一番,Clusternet 提供了例子,大家能够参照 README 中的步骤来实际一下多集群的利用散发。

退出咱们

Clusternet 我的项目开源进行时,请关注 https://github.com/clusternet... 点赞反对,欢送退出咱们一起奉献更多的性能。

相干链接

[1] https://github.com/clusternet...

[2] https://github.com/clusternet...

[3] https://krew.sigs.k8s.io/plug...

对于咱们

更多对于云原生的案例和常识,可关注同名【腾讯云原生】公众号~

福利:

①公众号后盾回复【手册】,可取得《腾讯云原生路线图手册》&《腾讯云原生最佳实际》~②公众号后盾回复【系列】,可取得《15个系列100+篇超实用云原生原创干货合集》,蕴含Kubernetes 降本增效、K8s 性能优化实际、最佳实际等系列。
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!