多个维度分析k8s多集群管理工具,到底哪个才真正适合你
关 注 微 信 公 众 号 《 云 原 生 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
个集群。
http://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 "http://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%
的用户已经在推动多云战略,这也是许多公司的计划。
http://tanzu.vmware.com/content/ebooks/the-state-of-kubernetes-2021
由于与 GCP
深度绑定,我们更接近多云战略是明智的,部署多集群将是第一步。
如何设置多集群
我们的研究从 CNCF
中可以支持和满足我们需求的现有工具开始。除了上面列出的痛苦之外,我们现在应该专注于我们实际需要的东西。
-
集群部署,可以快速部署多个集群,解决网络问题。
-
Cluster Discovery
,当用户资源分散到多个集群时,搜索当前需要运行的集群的中心服务。它还应该提供类似于一致性哈希的功能,以避免在集群随后增加时将资源重新部署到不同的集群。 -
GCP
资源和自定义CRD
支持。对于Google Config Connector
定义的那些GCP
资源,以及公司内部CRD
定义的资源,我们需要更多的支持。
http://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
开发来实现动态调度等功能。我们不选择它的最大原因。
http://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
个集群。
http://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 "http://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%
的用户已经在推动多云战略,这也是许多公司的计划。
http://tanzu.vmware.com/content/ebooks/the-state-of-kubernetes-2021
由于与 GCP
深度绑定,我们更接近多云战略是明智的,部署多集群将是第一步。
如何设置多集群
我们的研究从 CNCF
中可以支持和满足我们需求的现有工具开始。除了上面列出的痛苦之外,我们现在应该专注于我们实际需要的东西。
-
集群部署,可以快速部署多个集群,解决网络问题。
-
Cluster Discovery
,当用户资源分散到多个集群时,搜索当前需要运行的集群的中心服务。它还应该提供类似于一致性哈希的功能,以避免在集群随后增加时将资源重新部署到不同的集群。 -
GCP
资源和自定义CRD
支持。对于Google Config Connector
定义的那些GCP
资源,以及公司内部CRD
定义的资源,我们需要更多的支持。
http://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
开发来实现动态调度等功能。我们不选择它的最大原因。
http://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
请求就可以转发到相应的上下文中。
基本上,从单集群到多集群的架构变化如下。
正如所见,它比任何现有工具都更有效,并且更适合我们当前的情况。
结束
这是对我们遇到的问题、我们进行的讨论以及在实施多集群过程中引发的思考的回顾。我们没有使用社区中的任何工具,但我们确实通过研究它们的功能、优缺点为自己铺平了道路。
希望它也能为您提供多集群实施的全景图,并在您处于十字路口时有意义。
谢谢阅读!
- Go 中的 Kubernetes GraphQL 动态查询
- 揭开云原生数据管理的神秘面纱:操作层级
- 云原生数据库,激活数智创新之力
- 企业考虑云原生分布式数据库的三个原因
- 一组用于 Kubernetes 的现代 Grafana 仪表板
- Go 中的构建器模式
- 让我们使用 Go 实现基本的服务发现
- 云原生下一步的发展方向是什么?
- 用更云原生的方式做诊断|大规模 K8s 集群诊断利器深度解析
- 多个维度分析k8s多集群管理工具,到底哪个才真正适合你
- 使用 Kube-capacity CLI 查看 Kubernetes 资源请求、限制和利用率
- 使用 Go 在 Kubernetes 中构建自己的准入控制器
- 云原生数仓如何破解大规模集群的关联查询性能问题?
- 云原生趋势下的迁移与灾备思考
- 2022 年不容错过的六大云原生趋势!
- 使用 Prometheus 监控 Golang 应用程序
- 云原生时代下的机遇与挑战 DevOps如何破局
- 如何在云原生格局中理解Kubernetes合规性和安全框架
- 设计云原生应用程序的15条基本原则
- 使用 Operator SDK 为 Pod 标签编写Controller