OK,Hello,大家好,很高兴来到客户看分享今天是由唐中康和唐伯给大家带来的分享主题内容是一个1.5万节点的大型KBS集群的构建光业经验我是唐中康,来自埋予集团我将分享一些我们在这个工作过程中的一些经验和教训今天的分享内容分为两部分首先我来和大家介绍一下我们为什么需要构建一个这么大规模的一个KBS集群以及我们如何构建一个这么大规模的KBS集群接下来第二部分将由唐伯和大家一起聊一聊在构建大规模KBS集群里面的一些性能的优化技术OK,那我们开始第一部分的内容很多人其实会奇怪既然社区对KBS集群的规模有限制我们为什么还需要构建一个这么大规模的KBS集群其实有很多的原因我这里列了几个我相信在很多大的公司里面都会有这些共情的原因首先是超级应用其实很多社区包括大公司其实都会面临着这么一个情况就是APP越造越大以蚂蚁集团自身的例子来说我们其实有一些超级APP可能当个APP的规模都超过万几坡甚至达到两万几的一个坡的这么一个规模那么我们其实可以这里做一个简单的计算对于一个两万坡的规模的APP而言如果它的经典的一个规模是4C8G或者8C16G的话那么当APP的一个资源的需求我们换上下来可能就需要超过一千台机器甚至对于机器小一点甚至要达到两千台机器的一个规模当然这里隐含的一个条件是说我们在我们的集群眼镜的过程中不需要应用去做一些应用架构的调整以适应底下技术实施的一个变化这就会让我们提出的要求是说让我们需要保证KBS接口的不变第二个主要的原因其实是出于成本的考虑比如说我们为一个两万坡的这么一个task专门给一个小集群的话那么给我们的优化的手段就会很受限在这个过程中小集群我们就没有办法通过各种优化的技术去达到一个更好的资源利用率在这个话题方面大集群有一个天然的优势我们可以通过一些高级的调度手段比如说混布比如说分层调度来达到降低整个公司的运行成本对于成本的考虑其实是一个很重要的方面当然第三个方面其实受限于公司的一个应用的一个体系架构对于很多公司而言其实都会有这么一个需求可能出于数据本地话访问的一个考虑或者流量本地话管理的一个考虑会构建出来各种各样的一个应用的架构比如说虚拟数据中心或者一些相似的架构这些架构的设计就导致就会有一些要求这些要求可能是要求相同的一个逻辑架构里面一又跑在同一个集群上这就会给底层的集群增加一个很大的规模的需求基于上述原因当然可能还有一些其他的原因埋集团其实一直维护着业界最大规模的一些K8S集群最近因为业务的需求这个规模对我们又提出了一个更加大的挑战就是我们需要构建一个1.5万节点40万port100万压这么一个超级大的一个K8S集群那么今天我们就跟大家分享一下我们在构建集群的过程中的一些思考那么我们如何做到这个规模呢首先基于我们在埋集团在K8S领域的一个长时间的积累以及我们对于K8S请求模式的一个了解我们最终判断是这个规模是可达到的那接下来的问题就是我们如何去达到这个规模如何逐渐达到这个规模呢从路线来讲我们通过请求模拟通过压测通过防针再加上在线评测再通过逐渐上线的这么一个模式首先对于请求拟合来讲我们是要求所有的请求拟合都是基于真实流量的一个拟合那么对于性能的一个平占来讲我们采用了基于SNO的性能评价方法有了流量以及性能评价的方法接着我们是通过全面路的一个压测找出面路中的一个平经点并优化最终将这些优化的措施逐步再应用无损的一个条件下逐步上线到我们当前的一个集讯体系中那接下来我将逐渐介绍这四个方面我们是怎么做的首先对于真实流量拟合这个方面其实是我们非常重要的其实也是我们关系到整个工作的一个成败我们知道在K8还是集群里边我们有很多的请求各种各样的一个请求动作包括像list包括像get,put以及想update的这些大体可以分为sally一类是list一类是read一类是write那我们选取了集群就是我们某一个集群的一些组成的情况可以看到在集群里面大概有80%以上都是get的请求那剩下的18%是read请求那接下来list的请求这样更少我们可以看到其实请求的组成方式是不一样的当然从请求的消耗的角度来看这个比例又是完全倒过来的虽然list的比例比较小但是list对于K8还是一个资源消耗是最大的那接下来是read请求这两个都会远大于get请求所以我们要对集群里面的流量进行模拟的时候我们需要综合考虑到各种资源的不同以及请求流量的不同资源的不同体现在资源的大小请求流量的不同我刚才提到了体现在请求的请求量不一样那有了这些请求不同的一个比例之后我们可以通过我们的请求工具压力模拟工具从不同的角度去拟合线上的一个真实流量对于我们来说我们选起来像list watchget patch post delete五种动作来模拟整个集群中的请求量然后通过pod cr pvpvc的资源来模拟请求中的资源分布情况有了这个模拟的手段的时候我们可以通过线下模拟的一个环境跟真实的集群中的流量做对比看一下我们模拟的一个真实程度我们选取了一个在线的集群通过拟合的方式我们在资源的拟合资源分布的拟合达到80%在动作请求方式的拟合达到接近80%的这么一个情况下我们可以看到在在整个资源的使用量就是cpu和memory的一个使用率的一个相似度我们在我们的测试集群和真实集群能够达到80%以上同时在请求的latency的情况下的相似度可以达到85%以上整体来说还是不错的有了这个接近真实的一个请求流量之后我们就可以接下来对集群去做模拟压测在做模拟压测之前我们需要明确一点是我们如何去衡量集群的一个性能k8s集群的性能其实在社区也是一个研究了很长时间的一个话题目前的请求性目前的集群性能是基于slo的方式来进行评估的这个表格里面其实就是列出了社区里面对于k8s集群的一个请求性能的一个标准总结来说其实分为两个方面第一方面对于当资源的一个读写请求要求p99的一个研究是小于一秒当然对于list请求就有分为name space和k8s的两个级别的一个限制从我们的角度来看这个限制其实分为两点第一点来说我们认为这个限制其实是非常严格尤其是对于大规模集群来讲1.5万规模的一个集群它的规模已经大于社区标准的一个3倍之多在这种情况下达到社区的这么一秒的一个标准其实还是很难的从另外一个角度来讲这个标准其实代表着用户的体验用户对于k8s的一个性能的请求其实不会随着我们集群规模的一个侦打而降低所以这个方向也是我们需要去追求的OK那接下来说全列入的一个压次有了模拟流量有了我们的性能评估之后我们怎么样来做全列入的一个性能的优化我们都知道1.5万节点的一个规模相当于社区规模3倍之多那在这个情况下挑战其实也是全方位的那意味着我们的我们的性能优化手段也是需要是全列入的这里全列入包括像APSF、ETCDClient以及一些其他的优化APSF这一层主要是针对APSF当前的一个请求的一个cash的情况我们都知道对于APSF的中对APSF的请求APSF里面存在一个请求cash用以降低list的请求对于底层的一个冲击那么这个cash的使用率就是非常重要的一个优化的手段当然还有一些优化的手段后面谈播会给大家做更详细的介绍对于ETCD来说ETCD的优化手段其实非常多像ETCD的裁分就是社区里面非常常用的优化手段包括ETCD独写性能的一个优化我们都知道ETCD是一个多独少写的一个数据户在这种情况下写性能一直是一个大的瓶颈通过我们的优化ETCD在蚂蚁集团里的写性能有大幅的提升当然还包括ETCD的数据压缩以及数据的治理在客户端方面客户端请求方面我们通过客户端的一些经典的优化能够降低客户端的一个请求同时也通过客户端的一个附带金款来降低对于当APSF的一个冲击当然还有一些其他的优化像一些更好的存储的硬件像MEME给ETCD提供很大的性能加持像我们去降低各个组建的一个监控MATCHX的一个量来降低组建的一个执行的压力以及我们通过合并请求包括资源的压缩来进一步提升集群的性能基于对于全链的路对于KBS来说都是一个端道端的一个性能请求尤其是对于大规模集群来讲这个性能会更加的重要任何一个环节的性能短板都会给整个集群带来很大的一个冲击OK 刚刚提到了ETCD的一个性能我这里举了两个具体的例子来说明我们对ETCD的优化的过程中的一些考虑首先基于ETCD的一个体系结构我们知道ETCD的一个请求的Latency跟ETCD数据量的大小其实有一个很直接的关系这里我们列了一个数据想说明的是我们通过对于ETCD数据量的优化通过缩小ETCD的一个数据量能够达到像get, update, delete, create这些全系列的一个请求都能Latency能够降低到原来的一半这就相当于我们的性能有了成倍的一个提升另外一个对于ETCD很重要的是ETCD是整个KBAR的集群的一个数据基础我们在ETCD优化的过程中如何能够升级在线去拆分而不影响到集群中以存的应用这一点是非常重要的这里我举了一个例子以ETCD的拆分为例我们在拆分之前Client的端到APS的端到ETCD端整个资源RV其实是一致的那随着ETCD的拆分比如说我们把Port的ETCD拆分出来Port的ETCD会出现一个更小的RV这会造成整个Client的端的List Watch请求机制的一个失效那在这个过程中我们需要有某些技术手段去能够触发Client的端做一个List的操作更新ETCD的RV从而达到整个恢复List Watch机制的一个功能为了达到这个目的我们也是设计了很多技术方法最终能够做到整个ETCD拆分过程中包括ETCD升级过程中应用无干扰这么一个效果其实说起大规模的机群很多大家的关注点都在于性能都在于我们如何达到这么大一个规模的机群其实对于企业来讲稳定势力还要有企业的那我们在这个过程中如何做到真正的应用无打扰流量无损其实也是一个非常重要的话题这里会是一道三个方面具体来说刚刚提到了像ETCD这是数据的基础任何ETCD的一个fail都会造成非常大的干扰包括APS Server的一个升级以及运行时的一个高可用就是我们的机群规模达到了这么大规模之后我们的线流我们熔断包括机群的高可用方法如何去调整以降低整个机群的风险这个都是非常重要的再来由唐伯给大家分享一下我们在这个过程中一些更多的技术用画的一些技术细节大家好我叫唐伯来自蚂蚁集团接下来由我来为大家分享一下我们在KBS规模化进程当中做的一些具体的用画点我将从APS ServerWebhookController这三个方面来进行分享首先我们来看APS Server的一个剪接APS Server是KBS外部和内部组建进行访问和沟通的一个输扭由左边这样图可以看到APS Server从下到上分为不用的模块最下面的存储模块是用于APS Server来访问ETCD的一个模块APS Server会对ETCD进行List Watch和CRUD在此之上是缓存模块APS Server的缓存模块是为APS Server里面的不同资源pod node service等等提供了一个缓存机制在缓存层这个基础上是registry也就是注册表这一层这一层是为了APS Server对于pod node service这些不同的资源以及CRUD这些不同的请求进行一个特定的操作一个最简单的例子就是在创建pod的时候APS Server会被pod设置它的creation timestamp在这个registry之上是一系列的filter组成的filter chain这里面包括认证健全还有各种限流比如说社区的APF以及神器还有流量控制类似于go away这种filter在这个filter chain再上边就是APS Server对外暴露的各种API包括API v1健康检查还有matrix UI等等那么总体来说APS Server具有三个功能首先是它屏蔽了底层的etcd的存储细节并且提供了一个缓存机制在缓存机制的基础上又提供了list by labellist by field这种不同的访问功能第二点是APS Server对外暴露了关于集群内不同资源的标准的CRUE的接口这是API Server的第二个功能第三点是API Server提供了一个list watch源语通过list watch源语k8s集群内部和外部的客户端可以准时时的与API Server进行数据同步并且可以最终与etcd里面的状态保持一致就是达成一个最终一致性这个是API Server的一个简单介绍那么在规模化这个进程当中让API Server来支持如此大的一个规模的集群相对来说并不是一件很容易的事这个复杂度主要体现在以下极点首先是集群的规模很大其次是集群里面的各种资源的量很大比如说powder, config map, service, endpoints这些量都很大第三点是集群内部和外部的各个总签会对集群的各种资源来进行一个频繁的更新也就是集群里面的这些资源的变化率是很大第四点是集群中各个资源之间也有一个相互的依赖关系比如说service和endpoint比如说pv和pvc因为以上的这些复杂性我们可以看到这个从外部来对API Server进行一个系统的疏忆相对来说比较是比较难的所以我们就采取了反其道而行之的方法由内而外对API Server进行分层然后在主层进行优化这个分层和上一张图有所类似从下到上分别是etcd然后存储层、缓存层和访问层其中etcd这一层当然是etcd需要给API Server来提供SLO的保障同时也有etcd的运为的保障当然还有包括etcd的其他的一些优化比如说写优化比如说multi-sharding的一些优化在etcd的基础上存储层对API Server进行一些优化这些优化点包括API Server写uetcd的时候Guaranteed Update如果出现Resource Version的冲突会有一个重新get重新写入的过程但是在极群变化率特别大的情况下Resource Version的冲突是非常大的为了减少冲突我们增加它的尺寸退避这是存储层的优化点之一当然还包括其他的一些比如说对于写流etcd的数据大小进行压缩在存储层之上的缓存层相对来说是可以优化的点比较多的一层在这一层里我们进行了逐下的一些比较有距代表性的优化点比如说握持看是大小的动态调整比如说list操作的一些优化比如说这个对于极群中的常用资源和非常用资源增加所以这些优化在缓存层之上的访问层访问层相对来说优化点相对散一些就是我们会对其中profile出来的一些热点来进行优化比如说节点健全它的性能问题进行一些优化还有matrix数量太多然后来削减matrix这种优化那么接下来我将分层介绍其中一些比较典型的优化点首先我们来看缓存层的优化点缓存层这边相对来说比较有代表性的两个优化点如右所示左边是APS2缓存的一个大体的架构图APS2里面的缓存对于每一种资源都提供了一个Warchcash的结构Warchcash分为上下两个部分上边是一个现成安全的map这个map包含了一些索引比如说nodeName的索引name space的索引以及其他一些我们希望的label的索引在下边的一部分是WarchcashEvent的一个数组这个数组缓存了从ResourceVersionA到ResourceVersionB的一个WarchcashEvent里面的数据那么这个数组的打脚对于APS2的稳定性来说是直观重要的比较小的Warchcash的数组的大小会造成各种客户端在访问APS2的时候由于ResourceVersion已经不在这个数组里面了就会产生这个APS2返回这个2O的ResourceVersion的错误给客户端并且客户端收到这个错误之后还会进行重新的LeaseWarch操作这个LeaseWarch操作进而对APS2会产生更多的负面影响对这个是Warchcash里面的这个数组的影响第二点呢我们做的一个比较典型的优化是说给这个Warchcash增加了用户常用的索引就是我们对于APS2的日治进行了详细的分析并且根据日治提取出来了用户的访问模式然后在这个Warchcash里面根据用户的反问模式对特定的标签增加了相应的索引这里面的一个数据是说当集群里面砲的的规模在10万个砲的以上的情况下我去Least砲的LeastbyLabel这个砲的有没有损的情况下呢ResponseTime会有40倍的差异所以可见就是增加了索引对于客户端访问APS2的RT的提升还是非常巨大的接下来是刚才说的APS2这个Warchcash动态调整的优化点的更详细的一个解释就是刚才也说到了APS2这个Warchcash的大小它是非常重要的一个点太小的这个Warchcash会造成左边说的LeastWarch12的ResourceVersion的这个负面的循环这个负面循环呢竟然会加重APS2的压力如果太大的WarchcashSize也会就是消耗APS2的很大的内存因此对于这种大规模集群来说为了保证它的稳定性我们需要选择一个合理的Warchcash大小这个合理的WarchcashSize的大小就是根据这个集群中这个资源相对的相应的这个资源的变化率来设定了同时我们也对这个Warchcash大Warchcash大小动态调整的这个方法进行了优化那么在这个我们这个比较大规模的集群当中可以看到优化之前Pald和Node12的ResourceVersion如上面这样的图所示会分别到500到1000多这个规模就是每分钟那么在我们优化之后可以看到Pald的Warcharrow12的ResourceVersion这个arrow会从1000左右下降到700左右然后这个Node的Warcharrow也会从7800下降到接近预零就是几乎消失了那么整体来说这个集群当中list操作的个数会从4000多个每分钟下降到接近3000个每分钟也就是每分钟会有1000多个list操作的减少这个对于API Server对于我们整个集群的稳定性来说还是有很大的提升的那么在缓存层之后是存储层和接入层的一些典型的优化点的介绍吧存储层就是在GaranteedUpdate里面会出发这个ResourceVersion的冲突而导致Update不成功那么为了避免这些冲突我们就是在这个Transaction之后如果它发生冲突我们就加入指数退避这样大大的减少了集群中的这个GaranteedUpdate冲突的情况另外一点右边这样图是说这个API Server对于Coulette访问集群中的资源会有一个Node Authorizer就是节点健全这个节点健全的功能会在API Server内存里面构建一个比较大的图结构这个图结构随着集群资源量的增多它的更新也会逐渐变得缓慢那么我们发现了这个性能问题之后也是进行了一些优化同时也发现了社区的方案就是我们也是根据社区的这个方案来进行了优化并且解决了这个性能问题接下来我来分享一下WebHook相关的优化在大规模KBS集群当中WebHook的性能对于整体的稳定性以及整体的性能来说也是之关重要的下面我们来看一个典型的优化点就是API Server在访问WebHook的时候特别是Mutating的WebHookMutating WebHook会对Patch前和Patch后的两个Rentime Object来进行一个地规的对比就是会对两个对象的各个子字段进行地规的Reflect.dp口操作然后来生成这个Operation的数组Operation的数组就是它即将Patch回去的操作那么在生成即将Patch回去的操作的时候我们通过火焰图发现就是V2.createPatch函数实际上耗费了大量的CPU时间那么针对这个热点我们进行了一个优化就是在生成Patch的Operation数组之前我们先去对比Patch前和Patch后两个Rentime Object它的Bit的数组的情况以此来降低这个后面的非常多的一规的DP口操作那么在我们优化之后可以看到Patch的数量基本上可以削减到10%也就是削减到90%以上所以说这个虽然是一个非常简单的优化点但是效果看起来还是非常明显的除了Webhook之外Controller的性能也是至关重要的在我们的大规模KBS集群当中主要有三组Controller分别是KBS自带的原生的库博Controller Manager第二部分是蚂蚁集团里边各种原数据的Controller第三个就是各个业务方面的Controller包括大数据的Controller积极学习的Controller以及Pass到自己的Controller那么针对如此种类凡多的Controller我们采取的优化手段也是以不变硬拌变由内而外的来进行优化那么整体来说我们优化这些Controller的方法论就是如右边所示首先是删除不必要的Controller对于APS2的调用其次是合并一些相似的APS2的调用第三点是说对于这个POD它的整体的创建或者删除联络我们综合考虑多个组件的功能然后通过多个组件的配合来以此降低Controller对于APS2的调用第四点是专门针对各个业务方的Controller我们来规范这些Controller的使用方法以此达到最优的对于APS2的调用第五点是针对这些各个组件里面非常多的Metrics来进行Metrics的优化比如说调整Histogram类型的这种Metrics的Bucket Size第六点也就是相对于底层一点就是优化Controller Runtime还有这个Kind of Go那么在这些优化Controller的方法论的基础上我们也是对于这个Controller进行了一个比较大的性能提升下面有一些优化点这里边就不具体介绍了接下来我们来看一下整体的优化结果首先是APS2基础资源上CPU是略有降低的但是内存却是有所增加这个主要是因为我们的动态调整WashCashSize的大小会消耗一定内存这个也是我们预期之内的通过少量内存增加来换取了整体集存的稳定右下角这样通往是之前展示过的WashArrow还有LeaseOperation数量的减少就是可以看到在大规模机型中每分钟会有1000个以上的Lease操作的减少对 这个对于稳定性来说还是有很大提升的那么接下来来看一下整体的RT提升就是这张图从左投右分别是PatchPostPootDelete自种写操作的P99P90和P50的延迟有这张图可以看出这些延迟分别有大约30%至60%的降低就是由此也可以证明我们整体的KBS的大规模机群其实也在向着高效和稳定的方向发展接下来是未来的一些展望优化一个大规模的分布式系统无外乎其实可以总结出三点第一点就是提升这个系统本身的架构来借此提升它的性能和稳定性第二点是管理 访问系统的各种业务方各种外部的流量解决去优化它们的使用方法还有它们的架构第三点是去优化我们分布式系统所依赖的服务那么对于KBS对于KBS大规模机群这种分布式机群这种分布式的架构来说首先我们需要有SIO的签引这个SIO包括API Server的RT的SIOEDCD的RT的SIO以及交付给用户的POD它泡的在创建和删除的时候整体的耗时的这种SIO在这些SIO的签引下我们会去对API Server、EDCDoperator还有这些各种的业务方的operator以及我们自己的调动器和couplet会去全方位的进行优化并且我们希望最终可以达到了是一个可量化性也就是我们KBS机群中关键总建的CPU内存消耗以及对外暴露出的客户端访问API Server的RT还有用户在创建泡的删除泡的交付时间我们希望它都是一个可量化的可以从集群规模可以从集群的访问量例子CRUD访问量PODNO的个手这些来进行一个确定性的量化所以我们不光希望给用户提供的是一个高稳定性高性能的集群我们也希望给用户提供一个确定的集群好的今天的分享就到这里感谢大家的聆听谢谢