本文发布于一年多以前。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 联邦演变

Kubernetes 为将应用程序部署到集群提供了很好的原语:它可以像 kubectl create -f app.yaml 一样简单。跨多个集群部署应用程序从未如此简单。应用程序工作负载应如何分配?应用程序资源应该复制到所有集群、复制到选定的集群还是分区到集群?如何管理对集群的访问?如果用户想要分发的某些资源以某种形式预先存在于某些或所有集群中,会发生什么?

在 SIG Multicluster 中,我们的旅程表明,有多种可能的模型可以解决这些问题,并且可能没有单一的最佳、适用于所有场景的解决方案。然而,Kubernetes 集群联邦(简称 KubeFed)是最大的 Kubernetes 开源子项目,并且在这个问题领域中受到了社区的最大兴趣和贡献。该项目最初重用了 Kubernetes API,以消除现有 Kubernetes 用户任何额外的使用复杂性。由于以下总结的问题,这种方法是不可行的

  • 在集群级别重新实现 Kubernetes API 的困难,因为联邦特定的扩展存储在注释中。
  • 由于对 Kubernetes API 的 1:1 模拟,在联邦类型、放置和协调方面的灵活性有限。
  • 没有确定的 GA 路径,并且对 API 成熟度普遍感到困惑;例如,Deployment 在 Kubernetes 中是 GA,但在 Federation v1 中甚至不是 Beta 版本。

这些想法随着联邦特定的 API 架构和一个社区努力而进一步发展,现在继续作为 Federation v2。

概念概述

由于联邦试图解决一系列复杂的问题,因此有必要分解这些问题的不同部分。让我们来看看涉及的不同高级领域

Kubernetes Federation v2 Concepts

Kubernetes Federation v2 概念

联合任意资源

联邦的主要目标之一是能够定义 API 和 API 组,这些 API 和 API 组包含联合任何给定 Kubernetes 资源所需的基本原则。这一点至关重要,因为 CustomResourceDefinitions 作为使用新 API 扩展 Kubernetes 的一种方式而流行。

工作组得出联邦 API 和 API 组的通用定义,即“一种将‘正常’ Kubernetes API 资源分发到不同集群的机制”。最简单的形式可以将分发想象为跨联邦集群简单传播“正常 Kubernetes API 资源”。一位深思熟虑的读者肯定可以辨别出比简单传播 Kubernetes 资源更复杂的机制。

在定义联邦 API 的构建块的过程中,一个近期的目标也演变为“能够创建简单的联邦,也称为简单传播任何 Kubernetes 资源或 CRD,几乎无需编写代码”。接下来是一个核心 API 组,它将构建块定义为每个给定 Kubernetes 资源的 Template 资源、Placement 资源和 Override 资源、用于指定给定资源的同步或不同步的 TypeConfig 以及执行同步的相关控制器。更多详细信息请参见下一节。后续章节还将讨论能够遵循分层行为,其中更高级别的联邦 API 使用这些核心构建块的行为,用户能够使用整个 API 或部分 API 以及相关控制器。最后,此体系结构还允许用户编写其他控制器或使用他们自己的控制器替换可用的引用控制器,以执行所需行为。

“轻松联合任意 Kubernetes 资源”的能力以及解耦的 API,分为构建块 API、更高级别的 API 和可能的用户意图类型,以使不同的用户可以利用部分内容并编写控制器来组合特定于它们的解决方案,这为 Federation v2 提供了令人信服的理由。

联合资源:详细信息

从根本上讲,必须使用两种类型的信息来配置联邦

  • 联邦应该处理哪些 API 类型
  • 联邦应该将哪些集群作为分发这些资源的目标。

对于联邦处理的每种 API 类型,声明状态的不同部分都存在于不同的 API 资源中

  • Template 类型保存资源的基本规范 - 例如,名为 FederatedReplicaSet 的类型保存应分发到目标集群的 ReplicaSet 的基本规范
  • Placement 类型保存资源应分发到的集群的规范 - 例如,名为 FederatedReplicaSetPlacement 的类型保存有关应将 FederatedReplicaSets 分发到哪些集群的信息
  • 可选的 Overrides 类型保存有关应如何在某些集群中更改 Template 资源的规范 - 例如,名为 FederatedReplicaSetOverrides 的类型保存有关应如何在某些集群中更改 FederatedReplicaSet 的信息。

这些类型都按名称关联 - 这意味着对于名称为 foo 的特定 Template 资源,该资源的 Placement 和 Override 信息包含在名称为 foo 且与 Template 位于同一命名空间的 Override 和 Placement 资源中。

更高级别的行为

v2 API 的体系结构允许使用核心 API 类型(TemplatePlacementOverride)以及给定资源的相关控制器提供的机制来构建更高级别的 API。在社区中,我们发现了一些用例,并为这些用例实现了更高级别的 API 和相关控制器。后续章节中描述的某些类型也为任何有兴趣解决更复杂用例的人提供了一个有用的参考,该用例基于 v2 API 已经提供的机制构建。

ReplicaSchedulingPreference

ReplicaSchedulingPreference 提供了一种自动机制,用于将基于 Deployment 或 ReplicaSet 的联合工作负载的总副本数分配到联合集群中并进行维护。这基于用户提供的高级用户首选项。这些首选项包括用于分发副本的加权分配限制(最小和最大)的语义。这些还包括允许在某些集群中某些副本 Pod 保持未调度状态时动态重新分配副本的语义,例如由于该集群中的资源不足。有关更多详细信息,请访问ReplicaSchedulingPreferences 用户指南

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

Kubernetes 服务在构建微服务架构中非常有用。显然希望跨集群、区域、区域和云边界部署服务。跨集群的服务提供地理分布,实现混合云和多云场景,并提高超出单个集群部署的高可用性级别。希望其服务跨一个或多个(可能远程的)集群的客户,需要能够从集群内部和外部以一致的方式访问这些服务。

联邦 Service 的核心包含一个 Template(Kubernetes 服务的定义)、一个 Placement(要部署到的集群)、一个 Override(特定集群中的可选变体)和一个 ServiceDNSRecord(指定有关如何发现它的详细信息)。

注意:联邦服务必须为 LoadBalancer 类型,才能在集群之间被发现。

从联邦集群内的 Pod 中发现联邦服务

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

随着联邦服务和跨集群服务发现的引入,此概念已扩展到覆盖在您的集群联邦中、全局范围内的任何其他集群中运行的 Kubernetes 服务。 为了利用这种扩展范围,您可以使用略有不同的 DNS 名称(例如 myservice.mynamespace.myfederation)来解析联邦服务。使用不同的 DNS 名称还可以避免您的现有应用程序意外地遍历跨区域或跨地区的网络,从而可能导致不必要的网络费用或延迟,而无需您显式选择此行为。

让我们考虑一个示例,使用名为 nginx 的服务。

us-central1-a 可用区中的集群中的 Pod 需要联系我们的 nginx 服务。 它现在可以使用该服务的联邦 DNS 名称 nginx.mynamespace.myfederation,而不是使用该服务的传统集群本地 DNS 名称(nginx.mynamespace,它会自动扩展为 nginx.mynamespace.svc.cluster.local)。这将被自动扩展并解析为 nginx 服务最近的健康分片,无论它在世界上的哪个位置。如果本地集群中存在健康的分片,则将返回该服务的集群本地 IP 地址(由集群本地 DNS 返回)。这与非联邦服务解析完全相同。

如果本地集群中不存在该服务(或者存在但没有健康的后端 Pod),则 DNS 查询将自动扩展为 nginx.mynamespace.myfederation.svc.us-central1-a.us-central1.example.com。在幕后,它会找到距离我的可用区最近的分片的外部 IP。此扩展由集群本地 DNS 服务器自动执行,该服务器返回关联的 CNAME 记录。这会导致遍历 DNS 记录的层次结构,并最终到达附近联邦服务的外部 IP 之一。

也可以通过显式指定相应的 DNS 名称,而不依赖于自动 DNS 扩展,来定位 Pod 本地可用区和区域以外的可用区和区域中的服务分片。例如,即使发出查找的 Pod 位于美国,并且无论在美国是否存在服务的健康分片,nginx.mynamespace.myfederation.svc.europe-west1.example.com 都会解析为欧洲所有当前健康的服务分片。这对于远程监视和其他类似应用程序非常有用。

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

对于外部客户端,目前无法实现上述的自动 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

这样,您的客户端始终可以使用左侧的短格式,并且始终会自动路由到其所在大陆上最近的健康分片。所有必需的故障转移都由 Kubernetes 集群联邦自动为您处理。

作为进一步阅读,用户可以在使用 ExternalDNS 的多集群服务 DNS 指南中找到更详细的示例。

亲自尝试

要开始使用 Federation v2,请参阅用户指南。可以使用 Helm chart 完成部署,并且在控制平面可用后,可以使用用户指南的示例来获得一些使用 Federation V2 的实践经验。

Federation v2 可以部署在集群范围命名空间范围的配置中。 集群范围的部署将需要对主机和成员集群的集群管理员权限,并且可能非常适合在未运行关键工作负载的集群上评估联邦。 命名空间范围的部署仅需要访问主机和成员集群上的单个命名空间,并且更适合在运行工作负载的集群上评估联邦。 大多数用户指南都指的是集群范围的部署,而命名空间联邦部分记录了命名空间部署的使用有何不同。同一集群可以托管多个联邦,并且在使用命名空间联邦时,集群可以是多个联邦的一部分。

下一步

正如我们在本文开头所指出的那样,多集群问题领域非常广泛。 如果没有围绕这些对话的具体的软件,很难知道如何准确处理如此广泛的问题领域。 我们在联邦工作组中的希望是,Federation v2 可以成为围绕讨论的具体的成果。 我们很乐意了解大家在这个问题领域中获得的经验,他们对 Federation v2 的感受,以及他们将来有兴趣探索哪些用例。

欢迎大家加入我们在 sig-multicluster slack 频道或在太平洋标准时间星期三 07:30 举行的 联邦工作组会议上。