作者简介

Darren Shepherd,Rancher Labs联结创始人及首席架构师。在退出Rancher之前,Darren是Citrix的高级首席工程师,他在那里从事CloudStack、OpenStack、Docker的工作,并构建下一代基础设施编排技术。在退出Citrix之前,Darren曾在GoDaddy工作,他设计并领导一个团队施行私有和公有IaaS云。

本文转自Rancher Labs

2020年年初,Rancher开源了海量集群治理我的项目Fleet,为大量的Kubernetes集群提供集中的GitOps式治理。Fleet最重要的指标是可能治理100万个散布于不同地理位置的集群。当咱们设计Fleet架构时,咱们心愿应用规范的Kubernetes controller架构。这意味着咱们能够扩大Kubernetes的数量比之前要多很多。在本文中,我将介绍Fleet的架构、咱们用于测试扩大规模的办法和咱们的发现。

为什么是100万个集群?

随着K3s用户量爆发式增长(目前Github Star曾经超过15,000),边缘Kubernetes也开始迅猛发展。一些企业曾经采纳了边缘部署模型,其中每个设施都是单节点集群。或者你可能会看到应用3个节点的集群来提供高可用性(HA)。关键点在于咱们须要解决的是大量小型集群,而不是一个有很多节点的大型集群。现如今,简直任何中央的工程师都在应用Linux,他们都心愿应用Kubernetes来管理工作负载。尽管大多数K3s的边缘部署少于10,000个节点,但达到100万个节点并非不可能。而Fleet将满足你的规模扩大要求。

Fleet架构

Fleet架构的要害局部如下:

  • Fleet应用两阶段pull办法
  • Fleet是一组由规范K8S API交互驱动的K8S Controller
  • Fleet agent不须要始终放弃连贯
  • Fleet agent自身是另一组Kubernetes controller

要从git中进行部署,Fleet Manager首先要复制并存储git中的内容,而后Fleet manager决定须要应用git中的内容更新哪个集群,并创立部署记录供agent读取。当agent能够读取时,agent将check in以读取部署集群,部署新的资源并报告状态。

扩大规模测试方法

咱们应用两种办法来模仿100万个集群。首先,咱们部署了一组大型VM(m5ad.24xlarge - 384 GiB RAM)。每个VM应用k3d运行10个K3s集群。而后这10个集群每个都运行750个agent,每个agent都代表着一个上游的集群。总的来说,每个VM模仿7500个集群。均匀来看,部署一个VM、在Fleet注册所有集群并达到稳固状态大概须要破费40分钟。在两天的工夫里,咱们以这种形式启动虚拟机,直到达到10万个集群。在最后的10万个集群中,咱们发现了大部分的扩大问题。在解决了这些问题之后,扩大变得相当可预测。以这一速度,模仿剩下的90万个集群将会破费很长的工夫以及相当可观的资金。

而后,咱们采纳第二种办法:运行一个模拟器,它能够执行100万个集群会进行的所有API调用,而不须要上游的Kubernetes集群或部署Kubernetes资源。取而代之的是,模拟器进行API调用以注册新集群、发现新部署并报告它们的胜利状态。应用这种办法,咱们在一天内实现了从0到100万个模仿集群。

Fleet manager是一个运行在Kubernetes集群上的controller,运行在3个大型虚拟机(m5ad.24xlarge - 384 GiB RAM)和一个RDS(db.m5.24xlarge)实例上。实际上,咱们应用K3s来运行Fleet Manager集群。咱们这样做是因为Kine曾经在其中集成了。我将在前面解释什么是Kine以及为什么应用它。只管K3s针对的是小规模的集群,但它可能是最容易大规模运行的Kubernetes发行版,咱们应用它是因为其简略易用。值得注意的是,在EKS这样的托管提供商上,咱们无奈大规模运行Fleet,稍后我会解释这一点。

发现1:调整服务账户和费率限度

咱们遇到的第一个问题齐全出其不意。当一个Fleet agent注册到Fleet Manager时,它会应用一个长期的集群注册令牌(token)。而后,该令牌被用来为该集群/agent创立新的身份和凭证。集群注册令牌和该agent的凭证都是服务账户。咱们注册集群的速度受到controller-manager为服务账户创立令牌的速度的限度。通过钻研,咱们发现咱们能够批改controller-manager的默认设置来进步咱们创立服务账户的速度(-concurrent-serviceaccount-token-syncs=100)和每秒API申请的总体数量(-kube-api-qps=10000)。

发现2:etcd不能在此规模下运行

Fleet是作为Kubernetes Controller编写的。因而,将Fleet扩大到100万个集群意味着要在Kubernetes中治理数千万个对象。正如咱们所理解的,etcd并没有能力治理这么大的数据量。Etcd的次要空间有8GB的限度,默认设置为2GB。要害空间包含以后的值和它们之前尚未被垃圾收集的值。在Fleet中,一个简略的集群对象大概须要6KB。对于100万个集群,咱们至多须要6GB。然而一个集群个别蕴含10个左右的Kubernetes对象,加上每个部署一个对象。所以在实际操作中,咱们更有可能须要超过100万个集群10倍的内存空间。

为了绕过etcd的限度,咱们应用了Kine,这使得应用传统的RDBMS运行任何Kubernetes发行版成为可能。在这个规模测试中,咱们运行了RDS db.m5.24xlarge实例。咱们没有尝试对数据库进行适当的大小调整,而是从最大的m5实例开始。在测试完结时,咱们在Kine中领有大概2000万个对象。这意味着以这种规模运行Fleet不能在EKS这样的托管提供商上进行,因为它是基于etcd的,也不会为咱们的需要提供足够可扩大的数据存储。

这个测试仿佛并没有把数据库push得很厉害。诚然,咱们应用了一个十分大的数据库,但很显著咱们还有很多垂直扩大的空间。单条记录的插入和查找持续以可承受的速度进行。咱们留神到,随机列出大量对象(最多一万个)将会破费30秒到一分钟的工夫。但一般来说,这些查问会在不到1秒的工夫内实现,或者在十分粗犷的测试下5秒也能够实现。因为这些耗时很长的查问产生在缓存重载期间,所以对系统整体影响不大,咱们将在前面探讨。只管这些迟缓的查问并没有对Fleet造成显著的影响,但咱们还是须要进一步考察为什么会呈现这种状况。

发现3:减少监控缓存大小

当controller加载缓存时,首先会列出所有对象,而后从列表的修订版开始监控。如果有十分高的变化率并且列出对象破费了很长的工夫,那么你很容易陷入这样的状况:你实现了列表但无奈启动监控,因为API Server的监控缓存中没有这个修订版,或者曾经在etcd中被压缩了。作为一个变通办法,咱们将监控缓存设置为一个十分高的值(–default-watch-cache-size=10000000)。实践上,咱们认为咱们会遇到Kine的压实问题(compact),但咱们没有,这须要进一步考察。一般来说,Kine在压实(compact)的频率上要低很多。但在这种状况下,咱们狐疑咱们增加记录的速度超过了Kine压实的速度。这并不蹩脚。咱们并不心愿保持要保持一致的变化率,这只是因为咱们正在疾速注册集群。

发现4:加载迟缓的缓存

Kubernetes controller的规范实现是将你正在解决的所有对象缓存在内存中。对于Fleet,这意味着咱们须要加载数百万个对象来建设缓存。对象列表的默认分页大小为500。加载100万个对象须要2000个API申请。如果你假如咱们能够每秒钟进行一次列表调用、解决对象并开启下一页,这意味着加载缓存须要30分钟左右。可怜的是,如果这2000个API申请中的任何一个失败,这个过程就会从新开始。咱们尝试将页面大小减少到10,000个对象,但看到整体加载工夫并没有显著放慢。咱们开始一次列出1万个对象之后,咱们就遇到了一个问题,Kine会随机破费超过1分钟的工夫来返回所有对象。而后Kubernetes API Server会勾销申请,导致整个加载操作失败,不得不重新启动。咱们通过减少API申请超时(-request-timeout=30m)来解决这个问题,但这不是一个可承受的解决方案。放弃较小的页面大小能够确保申请的速度更快,但申请的数量减少了失败几率,并导致整个操作重启。

重启Fleet controller将须要破费45分钟的工夫。这一重启工夫同样实用于kube-apiserver和kube-controller-manager。这意味着你须要十分小心。这也是咱们发现运行K3s不如运行RKE等传统发行版的一点。K3s将api-server和controller-manager联合到同一个过程中,这使得重启api-server或controller-manager的速度比本来应有的速度慢,而且更容易出错。模仿一场灾难性的故障,须要齐全重启所有服务,包含Kubernetes,这所有花了几个小时才复原上线。

加载缓存所需的工夫和失败的几率是迄今为止咱们发现的扩大Fleet的最大问题。今后,这是咱们要解决的首要问题。

结 论

通过测试,咱们证实了Fleet的架构能够扩大到100万个集群,更重要的是,Kubernetes能够作为一个平台来治理更多的数据。Fleet自身与容器没有任何间接的关系,能够看成只是一个简略的利用,在Kubernetes中治理数据。这些发现为咱们开启了一个可能性,即把Kubernetes更多的当作一个通用的编排平台来写代码。当思考到你能够很容易地将一套controller与K3s捆绑在一起,Kubernetes就变成了一个很好的自成一体的利用server。

在扩大规模方面,从新加载缓存所需的工夫令人担忧,但相对是可控的。咱们将持续在这方面进行改良,使运行100万个集群不仅是可行的,而且是简略的。因为在Rancher Labs,咱们喜爱简略。