Kubernetes 已然成为云原生的基石,被广泛用于生产环境中,作为基础设施管理资源和应用。伴随 公有云、私有云、混合云、边缘计算等使用使用场景增多,人们越来越倾向使用多个 Kubernetes 集群来满足不同业务场景的需求。
多集群管理中,需要面对不同的场景构建和运维集群,适配多集群场景管理应用,如下图:

多集群管理中,集群实现、集群运行时、集群能力、应用管理、应用调度、应用访问等维度带来了很大的挑战,也为业务带来了新的可能性。
下述简单分析社区中多集群管理项目,理解不同维度的解决方案,为设计匹配自身技术和业务阶段的方案提供参考。
集群实现
Cluster API 是 Kubernetes 社区的官方项目 [1] ,提供声明式的 API 和工具来简化多 Kubernetes 集群的构建、升级、管理等。
不同的公有云厂商、私有云场景,计算、网络、存储等资源会有差异性,Cluster API 提供统一的操作界面,屏蔽了不同场景的资源和操作差异,提供了一致的集群实现体验。
快速的使用体验可参见 [2]。
Cluster API 的概念图如下 [3]:

Cluster API 为了便于管理集群实现,将集群类型区分为如下两种:
Management Cluster
Workload Cluster
Management Cluster 作为中心管控集群,用来管理 Workload Cluster 的生命周期。
Workload Cluster 用来承载 workloads。
这种抽象提供了多集群管理的通用抽象,将管控和业务解耦开,中心式管理业务,降低管控成本,同时业务在逻辑或物理层面实现隔离,保障业务对资源和稳定性等的需求。
Cluster API 提供了如下的 CRD,描述多集群实现的管理:
Machine
Machine 是对节点资源的描述,如 VM 等
需要注意 Cluster API 对 Machine 的维护是采用 Replace 的方案,即变更 Machine Spec 后,Cluster API 会删除旧的节点资源,新建节点资源,而非在原有节点资源上原地升级
可将 Machine 类比为 Kubernetes 中的 Pod
MachineSet
MachineSet 是对一组节点资源的描述,管理 Machine
通常情况下用户不直接操作 MachineSet 资源,而是使用 MachineDeployment 进行节点池的管理
可将 MachineSet 类比为 Kubernetes 中的 ReplicaSet
MachineDeployment
MachineDeployment 是对 MachineSet 和 Machine 的管理,如创建、升级等
可将 MachineDeployment 类比为 Kubernetes 中的 Deployment
MachineHealthCheck
MachineHealthCheck 定义了 Node 被认为不健康的条件
节点不健康时,MachineHealthCheck 会触发节点的修复操作,生成新的节点来替换旧节点
BootstrapData
BootstrapData 包含了节点相关的信息,用来将 Machine 描述转变为相应的资源节点
目前 Cluster API 支持多种集群实现,如阿里云、腾讯云、AWS 等,详细的列表可参见 [4]。
集群运行时 & 应用生命周期管理
社区中的多集群管理项目,通常是同时解决 集群运行时 和 应用生命周期管理,如华为云的 Karmada 、RedHat/蚂蚁/阿里云共同发起的 Open Cluster Management (下述简写为 OCM)、腾讯云的 Clusternet。
下述将通过图的方式简化对上述 3 个项目的理解。
Karmada
Karmada 是发展相对最早的多集群管理项目,目前已经捐献给 CNCF,项目地址参见 [5]。
来自 Karmada 的介绍:
Karmada (Kubernetes Armada) is a Kubernetes management system that enables you to run your cloud-native applications across multiple Kubernetes clusters and clouds, with no changes to your applications.
Karmada aims to provide turnkey automation for multi-cluster application management in multi-cloud and hybrid cloud scenarios, with key features such as centralized multi-cloud management, high availability, failure recovery, and traffic scheduling.
Karmada 架构:

Karmada 核心概念:

Karmada 也采用了类似 Cluster API 的 Management Cluster 和 Workload Cluster 的概念,且将 Management Cluster 作为统一的访问界面,将 Workload Cluster 对用户透明化。
这种模式下,Workload Cluster 是作为 隔离的资源池 来对待,Management Cluster 统一调度应用,透明化应用的部署,允许将一个应用实例分布在不同的集群中,且在 Workload Cluster 中仍以应用的方式进行管理,而非实例。
OCM
OCM 是 RedHat、蚂蚁、阿里云联合推出的多集群管理项目,项目参见 [6]。
OCM 对多集群管理的抽象设计的很好,抽象出了如下的概念,便于进行多集群管理的设计和实现 [7]:
Cluster Lifecycle: Cluster registration and management
cluster registration
manifests delivery
cluster scheduling
addon management
Application Lifecycle: Delivery, upgrade, and configuration of applications on Kubernetes clusters
GRC: Governance, Risk and Compliance across Kubernetes clusters
Use prebuilt security and configuration controllers toto enforce policies on Kubernetes configuration across your clusters
OCM 一张图理解:

OCM 也是将集群类型区分为 Management Cluster 和 Workload Cluster,分别用 Hub Cluster 和 Managed Cluster 概念描述。
OCM 定义了如下 CRD 来描述多集群管理问题:
ManagedCluster
用于 Workload Cluster 向 Management Cluster 进行集群注册
Placement
用于调度时选择适合的集群或集群集合
ManifestWork
在 Management Cluster 中,描述哪些资源需要部署在 Workload Cluster 中
ManagedClusterSets
描述集群集合,用来描述用户等可访问的集群
ManagedClusterAddon
描述管控组件
OCM 在 集群注册 方面,提供了双向控制,保障集群注册的可控性:
Workload Cluster 向 Management Cluster 申请注册
Management Cluster 决定是否接受 Workload Cluster 的注册
OCM 中,应用部署的工作流如下,示例参见 [8]:
Management Cluster 中
选择应用可部署的集群或集群集合
每个集群都有一个 Kubernetes namespace 对应
在选择的集群或集群集合的 namespace 中,通过 ManifestWork 描述资源和应用
Workload Cluster 中
Klusterlet 监听到 Managed Cluster 对应 namespace 中 ManifestWork 后,在所在集群部署资源和应用
Karmada 隐式控制 同一个应用部署在哪些集群,而在 OCM 中是需要显式指定。
Clusternet
Clusternet 是腾讯云推出的多集群管理项目,项目地址参见 [9]。
通过如下两张图简单理解其设计:


在 集群注册 方面,Clusternet 类似 OCM 实现了双向控制。
应用调度层面,用户可以指定选择哪些集群,然后 Clusternet 会根据配置将应用拆分到集群中部署。
通用问题
跨集群网络访问
上述 3 种多集群管理中,均会涉及到 同一个应用部署在多个集群 中的场景,此时就会涉及到应用跨集群访问,包括 集群间网络访问 和 外部对集群内应用访问 。
东西流量
社区中 KEP-1645 (Multi-Cluster Services API: [10]) 试图将跨集群网络访问标准化,提供跨集群的 Service API。目前有一个开源项目探索实现 Multiple-Cluster Services API,参见 [11]。
在这个 KEP 中,提出了两个 CRD:
ServiceExport
决定一个集群中的 Serivce 是否允许被其他集群访问到
ServiceImport
所在集群中,表征 ServiceExport 指定的服务
对于跨集群网络访问,是否扩展 Service 到跨集群场景,社区中也有不同的观点,可能会增加不必要的复杂度。
一种方案是每个集群有个 Gateway,作为集群流量的出入口,跨集群访问时统一走对应集群的 Gateway。
对于云厂商,网络通常会采用 VPC 管理,多集群网络访问,通常也会转换为 VPC 内部访问 或 跨 VPC 网络访问 问题,或许又会产生针对特定场景的跨集群网络访问方案。
另外,社区中也有一个多集群网络管理方案,可参见 [12]。
南北流量
暂时没有找到社区中有相关的提议或实现,公有云场景中通常可以考虑借助 API Gateway 或 4 层 LB 以及 NAT+EIP 等实现。
集群命名
多集群管理中,需要 唯一识别集群 ,此时需要有规范化的命名。
社区中的 KEP-2149 (ClusterId for ClusterSet identification) 对此尝试规划化,有兴趣可以了解下:[13] 。
跨集群 Namespace 管理
Kubernetes 中,namespace 是作为资源和应用管理软隔离的方案,应用是部署在 namespace 维度。
在多集群场景中,同一个应用可能会分布在多个集群中,此时需要考虑针对 namespace 的统一管理。
社区中有个 Namespace Sameness 的提议,可参见 [14],核心观点:
For a set of related clusters governed by a single authority, all namespaces of a given name are considered to be the same namespace
A single namespace should have a consistent owner across the set of clusters
该提议将 namespace 扩展到多集群级别,同样命名的 namespace 在不同的集群中有相同的语义,简化了 资源/应用 与 namespace 之间的映射管理。
管控 Controller
当前社区中的 Controller 多是面向 单集群+单租 场景,在多集群管理中,这类 Controller 需要部署在每个需要其能力的集群中。随着集群规模的增长,相应的运维成本和资源成本也会越来越大。
一种思路是将 Controller 实现为面向 多集群+多租 场景,Controller 在 Management Cluster 中统一部署,监听多个目标 Workload Cluster 的 kube-apiserver,然后做相应的操作。实现上可参考社区 VirtualCluster [15] 项目中 syncer [16] 的实现。部分场景中需要将相关的 CRD 与 Controller 拆开,Controller 部署在 Management Cluster 中,CRD 部署在 Workload Cluster 中。
但这种方式需要考虑 爆炸半径,可根据集群的重保级别判断是否下放 Controller,通过资源换取稳定性。
小结
上述对开源的多集群管理方案及通用问题进行了简单的总结,尝试将其解决方案映射到多集群管理的问题域中,进一步理解多集群管理面对的问题,通过定义抽象整理问题域并细化问题,为设计匹配自身技术和业务阶段的方案提供参考。
重新回顾该图:

可以将多集群管理问题域抽象为:

多集群管理为应用管理带来了新的可能性,可以进一步利用不同场景的资源,满足应用的多场景服务 (中心/边缘等)、跨场景统一管理界面、稳定性保障等需求。
参考
[1]https://github.com/kubernetes-sigs/cluster-api
[2]https://cluster-api.sigs.k8s.io/user/quick-start.html
[3]https://cluster-api.sigs.k8s.io/user/concepts.html
[4]https://cluster-api.sigs.k8s.io/reference/providers.html
[5]https://github.com/karmada-io/karmada/
[6]https://open-cluster-management.io/
[7]https://github.com/open-cluster-management-io/OCM
[8]https://open-cluster-management.io/scenarios/deploy-kubernetes-resources/
[9]https://github.com/clusternet/clusternet
[10]https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api
[11]https://github.com/kubernetes-sigs/mcs-api
[12]https://github.com/submariner-io/submariner
[13]https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/2149-clusterid
[14]https://github.com/kubernetes/community/blob/master/sig-multicluster/namespace-sameness-position-statement.md
[15]https://github.com/kubernetes-sigs/cluster-api-provider-nested/tree/main/virtualcluster
[16]https://github.com/kubernetes-sigs/cluster-api-provider-nested/tree/main/virtualcluster/cmd/syncer




