Kubernetes 集群联邦(KubeFed / Federation v2)实战指南:从多集群动机到跨集群编排与服务发现
2026/9/24 19:06:10 网站建设 项目流程
  • 教程
  • 云原生
  • 容器编排

【免费下载链接】kubernetes-handbook

Kubernetes 架构与生态:从云原生到 AI 原生基础设施的构建指南

项目地址:https://gitcode.com/gh_mirrors/ku/kubernetes-handbook
点击查看免费下载

本文以 practice/federation.md 为核心骨架,结合本仓库 concepts/multicluster.md 与images/目录下的架构图,系统讲解 Kubernetes 集群联邦(Cluster Federation)的演进脉络、KubeFed(Federation v2)的核心 API 组与 CRD 机制、跨集群服务发现与 DNS 解析流程,以及 ReplicaSchedulingPreference 副本编排策略。读完本文,你将理解"为什么需要多集群、如何确定集群数量、KubeFed 如何通过 Template/Placement/Override 三大构件联邦任意资源",并能直接套用文中的 YAML 配置示例搭建自己的联邦服务与跨集群 DNS。

为什么要使用集群联邦

Kubernetes 从 1.8 版本起就声称单集群最多可支持 5000 个节点和 15 万个 Pod,但很少有公司会部署如此庞大的单集群。在实际场景中,我们常因低延迟、故障隔离、可伸缩性或混合云等原因部署多个集群,又希望将它们统一管理,这时就需要集群联邦(Federation)。

Federation 使管理多个集群变得简单,它通过两个主要构建模块实现:

  • 跨集群同步资源:Federation 提供在多个集群中保持资源同步的能力。例如,可以保证同一个 Deployment 在多个集群中存在。
  • 跨集群服务发现:Federation 提供自动配置 DNS 服务以及在所有集群后端上进行负载均衡的能力。例如,可以提供一个全局 VIP 或 DNS 记录,通过它可以访问多个集群后端。

Federation 还可以提供一些其它用例:

  • 高可用:通过在集群间分布负载并自动配置 DNS 服务和负载均衡,federation 最大限度地减少集群故障的影响。
  • 避免厂商锁定:通过更简单的跨集群应用迁移方式,federation 可以防止集群厂商锁定。

需要明确的是:Federation 对于单个集群没有用处。基于下面这些原因,你可能需要多个集群:

  • 低延迟:通过在多个区域部署集群,可以最大限度减少区域近端用户的延迟。
  • 故障隔离:拥有多个小集群可能比单个大集群更利于故障隔离(例如在云服务提供商的不同可用区中部署多个集群)。
  • 可伸缩性:单个集群有可伸缩性限制(对大多数用户这不是典型场景,更多细节可参考 Kubernetes 社区的 SIG Scalability goals 文档)。
  • 混合云:你可以在不同的云服务提供商或本地数据中心中拥有多个集群。

本仓库 concepts/multicluster.md 对多集群管理做了同样的归纳:多集群是在多个 Kubernetes 集群上或跨集群部署应用的策略,目的是提高可用性、隔离性和可扩展性,同时有助于遵守不同地域或认证的法规要求,并可提升软件交付的速度与安全性(例如让单个开发团队将应用部署到隔离集群中,并有选择地暴露哪些服务可用于测试和发布)。

警告

虽然 federation 有很多吸引人的使用案例,但也有一些注意事项:

  • 增加网络带宽和成本:federation 控制平面会监控所有集群以确保当前状态符合预期。如果集群运行在云服务提供商的不同区域或不同的云服务提供商上,这将导致明显的网络成本增加。
  • 减少跨集群隔离:federation 控制平面中的 bug 可能影响所有集群。通过在 federation 中实现最少的逻辑可以缓解这种情况——只要有可能,它就将尽力把工作委托给 Kubernetes 集群中的控制平面。这种设计和实现在安全性及避免多集群停止运行上也有考量。
  • 成熟度:federation 项目相对较新,并非所有资源都可用,许多仍处于 alpha 状态。

混合云能力

Kubernetes 集群 federation 可以包含运行在不同云服务提供商(例如 Google Cloud、AWS)及本地(例如在 OpenStack 上)的集群。你只需要按需在合适的云服务提供商或地点创建集群,然后向 Federation API Server 注册每个集群的 API endpoint 和凭据即可。此后,你的 API 资源就可以跨越不同的集群和云服务提供商。

单个集群范围与集群数量规划

在诸如 Google Compute Engine 或 Amazon Web Services 等 IaaS 服务提供商中,虚拟机存在于区域(Zone)或可用区(Availability Zone)上。官方建议 Kubernetes 集群中的所有虚拟机应位于相同的可用区,因为:

  • 与拥有单个全局 Kubernetes 集群相比,单点故障更少;
  • 与跨可用区集群相比,推测单区域集群的可用性属性更容易;
  • Kubernetes 开发者在设计系统时(例如对延迟、带宽或相关故障进行假设),会假设所有机器位于一个单一数据中心,或以其它方式紧密连接。

在每个可用区同时拥有多个集群也是可以的,但总体上"少一点更好"。选择较少集群的理由是:

  • 某些情况下,在一个集群中拥有更多节点可以改进 Pod 的装箱打包(减少资源碎片);
  • 减少运维开销(尽管随着运维工具和流程的成熟,这一优势已逐渐减少);
  • 减少每个集群固定资源成本的开销,例如 apiserver 虚拟机(但对于大中型集群的整体集群成本来说,占比很小)。

拥有多个集群的原因则包括:

  • 严格的安全策略要求将一类工作与另一类工作隔离(可参见分区集群 Partitioning Clusters 的思路);
  • 对新的 Kubernetes 发行版或其它集群软件进行灰度测试。

选择正确的集群数量

Kubernetes 集群数量的选择可能是一个相对静态的决策,只是偶尔需要重新设定;相比之下,集群的节点数量和 service 的 pod 数量会依据负载情况和增长经常变化。

要选择集群数量,可遵循以下三步:

  1. 确定区域数量R:首先确定使用哪些区域,以便为所有终端用户提供足够低的延迟来运行 Kubernetes 服务。如果使用内容分发网络(CDN),则 CDN 托管内容的时延要求不需要考虑。法律问题也可能影响这一选择。例如,拥有全球客户群的公司可能会决定在美国、欧盟、亚太和南亚地区拥有集群。
  2. 确定可容忍的不可用集群数U:决定在整体仍然可用的前提下,可以同时有多少集群不可用。如果你不能确定,那么 1 是一个不错的选择。
  3. 计算集群数量
    • 如果在集群故障时允许负载均衡将流量引导到任何区域,则至少需要有比RU + 1更大的集群数量;
    • 如果不行(例如希望在集群故障时对所有用户确保低延迟),则需要数量为R * (U + 1)的集群(R个区域,每个区域中有U + 1个集群)。

无论如何,请尝试将每个集群放在不同的区域中。最后,如果你的任何集群需要比 Kubernetes 集群最大建议节点数更多的节点,那么你可能需要更多集群——Kubernetes v1.3 支持最多 1000 个节点的集群,v1.8 支持最多 5000 个节点的集群。

Kubernetes 集群联邦的演进:从 Federation v1 到 v2

Kubernetes 集群联邦的演进由 SIG Multicluster 推动,Federation 是 Kubernetes 的一个子项目。该项目最初选择重用 Kubernetes API,以消除现有 Kubernetes 用户的任何附加使用复杂性,但这种方式最终被证明行不通,原因包括:

  • 在集群层面重新实施 Kubernetes API 的困难,因为 Federation 的特定扩展存储在注释(annotation)中;
  • 由于 Kubernetes API 的 1:1 仿真,Federation 类型、放置(placement)和调节(reconciliation)的灵活性有限;
  • 没有固定的 GA 路径,API 成熟度普遍混乱——例如 Deployment 在 Kubernetes 中是 GA,但在 Federation v1 中甚至不是 Beta。

随着 Federation 特定的 API 架构和社区的努力,这些想法进一步发展,演进出Federation v2。请注意,Federation V1 版本已经归档,不再维护和更新,官方也不再推荐继续使用。要了解 Federation v2 的更多资料,可关注 kubefed 项目(Kubernetes SIGs 下的 KubeFed 仓库)。

将任意资源联合起来

联邦的主要目标之一是能够定义 API 和 API 组,其中包含联邦任何给定 Kubernetes 资源所需的基本原则。这一点至关重要,因为 CRD(CustomResourceDefinition)已经成为扩展 Kubernetes API 的主流方式。

Multicluster SIG 得出了 Federation API 和 API 组的共同定义,即"一种将规范的Kubernetes API 资源分配到不同集群的机制"。最简单的分布形式可以想象为:这种"规范的 Kubernetes API 资源"在联邦集群中的简单传播。除了这种简单传播之外,有心的读者自然可以看出更复杂的机制。

在定义 Federation API 构建模块的历程中,最早期的目标演化为"能够创建一个简单的联邦,也就是任何 Kubernetes 资源或 CRD 的简单传播,几乎不需要编写代码"。随后,核心 API 组进一步定义了构件,即每个给定的 Kubernetes 资源对应一个Template资源、一个Placement资源和一个Override资源,一个TypeConfig用于指定给定资源的同步或不同步,以及执行同步的相关控制器。

更进一步的架构还支持分层行为:更高级别的 Federation API 消耗这些核心构件,而用户能够消耗整个或部分 API 和相关控制器。最后,这种架构还允许用户编写额外的控制器,或用自己的控制器替换现有的参考控制器(reference controller),以执行所需的行为。

"轻松地联合任意 Kubernetes 资源"加上解耦的 API(分为构件 API、更高层次的 API 和可能的用户预期类型),使得不同的用户可以消费部分 API 并编写控制器组成特定解决方案——这为 Federation v2 提供了令人信服的案例。

联邦服务与跨集群服务发现

Kubernetes 服务在构建微服务架构时非常有用。人们明显希望跨越集群、可用区、区域和云的边界来部署服务。跨集群服务提供了地理分布,实现混合云和多云场景,并提高了超越单一集群部署的高可用性水平。希望其服务跨越一个或多个(可能是远程)集群的客户,需要在集群内外以一致的方式提供服务。

Federated Service 的核心包含四部分:一个 Template(Kubernetes 服务的定义)、一个 Placement(部署到哪个集群)、一个 Override(在特定集群中的可选变化)和一个 ServiceDNSRecord(指定如何发现它的细节)。

注意:联邦服务必须是LoadBalancer 类型,以便它可以跨集群发现。

Pod 如何发现联邦服务

默认情况下,Kubernetes 集群预先配置了集群本地 DNS 服务器,以及智能构建的 DNS 搜索路径,它们共同确保了由 pod 内部运行的软件发出的myservicemyservice.mynamespacesome-other-service.other-namespace等 DNS 查询会自动扩展并正确解析到本地集群中运行的服务的相应 IP。

随着联邦服务和跨集群服务发现的引入,这个概念被扩展到全局——覆盖你的集群联邦中所有集群中运行的 Kubernetes 服务。为了利用这个扩展的范围,需要使用一个稍微不同的 DNS 名称(例如myservice.mynamespace.myfederation)来解析联邦服务。使用不同的 DNS 名还可以避免现有的应用意外地穿越区域网络而产生不必要的网络费用或延迟。

让我们看一个使用名为 nginx 的服务的例子:

  1. us-central1-a可用区的集群中的一个 pod 需要联系 nginx 服务。它现在可以使用服务的联邦 DNS 名nginx.mynamespace.myfederation,而不是传统的集群本地 DNS 名(nginx.mynamespace自动扩展为nginx.mynamespace.svc.cluster.local)。该名字会被自动扩展并解析到离 nginx 服务最近的健康 shard。如果本地集群中存在健康 shard,那么该服务的集群本地 IP 地址将被返回(通过集群本地 DNS),这完全等同于非联邦服务解析。
  2. 如果服务在本地集群中不存在(或者存在但没有健康的后端 pod),DNS 查询会自动扩展到nginx.mynamespace.myfederation.svc.us-central1-a.example.com。在幕后,这会找到离我们的可用区最近的一个 shard 的外部 IP。这个扩展由集群本地 DNS 服务器自动执行,它返回相关的 CNAME 记录,从而触发对 DNS 记录层次结构的遍历,最终找到附近联邦服务的一个外部 IP。
  3. 也可以通过明确指定适当的 DNS 名称(而不是依赖自动 DNS 扩展),将目标锁定在 pod 本地以外的可用性区域和地区的服务 shard。例如nginx.mynamespace.myfederation.svc.europe-west1.example.com将解析到欧洲所有当前健康的服务 shard——即使发布查询的 pod 位于美国,也不管美国是否有健康的服务 shard。这对远程监控和其他类似应用很有用。

从联邦集群之外的其他客户端发现联邦服务

对于外部客户端,目前还不能实现上述自动 DNS 扩展。外部客户需要指定联邦服务的完全限定 DNS 名称(无论是区域、可用区还是全局名称)。为了方便起见,通常建议在服务中手动配置额外的静态 CNAME 记录,例如:

短名称CNAME
eu.nginx.acme.comnginx.mynamespace.myfederation.svc.europe-west1.example.com
us.nginx.acme.comnginx.mynamespace.myfederation.svc.us-central1.example.com
nginx.acme.comnginx.mynamespace.myfederation.svc.example.com

这样一来,客户就可以始终使用左侧的短名称,并自动路由到离他们位置最近的健康 shard。所有所需的故障转移都由 Kubernetes 集群联邦自动处理。

架构概览:KubeFed(Federation v2)

Kubernetes Cluster Federation 又名KubeFed 或 Federation v2。v2 架构在 Federation v1 基础之上,简化了扩展 Federated API 的过程,并加强了跨集群服务发现与编排的功能。KubeFed 在设计之初有两个最重要的核心理念:Modularization(模块化)Customizable(定制化),这两个理念希望 KubeFed 能够跟随 Kubernetes 生态发展,并持续保持相容性与扩展性。

由于 Federation 试图解决一系列复杂的问题,因此需要将这些问题的不同部分分解开来。下图展示了集群联邦的整体架构:

上图展示的集群联邦过程包括四个步骤:

  • 配置需要联邦的集群;
  • 配置需要在集群中传播的 API 资源;
  • 配置 API 资源如何分配到不同的集群;
  • 对集群中 DNS 记录注册。

相较于 v1,v2 在组件上最大的改变是将 API Server 移除,并通过 CRD 机制来完成 Federated Resources 的扩充。KubeFed Controller 管理这些 CRD,并实现同步资源、跨集群编排等功能。

目前 KubeFed 通过 CRD 方式新增了四种 API 群组来实现联邦机制的核心功能:

API Group用途
core.kubefed.k8s.io集群组态、联邦资源组态、KubeFed Controller 设定档等。
types.kubefed.k8s.io被联邦的 Kubernetes API 资源。
scheduling.kubefed.k8s.io副本编排策略。
multiclusterdns.kubefed.k8s.io跨集群服务发现设定。

在这些核心功能中,我们必须先了解一些 KubeFed 提出的基础概念,才能更清楚 KubeFed 是如何运作的。

Cluster Configuration(集群配置)

Cluster Configuration 用来定义哪些 Kubernetes 集群要被联邦。可通过kubefedctl join/unjoin来加入/删除集群。当成功加入时,会建立一个KubeFedCluster组件来储存集群相关信息,如 API Endpoint、CA Bundle 等。这些信息会被 KubeFed Controller 用于存取不同 Kubernetes 集群,以确保能够建立 Kubernetes API 资源,其工作方式如下图所示:

在 Federation 中,会区分Host 与 Member两种类型集群:

  • Host:用于提供 KubeFed API 与控制平面的集群。
  • Member:通过 KubeFed API 注册的集群,并提供相关身份凭证来让 KubeFed Controller 能够存取集群。Host 集群也可以作为 Member 被加入

Type Configuration(类型配置)

Type Configuration 定义了哪些 Kubernetes API 资源要被用于联邦管理。比如说想将 ConfigMap 资源通过联邦机制建立在不同集群上时,就必须先在 Federation Host 集群中,通过 CRD 建立新资源FederatedConfigMap,接着再建立名称为configmaps的 Type Configuration(FederatedTypeConfig)资源,描述 ConfigMap 要被 FederatedConfigMap 所管理。这样 KubeFed Controllers 才能知道如何建立 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

若想新增 CRD 的 Federated API,可通过kubefedctl enable <res>指令来建立,示例如下:

$ kubefedctl enable etcdclusters $ kubectl api-resources | grep etcd etcdclusters etcd etcd.database.coreos.com true EtcdCluster federatedetcdclusters fetcd types.kubefed.k8s.io true FederatedEtcdCluster $ kubectl -n kube-federation-system get federatedtypeconfigs | grep etcd etcdclusters.etcd.database.coreos.com 3m16s

可以看到,kubefedctl enable一次完成了两件事:为原生 CRD(如 etcdclusters)生成对应的 Federated 类型(federatedetcdclusters),并在kube-federation-system命名空间生成对应的 FederatedTypeConfig。

一个 Federated 资源一般都会具备三个主要功能,这些信息能够在 spec 中由使用者自行定义,如下范例:

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
  • Placement:定义 Federated 资源要分散到哪些集群上,若没有该字段,则不会分散到任何集群中。如 FederatedDeployment 的spec.placement定义了两个集群时,这些集群将被同步建立相同的 Deployment。另外也支持用spec.placement.clusterSelector的方式选择要放置的集群。
  • Override:定义修改指定集群的 Federated 资源中spec.template的内容。例如将 FederatedDeployment 部署到不同公有云上的集群时,就能通过spec.overrides来调整 Volume 或副本数。

注意:目前Override 不支持 List(Array)。比如说无法修改spec.template.spec.containers[0].image

Scheduling(副本编排)

KubeFed 提供了一种自动化机制来将工作负载实例分散到不同的集群中,这能够基于总副本数与集群的定义策略,将 Deployment 或 ReplicaSet 资源进行编排。编排策略是通过建立ReplicaSchedulingPreference(RSP)文件,再由 KubeFed RSP Controller 监听与撷取 RSP 内容,将工作负载实例建立到指定的集群上。这是基于用户给出的高级用户偏好,这些偏好包括:

  • 加权分布的语义;
  • 分布副本的限制(最小和最大);
  • 允许动态重新分配副本的语义——以防某些副本 Pod 仍然没有被调度到某些集群上(例如由于该集群资源不足)。

以下为一个 RSP 范例。假设有三个集群被联邦,名称分别为ap-northeastus-eastus-west

apiVersion: scheduling.kubefed.k8s.io/v1alpha1 kind: ReplicaSchedulingPreference metadata: name: test-deployment namespace: test-ns spec: targetKind: FederatedDeployment totalReplicas: 15 clusters: "*": weight: 2 maxReplicas: 12 ap-northeast: minReplicas: 1 maxReplicas: 3 weight: 1

该配置示意如下:

当该范例建立后,RSP Controller 会收到资源,并匹配对应 namespace/name 的 FederatedDeployment 与 FederatedReplicaSet 是否存在;若存在,会根据设定的策略计算出每个集群预期的副本数,之后覆写 Federated 资源中的spec.overrides内容以修改每个集群的副本数,最后再由 KubeFed Sync Controller 同步至每个集群的 Deployment。以上面为例,结果会是:ap-northeast 集群拥有 3 个 Pod,us-east 与 us-west 分别拥有 6 个 Pod(15 个副本按权重 2:2:1 分配,同时受 maxReplicas 12/3 约束,ap-northeast 因 maxReplicas: 3 而封顶在 3 个)。

注意:

  • spec.clusters未定义,则预设为{"*":{Weight: 1}}
  • 若有定义spec.replicas的 overrides,副本数以 RSP 为优先考量;
  • 分配的计算机制可以参考 KubeFed 源码中的kubefed/pkg/controller/util/planner/planner.go(Planner 实现了权重分配、min/max 约束与动态再平衡算法)。

Multi-cluster DNS(多集群 DNS)

KubeFed 提供了一组 API 资源以及 Controllers,来实现跨集群 Service/Ingress 的 DNS records 自动产生机制,并结合ExternalDNS来同步更新至 DNS 服务供应商。以下为简单例子:

apiVersion: multiclusterdns.kubefed.k8s.io/v1alpha1 kind: Domain metadata: name: test namespace: kube-federation-system domain: k8s.example.com --- apiVersion: multiclusterdns.kubefed.k8s.io/v1alpha1 kind: ServiceDNSRecord metadata: name: nginx namespace: development spec: domainRef: test recordTTL: 300

假设已建立一个名称为 nginx 的 FederatedDeployment,放到 development namespace 中,并且也建立了对应的 FederatedService 提供 LoadBalancer。当建立上述 Domain 与 ServiceDNSRecord 后,完整的 DNS 产生链路如下:

  1. Service DNS Controller依据 ServiceDNSRecord 文件内容,收集不同集群的 Service 信息,并将这些信息更新至 ServiceDNSRecord 的状态(status)中;
  2. DNS Endpoint Controller依据该 ServiceDNSRecord 的状态内容,建立一个 DNSEndpoint 文件,并产生 DNS records 资源;
  3. 最后由ExternalDNS同步更新 DNS records 至 DNS 供应商。

下图是 Service DNS 建立的架构:

若是 Ingress 的话,会由IngressDNSRecord文件取代,并由Ingress DNS Controller收集信息。

总结:KubeFed 的核心设计要点

回顾整篇文章,KubeFed(Federation v2)的核心设计可以归纳为以下几点:

  1. 模块化与定制化:API 被拆分为核心构件(Template / Placement / Override / TypeConfig)、更高级别的联邦 API 与用户自定义类型,用户既可以消费部分 API,也可以编写自己的控制器替换参考控制器。
  2. CRD 优先:v2 移除了独立的 Federation API Server,全部能力通过四组 CRD API(core / types / scheduling / multiclusterdns)承载,与 Kubernetes 生态的扩展方式保持一致。
  3. 三层同步链路:用户定义 Federated 资源 → KubeFed Controllers(Sync / RSP / DNS)计算与编排 → 同步到各 Member 集群的 Kubernetes 原生资源,同时通过 KubeFedCluster 保存的 Endpoint 与 CA Bundle 与各集群交互。
  4. 跨集群服务发现:通过myfederation域的 DNS 名称、自动 DNS 扩展与层次化 CNAME 遍历,让 Pod 与外部客户端都能就近访问健康 shard,实现地理分布、混合云与高可用。

如果你希望进一步了解多集群管理的整体背景(包括kubectl config的多集群访问配置),可参阅本仓库的 concepts/multicluster.md;联邦架构图与运行示意图均可在 images/ 目录中找到(如 federation-concepts.png、sync-controller.png、kubefed-rsp.png、kubefed-service-dns.png)。

  • 教程
  • 云原生
  • 容器编排

【免费下载链接】kubernetes-handbook

Kubernetes 架构与生态:从云原生到 AI 原生基础设施的构建指南

项目地址:https://gitcode.com/gh_mirrors/ku/kubernetes-handbook
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询