​多个维度分析k8s多集群管理工具,到底哪个才真正适合你

语言: CN / TW / HK

C T O

   

 

Go Rust Python Istio containerd CoreDNS Envoy etcd Fluentd Harbor Helm Jaeger Kubernetes Open Policy Agent Prometheus Rook TiKV TUF Vitess Arg o Buildpacks CloudEvents CNI Contour Cortex CRI-O Falco Flux gRPC KubeEdge Linkerd NATS Notary OpenTracing Operator  Framework SPIFFE SPIRE     Thanos

多个维度分析k8s多集群管理工具,到底哪个才真正适合你

当部署在云上的服务达到一定水平时,所有公司都应该接受多集群。根据 VMware 2020 Kubernetes 状态报告, 33% Kubernetes 采用者正在运行 26 个或更多集群, 20% 正在运行超过 50 个集群。

https://tanzu.s3.us-east-2.amazonaws.com/campaigns/pdfs/VMware_State_Of_Kubernetes_2020_eBook.pdf

无论是使用 AWS GKE 还是其他云服务商,无论是否自己搭建 Kubernetes 平台,无论是否使用自动伸缩功能,你都会发现单个集群的容量是有限的。 Kubernetes 官方推荐,“最大”的集群应该是

  • 每个节点不超过 110 Pod

  • 不超过 5000 个节点

  • 总共不超过 150000 pod

  • 总共不超过 300000 个容器

许多人可能认为他们当前的集群性能非常好,对多集群的需求还很遥远。但是,它们很快就会走向多集群。

动机

我们采用的单个集群负担很大:它包含大约 2000 个命名空间, 3000 个 Pod,但集群中的大部分资源都是 GCP 相关的,包括 10000 多个 StorageBucket 10000 IAM 资源,以及相当数量的 Bigtable BigQuery 相关的。与此同时, 50 家运营商正在运行数十个内部或开源控制器。

在性能方面, GKE 自动缩放器目前运行良好。但我们还是开始寻求多集群策略,将我们的资源和服务迁移到多集群,以解决以下问题。

可扩展性。在部署或升级某个 Operator 时,依赖于该 Operator Pod 必须重启,造成整个集群的不稳定性,因为这些 Pod 可能会管理每个 Namespace 中的大量资源。而当 APIServer 无法响应请求时,就会发生错误。由于 Kubernetes 的故障重启机制,所有 Pod 都会在数小时内重复重启。因此,单个集群已经无法满足我们快速升级、引入新用户、部署新资源的需求。

"error": "Get "https://10.1.1.1:443/apis?timeout=32s": context deadline exceeded
"Failed to get API Group-Resources", "error": "context deadline exceeded"
  • 可用性和用户体验。作为公司范围内 CI/CD 管道的一部分,我们的服务将影响几乎所有正在部署或将要部署的服务,例如 PR 合并或主构建。单个集群的爆炸半径太大,如果服务需要紧急部署,需要付出很多努力才能绕过我们的单节点故障。

  • 隔离。集群中的资源可以根据其变化频率分为两类:稳定的和不稳定的。我们可以通过将这些稳定的资源( P99 )移动到一个相对稳定的环境中来避免它们受到其他 operator 或资源的影响。

  • 性能。随着管理的资源数量增加到 10k ,一些集群级别的 operator 会遇到各种性能问题。有必要减少他们的 pod 使用开销并改善用户体验。

  • 多环境。我们集群中运行的数十个 operator 超出了我们的管理范围,大多数 operator 维护者都有自己的发布和部署权限。一旦其中一个出现问题,整个集群将面临可用性问题。但是,由于当前的测试环境和生产之间的差距很大,因此很难预测生产中可能出现的问题。因此,我们需要一个更安全的解决方案来测试和发布这些 operator

多集群拯救一切,大大减轻现有 APIServer 的压力,加快我们新功能的升级和部署,减少对用户的影响,缩小爆炸半径,提升用户体验。

此外,“不要把鸡蛋放在一个篮子里”似乎也是云战略的趋势。在 VMware 最新的 2021 年报告中, 36% 的用户已经在推动多云战略,这也是许多公司的计划。

https://tanzu.vmware.com/content/ebooks/the-state-of-kubernetes-2021

由于与 GCP 深度绑定,我们更接近多云战略是明智的,部署多集群将是第一步。

如何设置多集群

我们的研究从 CNCF 中可以支持和满足我们需求的现有工具开始。除了上面列出的痛苦之外,我们现在应该专注于我们实际需要的东西。

  • 集群部署,可以快速部署多个集群,解决网络问题。

  • Cluster Discovery ,当用户资源分散到多个集群时,搜索当前需要运行的集群的中心服务。它还应该提供类似于一致性哈希的功能,以避免在集群随后增加时将资源重新部署到不同的集群。
  • GCP 资源和自定义 CRD 支持。对于 Google Config Connector 定义的那些 GCP 资源,以及公司内部 CRD 定义的资源,我们需要更多的支持。
https://cloud.google.com/config-connector/docs/overview

同时,我们也需要适应很多地方的多集群变化。

根据 CI/CD 中的当前请求对资源进行分组。有时,我们需要同时在多个集群上启动操作。

  • 确保每个 operator 都支持多集群。
  • 为用户提供 UX CLI 工具来发现他们的 CLI 操作资源。考虑到所有这些需求,让我们看看社区中的用户如何实现多集群,采用哪些策略,使用哪些工具。

战略

通常有两种多集群策略,以 Kubernetes 为中心和以网络为中心。

  • Kubernetes 为中心,管理多个集群,通过在多个集群上构建控制平面层来分发和调度资源管理请求,这些集群相互隔离,每个集群管理不同的资源。
  • 以网络为中心,通过网络配置实现不同集群之间的通信,实现资源复制,保持每个集群上的资源一致。

您可能会发现这两种策略类似于克服我们在数据库中遇到的瓶颈的传统方法。确切地!以 Kubernetes 为中心就像 master-master 模式,依赖于数据库中间件(控制平面)来处理和分发请求,而以 network-centric master-slave 模式,主从之间的通信最终保持数据一致.

在我们的案例中,以网络为中心的策略并不适用,但以 Kubernetes 为中心的策略可以减轻每个集群的负担。

工具

来自云提供商的那些工具,例如 GKE 的多集群支持,已经过时了。它们基本上是以网络为中心的,并伴随着两个主要问题。

  • 不那么开源,难以定制或二次开发。

  • 与云提供商本身高度耦合,不利于未来的多云或混合云战略。

现在看看我们可以选择社区中哪些流行的工具。

Kubefed

这个流行的多集群工具有两个版本, v1 kube-federation (已经放弃)和 v2 kubefed

kubefed 的整体架构可以看出,它本质上是由两个 CRDType Configuration 和, 组成的, Cluster Configuration 并通过 CRD 各自的控制器和准入 webhook 来实现这两个主要功能。

  • 跨集群分布。通过抽象、 和三个概念 Templates ,可以将资源(如)部署到不同的集群,实现多集群扩展。 PlacementOverridesDeployment
  • 调度 clusterSelector ,用和实现资源调度 ReplicaSchedulingPreference 。此外, kubefed 还支持高可用、更轻松的资源迁移、多云和混合云部署等诸多特性。

然而,它不是我们要找的那个。

  • 对于大多数开发人员来说,它是一个复杂的工具,学习曲线陡峭。

  • 不支持自定义分发策略,无法满足我们隔离不同稳定性资源的需求。例如, ReplicaSchedulingPreference 只能支持 Deployments Replicasets
  • 它不支持自定义 CRD 。我们需要额外的努力来管理来自 Config Connector .

Gitops

Gitops 已经是非常流行的 CI/CD 标准,用于将 Kubernetes 资源部署到集群,例如 FluxCD Fleet ArgoCD ,其中大部分都支持多集群。这是我们可以依靠的吗?

FluxCD 支持多集群和多租户,使用 kustomization helm 添加新集群,并且支持资源隔离。

经过评估,它也不是那个。

  • 没有动态分布。资源分配需要通过类似的方式提前注入 go template ,而不是动态分配。而我们自己的 CI/CD 工具也无法与之无缝集成。

  • 副作用。 helm 申请的开销 kustomize 太高了。这些缺点是其他 Gitops 共有的,也是不适用的。

Karmada

Karmada 来自 CNCF 沙箱,支持多集群和多云策略。

它的设计部分继承自 kubefed v1 v2 ,与 APIServer Scheduler controller-manager 构成一个控制平面,并通过两个 crd PropagationPolicy OverridePolicy 实现资源调度和分发。

Karmada 有很多优点,包括但不限于,

  • 集群管理。统一的 API 支持集群注册和生命周期管理。
  • 声明性资源调度。支持自定义调度策略,根据标签和状态动态调度资源到合适的集群。

  • Karmada 的主要优势在于原生 Kubernetes 资源处理,但它天生不支持 CRD

对于 Kubernetes 原生资源, Karmada 知道如何解析它们,但对于 CRD 定义的自定义资源(或通过聚合 apiserver 之类的扩展),由于缺乏对资源结构的了解,只能将其视为普通资源。因此,高级调度算法不能用于它们。

即需要 Resource Interpreter 开发来实现动态调度等功能。我们不选择它的最大原因。

https://github.com/karmada-io/karmada/blob/master/docs/userguide/customizing-resource-interpreter.md

我们自己的方式

意识到我们正在以一种非常“独特”的方式使用 Kubernetes ,这与社区中的大多数场景不同,我们决定定制自己的实现来完全满足我们的需求。

从当前的单集群过渡到多集群,没有太多事情要做。

  • 集群管理。我们已经使用 terraform 创建了当前集群,因此我们可以 terraform 在解决网络问题并拥有足够的 IP 后快速创建其他集群。

  • 调度。当我们决定根据命名空间将资源分配到不同的集群时,我们需要一个中央调度服务:当传入一个命名空间时,该服务可以返回相应的集群上下文,以便我们可以将资源部署到 CI/CD 服务。该服务还应支持 GRPC ,以与公司内部的分销策略相统一。

  • Golang 支持。我们有很多自研的 operator ,所以 operator 的维护者需要 Golang 包的支持。当然,这是一个不错的选择,因为他们可以通过 RPC 接口获取集群信息。

  • 自动化。使用单个集群,我们通过 CLI 或简单的脚本手动完成集群的构建、安装工具、安装和部署各种 operator 。现在有了多集群,当手动一个一个地部署集群似乎效率低下且容易出错时,我们需要升级。因此,自动化相关的工具和完整的脚本是必要的。

  • 命令行工具。我们希望为用户提供与单集群场景相同的多集群体验,他们可以登录到我们的集群来查看他们的资源。为此,我们需要实现一个 kubectl 插件来封装相关逻辑,只要用户通过命名空间, kubectl 请求就可以转发到相应的上下文中。

基本上,从单集群到多集群的架构变化如下。

正如所见,它比任何现有工具都更有效,并且更适合我们当前的情况。

结束

这是对我们遇到的问题、我们进行的讨论以及在实施多集群过程中引发的思考的回顾。我们没有使用社区中的任何工具,但我们确实通过研究它们的功能、优缺点为自己铺平了道路。

希望它也能为您提供多集群实施的全景图,并在您处于十字路口时有意义。

谢谢阅读! 多个维度分析k8s多集群管理工具,到底哪个才真正适合你

当部署在云上的服务达到一定水平时,所有公司都应该接受多集群。根据 VMware 2020 Kubernetes 状态报告, 33% Kubernetes 采用者正在运行 26 个或更多集群, 20% 正在运行超过 50 个集群。

https://tanzu.s3.us-east-2.amazonaws.com/campaigns/pdfs/VMware_State_Of_Kubernetes_2020_eBook.pdf

无论是使用 AWS GKE 还是其他云服务商,无论是否自己搭建 Kubernetes 平台,无论是否使用自动伸缩功能,你都会发现单个集群的容量是有限的。 Kubernetes 官方推荐,“最大”的集群应该是

  • 每个节点不超过 110 Pod

  • 不超过 5000 个节点

  • 总共不超过 150000 pod

  • 总共不超过 300000 个容器

许多人可能认为他们当前的集群性能非常好,对多集群的需求还很遥远。但是,它们很快就会走向多集群。

动机

我们采用的单个集群负担很大:它包含大约 2000 个命名空间, 3000 个 Pod,但集群中的大部分资源都是 GCP 相关的,包括 10000 多个 StorageBucket 10000 IAM 资源,以及相当数量的 Bigtable BigQuery 相关的。与此同时, 50 家运营商正在运行数十个内部或开源控制器。

在性能方面, GKE 自动缩放器目前运行良好。但我们还是开始寻求多集群策略,将我们的资源和服务迁移到多集群,以解决以下问题。

可扩展性。在部署或升级某个 Operator 时,依赖于该 Operator Pod 必须重启,造成整个集群的不稳定性,因为这些 Pod 可能会管理每个 Namespace 中的大量资源。而当 APIServer 无法响应请求时,就会发生错误。由于 Kubernetes 的故障重启机制,所有 Pod 都会在数小时内重复重启。因此,单个集群已经无法满足我们快速升级、引入新用户、部署新资源的需求。

"error": "Get "https://10.1.1.1:443/apis?timeout=32s": context deadline exceeded
"Failed to get API Group-Resources", "error": "context deadline exceeded"
  • 可用性和用户体验。作为公司范围内 CI/CD 管道的一部分,我们的服务将影响几乎所有正在部署或将要部署的服务,例如 PR 合并或主构建。单个集群的爆炸半径太大,如果服务需要紧急部署,需要付出很多努力才能绕过我们的单节点故障。

  • 隔离。集群中的资源可以根据其变化频率分为两类:稳定的和不稳定的。我们可以通过将这些稳定的资源( P99 )移动到一个相对稳定的环境中来避免它们受到其他 operator 或资源的影响。

  • 性能。随着管理的资源数量增加到 10k ,一些集群级别的 operator 会遇到各种性能问题。有必要减少他们的 pod 使用开销并改善用户体验。

  • 多环境。我们集群中运行的数十个 operator 超出了我们的管理范围,大多数 operator 维护者都有自己的发布和部署权限。一旦其中一个出现问题,整个集群将面临可用性问题。但是,由于当前的测试环境和生产之间的差距很大,因此很难预测生产中可能出现的问题。因此,我们需要一个更安全的解决方案来测试和发布这些 operator

多集群拯救一切,大大减轻现有 APIServer 的压力,加快我们新功能的升级和部署,减少对用户的影响,缩小爆炸半径,提升用户体验。

此外,“不要把鸡蛋放在一个篮子里”似乎也是云战略的趋势。在 VMware 最新的 2021 年报告中, 36% 的用户已经在推动多云战略,这也是许多公司的计划。

https://tanzu.vmware.com/content/ebooks/the-state-of-kubernetes-2021

由于与 GCP 深度绑定,我们更接近多云战略是明智的,部署多集群将是第一步。

如何设置多集群

我们的研究从 CNCF 中可以支持和满足我们需求的现有工具开始。除了上面列出的痛苦之外,我们现在应该专注于我们实际需要的东西。

  • 集群部署,可以快速部署多个集群,解决网络问题。

  • Cluster Discovery ,当用户资源分散到多个集群时,搜索当前需要运行的集群的中心服务。它还应该提供类似于一致性哈希的功能,以避免在集群随后增加时将资源重新部署到不同的集群。
  • GCP 资源和自定义 CRD 支持。对于 Google Config Connector 定义的那些 GCP 资源,以及公司内部 CRD 定义的资源,我们需要更多的支持。
https://cloud.google.com/config-connector/docs/overview

同时,我们也需要适应很多地方的多集群变化。

根据 CI/CD 中的当前请求对资源进行分组。有时,我们需要同时在多个集群上启动操作。

  • 确保每个 operator 都支持多集群。
  • 为用户提供 UX CLI 工具来发现他们的 CLI 操作资源。考虑到所有这些需求,让我们看看社区中的用户如何实现多集群,采用哪些策略,使用哪些工具。

战略

通常有两种多集群策略,以 Kubernetes 为中心和以网络为中心。

  • Kubernetes 为中心,管理多个集群,通过在多个集群上构建控制平面层来分发和调度资源管理请求,这些集群相互隔离,每个集群管理不同的资源。
  • 以网络为中心,通过网络配置实现不同集群之间的通信,实现资源复制,保持每个集群上的资源一致。

您可能会发现这两种策略类似于克服我们在数据库中遇到的瓶颈的传统方法。确切地!以 Kubernetes 为中心就像 master-master 模式,依赖于数据库中间件(控制平面)来处理和分发请求,而以 network-centric master-slave 模式,主从之间的通信最终保持数据一致.

在我们的案例中,以网络为中心的策略并不适用,但以 Kubernetes 为中心的策略可以减轻每个集群的负担。

工具

来自云提供商的那些工具,例如 GKE 的多集群支持,已经过时了。它们基本上是以网络为中心的,并伴随着两个主要问题。

  • 不那么开源,难以定制或二次开发。

  • 与云提供商本身高度耦合,不利于未来的多云或混合云战略。

现在看看我们可以选择社区中哪些流行的工具。

Kubefed

这个流行的多集群工具有两个版本, v1 kube-federation (已经放弃)和 v2 kubefed

kubefed 的整体架构可以看出,它本质上是由两个 CRDType Configuration 和, 组成的, Cluster Configuration 并通过 CRD 各自的控制器和准入 webhook 来实现这两个主要功能。

  • 跨集群分布。通过抽象、 和三个概念 Templates ,可以将资源(如)部署到不同的集群,实现多集群扩展。 PlacementOverridesDeployment
  • 调度 clusterSelector ,用和实现资源调度 ReplicaSchedulingPreference 。此外, kubefed 还支持高可用、更轻松的资源迁移、多云和混合云部署等诸多特性。

然而,它不是我们要找的那个。

  • 对于大多数开发人员来说,它是一个复杂的工具,学习曲线陡峭。

  • 不支持自定义分发策略,无法满足我们隔离不同稳定性资源的需求。例如, ReplicaSchedulingPreference 只能支持 Deployments Replicasets
  • 它不支持自定义 CRD 。我们需要额外的努力来管理来自 Config Connector .

Gitops

Gitops 已经是非常流行的 CI/CD 标准,用于将 Kubernetes 资源部署到集群,例如 FluxCD Fleet ArgoCD ,其中大部分都支持多集群。这是我们可以依靠的吗?

FluxCD 支持多集群和多租户,使用 kustomization helm 添加新集群,并且支持资源隔离。

经过评估,它也不是那个。

  • 没有动态分布。资源分配需要通过类似的方式提前注入 go template ,而不是动态分配。而我们自己的 CI/CD 工具也无法与之无缝集成。

  • 副作用。 helm 申请的开销 kustomize 太高了。这些缺点是其他 Gitops 共有的,也是不适用的。

Karmada

Karmada 来自 CNCF 沙箱,支持多集群和多云策略。

它的设计部分继承自 kubefed v1 v2 ,与 APIServer Scheduler controller-manager 构成一个控制平面,并通过两个 crd PropagationPolicy OverridePolicy 实现资源调度和分发。

Karmada 有很多优点,包括但不限于,

  • 集群管理。统一的 API 支持集群注册和生命周期管理。
  • 声明性资源调度。支持自定义调度策略,根据标签和状态动态调度资源到合适的集群。

  • Karmada 的主要优势在于原生 Kubernetes 资源处理,但它天生不支持 CRD

对于 Kubernetes 原生资源, Karmada 知道如何解析它们,但对于 CRD 定义的自定义资源(或通过聚合 apiserver 之类的扩展),由于缺乏对资源结构的了解,只能将其视为普通资源。因此,高级调度算法不能用于它们。

即需要 Resource Interpreter 开发来实现动态调度等功能。我们不选择它的最大原因。

https://github.com/karmada-io/karmada/blob/master/docs/userguide/customizing-resource-interpreter.md

我们自己的方式

意识到我们正在以一种非常“独特”的方式使用 Kubernetes ,这与社区中的大多数场景不同,我们决定定制自己的实现来完全满足我们的需求。

从当前的单集群过渡到多集群,没有太多事情要做。

  • 集群管理。我们已经使用 terraform 创建了当前集群,因此我们可以 terraform 在解决网络问题并拥有足够的 IP 后快速创建其他集群。

  • 调度。当我们决定根据命名空间将资源分配到不同的集群时,我们需要一个中央调度服务:当传入一个命名空间时,该服务可以返回相应的集群上下文,以便我们可以将资源部署到 CI/CD 服务。该服务还应支持 GRPC ,以与公司内部的分销策略相统一。

  • Golang 支持。我们有很多自研的 operator ,所以 operator 的维护者需要 Golang 包的支持。当然,这是一个不错的选择,因为他们可以通过 RPC 接口获取集群信息。

  • 自动化。使用单个集群,我们通过 CLI 或简单的脚本手动完成集群的构建、安装工具、安装和部署各种 operator 。现在有了多集群,当手动一个一个地部署集群似乎效率低下且容易出错时,我们需要升级。因此,自动化相关的工具和完整的脚本是必要的。

  • 命令行工具。我们希望为用户提供与单集群场景相同的多集群体验,他们可以登录到我们的集群来查看他们的资源。为此,我们需要实现一个 kubectl 插件来封装相关逻辑,只要用户通过命名空间, kubectl 请求就可以转发到相应的上下文中。

基本上,从单集群到多集群的架构变化如下。

正如所见,它比任何现有工具都更有效,并且更适合我们当前的情况。

结束

这是对我们遇到的问题、我们进行的讨论以及在实施多集群过程中引发的思考的回顾。我们没有使用社区中的任何工具,但我们确实通过研究它们的功能、优缺点为自己铺平了道路。

希望它也能为您提供多集群实施的全景图,并在您处于十字路口时有意义。

谢谢阅读!