设计Kubernetes集群:应该有多少个?

注意 佩雷夫。:来自learningk8s教育项目的材料是在设计基于Kubernetes的基础设施时一个常见问题的答案。我们希望对每个选项的利弊进行足够详细的描述,有助于为您的项目做出最佳选择。



TL; DR:同一组工作负载可以在多个大型集群(每个集群将拥有大量工作负载)或许多小型集群(每个集群具有少量负载)上运行。

下表总结了每种方法的利弊:



当使用Kubernetes作为运行应用程序的平台时,经常会出现一些有关集群配置复杂性的基本问题:

  • 要使用几个集群?
  • 他们有多大?
  • 每个群集应包括什么?

在本文中,我将通过分析每种方法的利弊来尝试回答所有这些问题。

问题陈述


作为软件创建者,您可能会并行开发和操作许多应用程序。

此外,这些应用程序的许多实例都可能在各种环境中运行-例如,可以进行开发测试生产

结果是应用程序和环境的完整矩阵:


应用程序和环境

在上面的示例中,展示了3个应用程序和3个环境,最终提供了9种可能的选择。

每个应用程序实例都是一个独立的部署单元,可以独立于其他应用程序进行操作。

请注意,应用程序实例可能包含许多组件。例如前端,后端,数据库等。对于微服务应用程序,实例将包括所有微服务。

结果,Kubernetes用户有几个问题:

  • 是否应将所有应用程序实例放在一个集群中?
  • 是否应该为应用程序的每个实例创建一个单独的集群?
  • 还是应该结合使用以上方法?

所有这些选项都非常可行,因为Kubernetes是一个灵活的系统,不会限制用户的可能性。

以下是一些可能的方法:

  • 一个大型的公共集群;
  • 许多小型的高度专业化的集群;
  • 每个应用程序一个集群;
  • 每个环境一个集群。

如下所示,前两种方法处于选项范围的相对两端:


从几个大型群集(在左侧)到许多小型群集(在右侧)

通常,如果一个群集的节点和吊舱之和较大,则它被认为比另一个群集更大。例如,具有10个节点和100个容器的群集比具有1个节点和10个容器的群集大。

好吧,让我们开始吧!

1.一个大型公共集群


第一种选择是将所有工作负载放置在一个集群中:


一个大型集群

作为该方法的一部分,该集群用作通用基础架构平台 -您只需在现有Kubernetes集群中部署所需的一切即可。

命名空间的 Kubernetes允许在逻辑上将集群的一部分彼此分开,以便其命名空间可用于应用程序的每个实例。

让我们看看这种方法的优缺点。

+有效利用资源


对于单个集群,仅需要启动和管理Kubernetes集群所需的所有资源的一个副本。

例如,这对于主节点是正确的。通常,每个Kubernetes集群有3个主节点,因此,对于一个集群,它们的数量将保持不变(为了比较,10个集群将需要30个主节点)。

上述细微之处适用于在整个群集范围内运行的其他服务,例如负载平衡器,入口控制器,身份验证,日志记录和监视系统。

在单个群集中,所有这些服务都可以立即用于所有工作负载(与多个群集一样,您无需创建它们的副本)。

+便宜


由于上述原因,较少数量的群集通常较便宜,因为没有多余资源的成本。

对于主节点而言尤其如此,而无论采用哪种放置方法(内部部署还是在云端),主节点都会花费大量资金。

一些托管的Kubernetes服务,例如Google Kubernetes Engine(GKE)Azure Kubernetes Service(AKS),可免费提供控制层。在这种情况下,成本问题不那么尖锐。

还有一些托管服务,每个Kubernetes集群收取固定费用(例如,Amazon Elastic Kubernetes Service,EKS)。

+有效的管理


管理单个集群比几个集群容易。

管理可能包括以下任务:

  • Kubernetes的更新版本;
  • CI / CD管道配置
  • CNI插件安装;
  • 建立用户认证系统;
  • 设置访问控制器;

还有许多其他...

对于一个群集,所有这些操作仅需执行一次。

对于许多集群,操作将不得不重复多次,这可能需要对过程和工具进行某种自动化,以确保系统和统一的过程。

现在,关于劣势的几句话。

-单点故障


如果单个群集发生故障所有工作负载将立即停止工作

当出现问题时,有很多选择:

  • 更新Kubernetes会导致意外的副作用;
  • 群集范围内的组件(例如,CNI插件)无法正常工作;
  • 群集组件之一配置不正确。
  • 基础基础架构出现故障。

一种此类事件可能会严重破坏位于公共群集中的所有工作负载。

-缺乏硬质绝缘


在共享集群中工作意味着应用程序共享集群节点上的硬件,网络功能和操作系统。

从某种意义上说,在同一主机上运行具有两个不同应用程序的两个容器类似于在运行相同OS内核的同一台计算机上运行的两个进程。

Linux容器提供某种形式的隔离,但远没有像虚拟机所提供的隔离那样强大。本质上,容器中的进程与主机操作系统上运行的进程相同。

这可能是一个安全问题:理论上,这样的组织允许不相关的应用程序彼此交互(有意或无意)。

此外,在Kubernetes群集共享所有工作负载的一些集群范围的服务,如DNS -这使得应用程序能够找到其他应用程序的服务在群集中。

根据对应用程序安全性的要求,以上所有项可能具有不同的含义。

Kubernetes提供了各种工具来防止安全问题,例如PodSecurityPoliciesNetworkPolicies。但是,由于其正确的配置还需要一些经验,因此它们不能完全消除所有安全漏洞。

请务必记住,Kubernetes最初是为共享而设计的而不是为了隔离和安全

-缺乏紧密的多租户


鉴于Kubernetes集群中共享资源的丰富性,有许多方法可以使不同的应用程序“相互hit脚”。

例如,一个应用程序可以垄断某些共享资源(例如处理器或内存),并剥夺在同一节点上运行的其他应用程序对其的访问权。

Kubernetes提供了各种机制来控制这种行为,例如资源请求和限制 (另请参见“ CPU限制和Kubernetes中的主动节流 ”一文,大约翻译)ResourceQuotasLimitRanges。但是,与安全性一样,它们的配置非常重要,并且不能完全防止所有不可预见的副作用。

-大量的用户


对于单个群集,许多人必须打开对该群集的访问权限。并且他们的数量越多,他们“破坏某些东西”的风险就越高。

在集群内部,您可以控制使用基于角色的访问控制(RBAC) 进行的操作和执行的操作(请参阅文章“ Kubernetes中的用户和RBAC授权 ”-大约传输但是,这不会阻止用户在其责任范围内``破坏''某些东西。

-集群不能无限增长


用于所有工作负载的群集可能会很大(就节点和Pod的数量而言)。

但是这里又出现了一个问题:Kubernetes中的集群不能无限增长。

群集大小有理论上的限制。在Kubernetes,大约有5,000个节点,15万个pod和30万个容器

但是,在现实生活中,问题可以更早地开始出现-例如,只有500个节点

事实是,大型集群在Kubernetes控制层上施加了很高的负载。换句话说,为了使群集保持运行并有效地使用资源,需要进行仔细的调整。

在原始博客中名为“ 架构Kubernetes集群-选择工作节点大小的相关文章中对此问题进行了探讨

但是,让我们看一下相反的方法:许多小型集群。

2.许多小型的专业集群


使用这种方法,您可以为每个部署的元素使用单独的群集:


许多小型群集

就本文而言,部署的元素是指应用程序的实例-例如,单独的应用程序的开发版本。

该策略使用Kubernetes作为单个应用程序实例的专用运行时

让我们看看这种方法的优缺点。

+限制“爆炸半径”


当群集发生故障时,负面影响仅限于该群集中部署的那些工作负载。所有其他工作负载保持不变。

+绝缘


托管在单个群集上的工作负载不共享资源,例如处理器,内存,操作系统,网络或其他服务。

结果,我们在不相关的应用程序之间建立了严格的隔离,这可能会有利地影响它们的安全性。

+用户数量少


鉴于每个群集仅包含有限的工作负载集,因此可以访问该群集的用户数量会减少。

访问集群的人数越少,发生“破坏”的风险越低。

让我们看一下缺点。

-资源利用效率低下


如前所述,每个Kubernetes集群都需要一组控制资源:主节点,控制层组件以及用于监视和日志记录的解决方案。

在大量的小型集群的情况下,有必要分配更大份额的资源用于管理。

- 高成本


资源使用效率低下会自动导致高成本。

例如,维护30个主节点而不是三个具有相同计算能力的主节点必然会影响成本。

-行政困难


管理多个Kubernetes集群比管理一个集群困难得多。

例如,您将必须为每个群集配置身份验证和授权。Kubernetes的升级也必须完成几次。

最有可能的是,您将必须应用自动化来提高所有这些任务的效率。

现在考虑不太极端的情况。

3.每个应用程序一个集群


作为此方法的一部分,您可以为特定应用程序的所有实例创建一个单独的群集:


每个应用程序的群集

这种方法可以被视为对“ 每个团队单独的群集 ”原理的概括,因为通常一个工程师团队会参与一个或多个应用程序的开发。

让我们看看这种方法的优缺点。

+可以为应用程序定制集群


如果应用程序有特殊需要,则可以在群集中实现它们而不会影响其他群集。

这样的需求可能包括GPU工作人员,特定的CNI插件,服务网格或某些其他服务。

每个群集都可以针对其中运行的应用程序进行定制,以便仅包含所需的内容。

-一个集群中的不同环境


这种方法的缺点是,来自不同环境的应用程序实例共存于同一群集中。

例如,应用程序的prod版本与dev版本在同一群集中运行。这也意味着开发人员在运行应用程序生产版本的同一集群中进行活动。

如果由于开发人员的行为或集群中dev版本的故障而导致故障,则prod版本可能会遭受损失-这种方法的巨大缺点。

最后,我们列表中的最后一个脚本。

4.每个环境一个集群


该方案为每个环境分配一个单独的集群:


一个集群用于环境

例如,您可以拥有devtestprod集群,在其中您将运行为特定环境设计的所有应用程序实例。

这是此方法的优缺点。

+隔离产品环境


通过这种方法,所有环境都相互隔离。但是,实际上,这对于产品环境尤为重要。

现在,该应用程序的生产版本独立于其他集群和环境中发生的事情。

因此,如果在开发集群中突然出现问题,则应用程序的生产版本将继续工作,就好像什么都没有发生一样。

+集群可以根据环境进行调整


每个集群都可以根据其环境进行定制。例如,您可以:

  • 在开发集群中安装开发和调试工具;
  • 测试集群中安装测试框架和工具;
  • 产品集群中使用更强大的设备和网络渠道

这使您可以提高应用程序的开发和运行效率。

+限制对生产集群的访问


直接使用产品集群的需求很少出现,因此您可以极大地限制有权使用它的人们的圈子。

您甚至可以走得更远,并且通常使人们无法访问该群集,并使用自动CI / CD工具执行所有部署。这种方法将在最相关的位置将人为错误的风险降到最低。

现在,关于劣势的几句话。

-应用程序之间缺乏隔离


该方法的主要缺点是应用程序之间缺乏硬件和资源隔离。

不相关的应用程序共享群集资源:系统核心,处理器,内存和其他一些服务。

如上所述,这可能具有潜在的危险。

-无法本地化应用程序依赖项


如果应用程序有特殊要求,那么所有集群都必须满足它们。

例如,如果一个应用程序需要GPU,则每个群集必须至少包含一个带有GPU的工作程序(即使仅由该应用程序使用)。

结果,我们冒着成本增加和资源利用效率低下的风险。

结论


如果您有一组特定的应用程序,则可以将它们放置在几个大型群集或多个小型群集中。

本文讨论了各种方法的利弊,从一个全球集群到几个小型且高度专业化的集群:

  • 一个大型的公共集群;
  • 许多小型的高度专业化的集群;
  • 每个应用程序一个集群;
  • 每个环境一个集群。

那么,选择哪种方法呢?

像往常一样,答案取决于用例:您需要权衡不同方法的利弊,并选择最佳选择。

但是,选择不限于以上示例-您可以使用它们的任意组合!

例如,您可以为每个团队组织几个集群:一个用于开发的集群(将具有开发测试环境)和一个用于生产的集群(将在其中放置生产环境)。

根据本文中的信息,您可以针对特定情况相应地优化优缺点。祝好运

聚苯乙烯


另请参阅我们的博客:


All Articles