集群联邦的一些典型应用场景:多个供应商,并在必要时直接迁移到其他供应商。故障隔离:拥有多个小集群可能比单个大集群更有利于故障隔离。Federationv1最早的多集群项目,由K8s社区提出并维护。Federationv1已经围绕K8sv1.3(DesignProposal)进行了设计,并在接下来的几个版本中发布了相关组件和命令行工具(kubefed),帮助用户快速搭建federation集群,并在v1.6进入Beta阶段;但是Federationv1进入Beta后,就没有再开发了。由于灵活性和API成熟度问题,它在K8sv1.11前后被正式放弃。v1的基本架构如上图所示。主要包括三个组件:FederationAPIServer:类似于K8sAPIServer,对外提供统一的资源管理入口,但只允许使用Adapter扩展支持的K8s资源。ControllerManager:提供多个集群间的资源调度和State同步,类似于kube-controller-managerEtcd:用于存储Federation资源。在v1版本中,创建联邦资源的一般步骤如下:将联邦的所有配置信息写入资源对象注解中。整个创建过程和K8s类似。创建资源到FederationAPIServer,然后FederationControllerManager会根据注解中的配置创建资源到各个子集群;下面是一个ReplicaSet的例子:这种架构带来的问题主要有两个:不够灵活,每次创建新的资源时,都必须添加一个Adapter(提交代码重发);并且该对象将携带许多缺乏独立API对象版本控制的特定于联邦的注释。比如Deployment在Kubernetes中是GA的,但只在Federationv1中,BetaFederationv2有了v1版本的经验和教训后,社区提出了一种新的集群联邦架构:Federationv2;Federation项目的演进也可以参考KubernetesFederationEvolution一文。v2版本使用CRD实现整体功能。通过定义多种自定义资源(CR),省略了v1中的APIServer;v2版本包含两个组件:admission-webhook提供访问控制controller-manager处理自定义资源和协调不同集群之间的状态v2版本中创建联邦资源的一般流程如下:CreateaFederatedResourceintoAPIHost集群的Server,然后controller-manager会介入将相应的资源分发到不同的集群,分发规则等都写在这个FederatedResource对象中。从逻辑上讲,Federationv2分为配置(configuration)和传播(distribution)两部分;配置主要包括两个配置:ClusterConfiguration和TypeConfiguration。ClusterConfiguration用于保存联邦管理的集群的API认证信息。您可以通过kubefedctljoin/unjoin加入/删除集群。加入成功后,会创建一个KubeFedClusterCR,用于存放集群的相关信息,如APIEndpoint、CABundle、Token等,后续的controller-manager会使用这些信息来访问不同的Kubernetes集群。apiVersion:core.kubefed.io/v1beta1kind:KubeFedClustermetadata:creationTimestamp:"2019-10-24T08:05:38Z"generation:1name:cluster1namespace:kube-federation-systemresourceVersion:"647452"selfLink:/apis/core.kubefed.io/v1beta1/namespaces/kube-federation-system/kubefedclusters/cluster1uid:4c5eb57f-5ed4-4cec-89f3-cfc062492ae0spec:apiEndpoint:https://172.16.200.1:6443caBundle:LS....Qo=secretRef:名称:cluster1-shb2xstatus:条件:-lastProbeTime:“2019-10-28T06:25:58Z”lastTransitionTime:“2019-10-28T05:13:47Z”消息:/healthz响应正常:ClusterReady状态:“True”"type:Readyregion:""TypeConfiguration定义了哪些KubernetesAPI资源将被用于联邦管理;例如,当你想通过联邦机制在不同的集群上建立ConfigMap资源时,你必须首先在Host集群中,通过CRD创建一个新的资源FederatedConfigMap,然后创建一个名为configmaps的类型配置(FederatedTypeConfig)资源,然后描述ConfigMap将由FederatedConfigMap管理,以便Kubefedcontroller-manager可以知道如何构建Federated资源,示例如下:apiVersion:core.kubefed.k8s.io/v1beta1kind:FederatedTypeConfigmapsnamespace:kube-federation-systemspec:federatedType:group:types.kubefed.k8s.iokind:FederatedConfigMappluralName:federatedconfigmapsscope:Namespacedversion:v1beta1propagation:EnabledtargetType:kind:ConfigMappluralName:configmapsscope:Namespacedversion:v1FederatedResourceCRD还有一个关键的CRD:FederatedResource,如果要添加资源进行联邦托管,需要新建一个FederatedXXCRD描述相应资源的结构和分布策略(需要分布到哪些集群);FederatedResourceCRD主要包括三个部分:Templates用于描述被联邦化的资源;Placement用于描述将要分发的资源部署的集群,如果没有配置,则不会分发到任何集群。Overrides允许覆盖某些集群的某些资源。例子如下:apiVersion:types.kubefed.k8s.io/v1beta1kind:FederatedDeploymentmetadata:name:test-deploymentnamespace:test-namespacespec:template:#定义Deployment的所有内容,可以理解为Deployment之间的关系和豆荚metadata:labels:app:nginxspec:...placement:clusters:-name:cluster2-name:cluster1overrides:-clusterName:cluster2clusterOverrides:-path:spec.replicasvalue:5这些FederatedXXCRD可以通过kubefedctl来创建,也可以生成/编写对应的CRD,自己创建。结合上面介绍的ClusterConfiguration、TypeConfiguration和FederatedResourceCRD,v2版本的整体架构和相关概念更加清晰:SchedulingKubefed目前只能做一些简单的集群间调度,即手动指定。对于手动指定调度方式主要分为两部分,一是直接在资源中指定目的集群,二是通过ReplicaSchedulingPreference进行比例分配。直接在资源中指定可以通过clusters指定一个集群列表,也可以通过clusterSelector根据集群标签选择一个集群,但是有两点需要注意:如果clusters字段被指定了,clusterSelector会被忽略。选择的集群是平等的,资源将在每个选择的集群中部署一个不可区分的副本。spec:placement:clusters:-name:cluster2-name:cluster1clusterSelector:matchLabels:foo:bar如果需要在多个集群之间进行差异化调度,需要引入ReplicaSchedulingPreference进行比例调度:apiVersion:scheduling.kubefed.io/v1alpha1kind:ReplicaSchedulingPreferencemetadata:name:test-deploymentnamespace:test-nsspec:targetKind:FederatedDeploymenttotalReplicas:9clusters:A:minReplicas:4maxReplicas:6weight:1B:minReplicas:4maxReplicas:8weight:2totalReplicas定义副本总数,集群描述不同集群的最大/最小副本和权重。目前ReplicaSchedulingPreference只支持两种资源,deployments和replicasets。KarmadaKarmada是华为开源的多云容器编排项目。这个项目是KubernetesFederationv1和v2的延续。这两个版本继承了一些基本概念。Karmada主要有三个组件:KarmadaAPIServer:本质上是一个普通的K8sAPIServer,绑定到一个单独的etcd上,用来存储联邦要管理的资源KarmadaControllerManager:多个控制器的集合,监听KarmadaAPIServerKarmadaScheduler:提供先进的多集群调度策略。与Federationv1类似,我们将要写入的资源发送到Karmada自己的APIServer。以前,controller-manager设置资源被分发到每个集群;但是这个APIServer是K8s原生的,所以支持任何资源,在Federationv1之前的版本不会有问题,而且federated托管资源的分发策略也是由一个单独的CRD来控制的。在v2中也不需要配置FederatedResourceCRD和TypeConfigure。Karmada的一些基本概念:ResourceTemplate:Karmada使用K8s原生API定义作为资源模板,方便快速对接K8s生态工具链PropagaionPolicy:Karmada提供独立的策略API,用于配置资源分发策略OverridePolicy:Karmada提供一个独立的差异化API来配置集群相关的差异化配置,比如配置不同的集群使用不同的镜像ClusterCluster资源记录类似于Federationv2,即管理访问集群的一些必要信息:APIEndpoint,CABundle和access令牌。spec:apiEndpoint:https://172.31.165.66:55428secretRef:name:member1namespace:karmada-clustersyncMode:Push但是一个不同的是Karmada的Cluster资源有两种同步模式:Push和Pull;Push是最常见和常见的方式,宿主机集群的Karmada组件会负责同步和更新此类集群的状态;Pull模式成员集群上会运行一个Karmada-agent组件,它将负责收集自身状态并更新宿主机集群对应的Cluster资源状态。在Karmada中向成员集群分发资源的PropagaionPolicy需要配置这个单独的PropagationPolicyCR;以下面的nginx应用为例,首先是ResourceTemplate,也就是普通的K8sDeployment:apiVersion:apps/v1kind:Deploymentmetadata:name:nginxlabels:app:nginxspec:replicas:2selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:-image:nginxname:在nginx之后配置一个PropagationPolicy来控制这个nginx部署资源的分发策略,在下面的例子中,nginxapplication会按照1:1的权重分配到member1和member2集群:apiVersion:policy.karmada.io/v1alpha1kind:PropagationPolicymetadata:name:nginx-propagationspec:resourceSelectors:-apiVersion:apps/v1kind:Deploymentname:nginx放置:clusterAffinity:clusterNames:-member1-member2replicaScheduling:replicaDivisionPreference:WeightedreplicaPreferSchedulingType:Divided统计权重:clusterNames:-member1weight:1-targetCluster:clusterNames:-member2weight:1在KarmadaAPIServer中创建这两个资源后,可以通过KarmadaAPIServer查询资源状态:$kubectlgetdeployNAMEREADYUP-TO-DATEAVAILABLEAGEnginex2/22251s但注意,这并不意味着应用程序运行在KarmadaAPIServer所在的集群上。其实这个集群上并没有workload,但是存储了这些ResourceTemplates,实际的workload运行在上面PropagationPolicy配置的member1和member2集群中,切换到member1/member2集群可以看到:$kubectlgetdeployNAMEREADYUP-TO-DATEAVAILABLEAGEnginex1/1116m26s$kubectlgetpodNAMEREADYSTATUSRESTARTSAGEnginex-6799fc88d8-7cgfz1/1Running06m29s分发策略除了最常见的之外还支持LabelSelector、FieldSelector和ExcludeClusters上面指定了clustername,如果这些过滤项都被设置了,那么只会筛选出满足所有条件的cluster;除了集群亲和性,还支持SpreadConstraints:按region,zoneandprovider等组对集群进行动态分组,应用只能分发到对于某些类型的集群(如nativeDeployment和StatefulSet)有副本的资源,支持在分配资源到不同集群时按需更新副本数,比如在member1集群上希望有2个nginx副本申请,member2上只有一份;策略有很多,第一个是ReplicaSchedulingType,它有两个可选值:Duplicated:每个候选成员cluster的副本数相同,从原始资源复制而来,不设置ReplicaSchedulingStrategy的效果是一样的。Divided:根据有效候选成员集群的个数将replica分成几个部分,每个cluster的replica数量由ReplicaDivisionPreference决定,这个ReplicaDivisionPreference有两个可选值:Aggregated:考虑集群的可用资源,调度这些replica尽可能在几个集群上,如果一个集群可以容纳所有的副本,那么只会调度到这个集群,对应的资源也会存在于其他集群上,但是副本数为0加权:根据以WeightPreference来划分副本数,这个WeightPreference很简单,直接指定每个cluster的权重。完整详细的结构请参考Placement的API定义。OverridePolicyOverridePolicy非常简单。通过添加OverridePolicyCR为不同集群配置差异化配置,直接看例子:apiVersion:policy.karmada.io/v1alpha1kind:OverridePolicymetadata:name:example-overridenamespace:defaultspec:resourceSelectors:-apiVersion:apps/v1kind:Deployment名称:nginxtargetCluster:clusterNames:-member1labelSelector:matchLabels:failuredomain.kubernetes.io/region:dc1overriders:plaintext:-path:/spec/template/spec/containers/0/imageoperator:replacevalue:'dc-1.registry.io/nginx:1.17.0-alpine'-路径:/metadata/annotations运算符:添加值:foo:bar参考链接https://blog.ihypo.net/15716465002689.htmlhttps://blog.ihypo。net/15718231244282.htmlhttps://jimmysong.io/kubernetes-handbook/practice/federation.htmlhttps://support.huaweicloud.com/productdesc-mcp/mcp_productdesc_0001.html