文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

初探几种常用的 Kubernetes 多集群方案

2024-12-01 19:35

关注

集群联邦的一些典型应用场景:

Federation v1

最早的多集群项目,由 K8s 社区提出和维护。

Federation v1 在 K8s v1.3 左右就已经着手设计(Design Proposal),并在后面几个版本中发布了相关的组件与命令行工具(kubefed),用于帮助使用者快速建立联邦集群,并在 v1.6 时,进入了 Beta 阶段;但 Federation v1 在进入 Beta 后,就没有更进一步的发展,由于灵活性和 API 成熟度的问题,在 K8s v1.11 左右正式被弃用。

v1 的基本架构如上图,主要有三个组件:

在 v1 版本中我们要创建一个联邦资源的大致步骤如下:把联邦的所有配置信息都写到资源对象 annotations 里,整个创建流程与 K8s 类似,将资源创建到 Federation API Server,之后 Federation Controller Manager 会根据 annotations 里面的配置将该资源创建到各子集群;下面是一个 ReplicaSet 的示例:

这种架构带来的主要问题有两个:

Federation v2

有了 v1 版本的经验和教训之后,社区提出了新的集群联邦架构:Federation v2;Federation 项目的演进也可以参考 Kubernetes Federation Evolution 这篇文章。

v2 版本利用 CRD 实现了整体功能,通过定义多种自定义资源(CR),从而省掉了 v1 中的 API Server;v2 版本由两个组件构成:

在 v2 版本中要创建一个联邦资源的大致流程如下:

将 Federated Resource 创建到 Host 集群的 API Server 中,之后 controller-manager 会介入将相应资源分发到不同的集群,分发的规则等都写在了这个 Federated Resource 对象里面。

在逻辑上,Federation v2 分为两个大部分:configuration(配置)和 propagation(分发);configuration 主要包含两个配置:Cluster Configuration 和 Type Configuration。

Cluster Configuration

用来保存被联邦托管的集群的 API 认证信息,可通过 ​​kubefedctl join/unjoin​​ 来加入/删除集群,当成功加入时,会建立一个 ​​KubeFedCluster​​ CR 来存储集群相关信息,如 API Endpoint、CA Bundle 和 Token 等。后续 controller-manager 会使用这些信息来访问不同 Kubernetes 集群。

apiVersion: core.kubefed.io/v1beta1
kind: KubeFedCluster
metadata:
creationTimestamp: "2019-10-24T08:05:38Z"
generation: 1
name: cluster1
namespace: kube-federation-system
resourceVersion: "647452"
selfLink: /apis/core.kubefed.io/v1beta1/namespaces/kube-federation-system/kubefedclusters/cluster1
uid: 4c5eb57f-5ed4-4cec-89f3-cfc062492ae0
spec:
apiEndpoint: https://172.16.200.1:6443
caBundle: LS....Qo=
secretRef:
name: cluster1-shb2x
status:
conditions:
- lastProbeTime: "2019-10-28T06:25:58Z"
lastTransitionTime: "2019-10-28T05:13:47Z"
message: /healthz responded with ok
reason: ClusterReady
status: "True"
type: Ready
region: ""

Type Configuration

定义了哪些 Kubernetes API 资源要被用于联邦管理;比如说想将 ​​ConfigMap​​ 资源通过联邦机制建立在不同集群上时,就必须先在 Host 集群中,通过 CRD 建立新资源 ​​FederatedConfigMap​​,接着再建立名称为 ​​configmaps​​ 的 Type configuration(​​FederatedTypeConfig​​)资源,然后描述 ​​ConfigMap​​ 要被 ​​FederatedConfigMap​​ 所管理,这样 Kubefed controller-manager 才能知道如何建立 Federated 资源,一个示例如下:

apiVersion: core.kubefed.k8s.io/v1beta1
kind: FederatedTypeConfig
metadata:
name: configmaps
namespace: kube-federation-system
spec:
federatedType:
group: types.kubefed.k8s.io
kind: FederatedConfigMap
pluralName: federatedconfigmaps
scope: Namespaced
version: v1beta1
propagation: Enabled
targetType:
kind: ConfigMap
pluralName: configmaps
scope: Namespaced
version: v1

Federated Resource CRD

其中还有一个关键的
CRD:Federated Resource,如果想新增一种要被联邦托管的资源的话,就需要建立一个新的 FederatedXX 的
CRD,用来描述对应资源的结构和分发策略(需要被分发到哪些集群上);Federated Resource CRD 主要包括三部分:

一个示例如下:

apiVersion: types.kubefed.k8s.io/v1beta1
kind: FederatedDeployment
metadata:
name: test-deployment
namespace: test-namespace
spec:
template: # 定义 Deployment 的所有內容,可理解成 Deployment 与 Pod 之间的关联。
metadata:
labels:
app: nginx
spec:
...
placement:
clusters:
- name: cluster2
- name: cluster1
overrides:
- clusterName: cluster2
clusterOverrides:
- path: spec.replicas
value: 5

这些 FederatedXX CRD 可以通过 ​​kubefedctl enable ​ 来创建,也可以自己生成/编写对应的 CRD 再创建。

结合上面介绍了的 Cluster Configuration、Type Configuration 和 Federated Resource CRD,再来看 v2 版本的整体架构和相关概念就清晰很多了:

Scheduling

Kubefed 目前只能做到一些简单的集群间调度,即手工指定,对于手工指定的调度方式主要分为两部分,一是直接在资源中制定目的集群,二是通过 ​​ReplicaSchedulingPreference​​ 进行比例分配。

直接在资源中指定可以通过 ​​clusters​​ 指定一个 ​​cluster​​ 列表,或者通过 ​​clusterSelector​​ 来根据集群标签选择集群,不过有两点要注意:

spec:
placement:
clusters:
- name: cluster2
- name: cluster1
clusterSelector:
matchLabels:
foo: bar

如果需要在多个集群间进行区别调度的话就需要引入 ​​ReplicaSchedulingPreference​​ 进行按比例的调度了:

apiVersion: scheduling.kubefed.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
name: test-deployment
namespace: test-ns
spec:
targetKind: FederatedDeployment
totalReplicas: 9
clusters:
A:
minReplicas: 4
maxReplicas: 6
weight: 1
B:
minReplicas: 4
maxReplicas: 8
weight: 2

​totalReplicas​​ 定义了总副本数,​​clusters​​ 描述不同集群的最大/最小副本以及权重。

目前 ReplicaSchedulingPreference 只支持 deployments 和 replicasets 两种资源。

Karmada

Karmada 是由华为开源的多云容器编排项目,这个项目是 Kubernetes Federation v1 和 v2 的延续,一些基本概念继承自这两个版本。

Karmada 主要有三个组件:

和 Federation v1 类似,我们下发一个资源也是要写入到 Karmada 自己的 API Server 中,之前 controller-manager 根据一些 policy 把资源下发到各个集群中;不过这个 API Server 是 K8s 原生的,所以支持任何资源,不会出现之前 Federation v1 版本中的问题,然后联邦托管资源的分发策略也是由一个单独的 CRD 来控制的,也不需要配置 v2 中的 Federated Resource CRD 和 Type Configure。

Karmada 的一些基本概念:

Cluster

Cluster 资源记录的内容和 Federation v2 类似,就是访问被纳管集群的一些必要信息:API Endpoint、CA Bundle 和访问 Token。

spec:
apiEndpoint: https://172.31.165.66:55428
secretRef:
name: member1
namespace: karmada-cluster
syncMode: Push

但是有一个不一样的点是,Karmada 的 ​​Cluster​​ 资源有两种 sync 模式:​​Push​​ 和 ​​Pull​​;​​Push​​ 就是最普通、最常见的方式,host 集群的 Karmada 组件会负责同步并更新这类集群的状态;​​Pull​​ 模式的 member 集群上会运行一个 ​​karmada-agent​​ 组件,这个组件会负责收集自己的状态并且更新 host 集群的相应的 ​​Cluster​​ 资源状态。

Propagaion Policy

在 Karmada 中分发资源到 member 集群需要配置这个单独 ​​PropagationPolicy​​ CR;以下面的 nginx 应用为例,首先是 Resource Template,这个就是普通的 K8s ​​Deployment​​:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx

之后配置一个 ​​PropagationPolicy​​ 来控制这个 nginx ​​Deployment​​ 资源的分发策略即可,在下面的示例中,会将 nginx 应用按 1:1 的权重比分发到 member1 和 member2 集群中:

apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: nginx-propagation
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
placement:
clusterAffinity:
clusterNames:
- member1
- member2
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
- targetCluster:
clusterNames:
- member1
weight: 1
- targetCluster:
clusterNames:
- member2
weight: 1

在 Karmada API Server 中创建这两个资源后,可以通过 Karmada API Server 查询到该资源的状态:

$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/2 2 2 51s

但是注意,这并不代表应用运行在 Karmada API Server 所在的集群上,实际上这个集群上没有任何工作负载,只是存储了这些 Resource Template,实际的工作负载都运行在上面 ​​PropagationPolicy​​ 配置的 member1 和 member2 集群中,切换到 member1/member2 集群中可以看到:

$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 6m26s

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-7cgfz 1/1 Running 0 6m29s

分发策略除了上面最普通的指定集群名称外也支持 ​​LabelSelector​​、​​FieldSelector​​ 和 ​​ExcludeClusters​​,如果这几个筛选项都设置了,那只有全部条件都满足的集群才会被筛选出来;除了集群亲和性,还支持 ​​SpreadConstraints​​:对集群动态分组,按 ​​region​​、​​zone​​ 和 ​​provider​​ 等分组,可以将应用只分发到某类集群中。

针对有 ​​replicas​​ 的资源(比如原生的 ​​Deployment​​ 和 ​​StatefulSet​​),支持在分发资源到不同集群的时候按要求更新这个副本数,比如 member1 集群上的 nginx 应用我希望有 2 个副本,member2 上的只希望有 1 个副本;策略有很多,首先是 ​​ReplicaSchedulingType​​,有两个可选值:

而这个 ​​ReplicaDivisionPreference​​ 又有两个可选值:

完整和详细的结构可以参考 ​​Placement​​ 的 API 定义。

Override Policy

Override Policy 就很简单了,通过增加 ​​OverridePolicy​​ 这个 CR 来配置不同集群的差异化配置,直接看一个例子:

apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
name: example-override
namespace: default
spec:
resourceSelectors:
- apiVersion: apps/v1
kind: Deployment
name: nginx
targetCluster:
clusterNames:
- member1
labelSelector:
matchLabels:
failuredomain.kubernetes.io/region: dc1
overriders:
plaintext:
- path: /spec/template/spec/containers/0/image
operator: replace
value: 'dc-1.registry.io/nginx:1.17.0-alpine'
- path: /metadata/annotations
operator: add
value:
foo: bar

 参考链接

来源:奇妙的Linux世界内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯