作者简介

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,我们喜欢简单。

Rancher首席架构师解读Fleet:它何以管理百万集群?的更多相关文章

  1. 架构师必备:Redis的几种集群方案

    结论 有以下几种Redis集群方案,先说结论: Redis cluster:应当优先考虑使用Redis cluster. codis:旧项目如果仍在使用codis,可继续使用,但也推荐迁移到Redis ...

  2. Kubernetes全栈架构师(Kubeadm高可用安装k8s集群)--学习笔记

    目录 k8s高可用架构解析 Kubeadm基本环境配置 Kubeadm系统及内核升级 Kubeadm基本组件安装 Kubeadm高可用组件安装 Kubeadm集群初始化 高可用Master及Token ...

  3. Kubernetes全栈架构师(二进制高可用安装k8s集群部署篇)--学习笔记

    目录 二进制高可用基本配置 二进制系统和内核升级 二进制基本组件安装 二进制生成证书详解 二进制高可用及etcd配置 二进制K8s组件配置 二进制使用Bootstrapping自动颁发证书 二进制No ...

  4. Kubernetes全栈架构师(二进制高可用安装k8s集群扩展篇)--学习笔记

    目录 二进制Metrics&Dashboard安装 二进制高可用集群可用性验证 生产环境k8s集群关键性配置 Bootstrapping: Kubelet启动过程 Bootstrapping: ...

  5. 葡萄城首席架构师:前端开发与Web表格控件技术解读

    讲师:Issam Elbaytam,葡萄城集团全球首席架构师(Chief Software Architect of GrapeCity Global).曾任 Data Dynamics.Inc 创始 ...

  6. 子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

    本文原文内容来自InfoQ的技术分享,本次有修订.勘误和加工,感谢原作者的分享. 1.前言 自从2018年8月20日子弹短信在锤子发布会露面之后(详见<老罗最新发布了“子弹短信”这款IM,主打熟 ...

  7. [转]CTO、技术总监、首席架构师的区别

    经常有创业公司老板来拜访我,常常会拜托给我一句话:帮我找一个CTO. 我解释的多了,所以想把这个写下来,看看你到底需要的应该是啥. 一.高级程序员 如果你是一个刚刚创业的公司,公司没有专职产品经理和项 ...

  8. CTO、技术总监、首席架构师的区别

    2016年11月30日13:22:26[转] CTO.技术总监.首席架构师的区别 提升自已的能力,比如专业技术,行业发展趋势,技术发展趋势,协调能力,组织能力,管理能力等[技术总监] 需要从技术总监和 ...

  9. 【转】】CTO、技术总监、首席架构师的区别

    经常有创业公司老板来拜访我,常常会拜托给我一句话:帮我找一个CTO. 我解释的多了,所以想把这个写下来,看看你到底需要的应该是啥. 一.高级程序员 如果你是一个刚刚创业的公司,公司没有专职产品经理和项 ...

随机推荐

  1. egg的基本使用

    一.脚手架(可以快速生成项目) 1.新建一个项目文件夹,使用如下命令: 2.npm  init  egg  --type=simple 3.npm i 它会根据package.json里记录的所需包进 ...

  2. SSM框架中常用的注解及含义

    @Controller---使用它标记在一个类上,dispatcher会扫描使用该注解类的方法,并检测该方法是否使用了@RequestMapping注解,加上RequestMapping注解的方法才是 ...

  3. 超详细!使用 LVS 实现负载均衡原理及安装配置详解---转

    负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学 ...

  4. block、inline、inline-block区别以及标签嵌套

    1.block 将元素转为块元素,块元素占一行,可以设置宽和高. 2.inline 将元素转为行内元素,占一行,不可以设置宽和高. 3.inline-block 将元素设置为行内块元素,这时元素既可以 ...

  5. Day9 python高级特性-- 列表生成式 List Comprehensions

    Python内置的非常简单却强大的可以用来创建list的生成式.    私理解为,就是for循环出来的结果搞成个list~~~~    要生成顺序增量list可以使用list(range(x,y))来 ...

  6. Unity 操作快捷键

            Q Hand(手形)工具 可以平移整个Scene视图       W Translate(移动)工具 移动所选择的游戏对象       E Rotate(旋转)工具 按任意角度旋转游戏 ...

  7. IDEA中flink程序报错找不到类

    Idea中运行flink程序,报错找不到类,其中pom文件中一项依赖为: <dependency> <groupId>org.apache.flink</groupId& ...

  8. 1款开源工具,实现自动化升级K3S集群!

    即便你的集群能够平稳运行,Kubernetes升级依旧是一项艰难的任务.由于每3个月Kubernetes会发布一个新版本,所以升级是十分必要的.如果一年内你不升级你的Kubernetes集群,你就会落 ...

  9. 深度学习炼丹术 —— Taoye不讲码德,又水文了,居然写感知器这么简单的内容

    手撕机器学习系列文章就暂时更新到此吧,目前已经完成了支持向量机SVM.决策树.KNN.贝叶斯.线性回归.Logistic回归,其他算法还请允许Taoye在这里先赊个账,后期有机会有时间再给大家补上. ...

  10. 一、Electron + Webpack + Vue 搭建开发环境及打包安装

    目录 Webpack + Vue 搭建开发环境及打包安装 ------- 打包渲染进程 Electron + Webpack  搭建开发环境及打包安装 ------- 打包主进程 Electron + ...