乐趣区

关于集群:Rancher首席架构师解读Fleet它何以管理百万集群

作者简介

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,咱们喜爱简略。

退出移动版