大家下午好我是来自上期通用的戴嘉顺今天很荣幸可以站在QBCon的舞台上然后拉上我的两位小伙伴给大家做些女员生方面的技术的分享今天我们分享的主题是构建一个Ate of Atew的QBnated控制品面那与业界更多上层盖楼的方案有所不同的是我们针对实际的业务足球实现了一个更加扁平化的话希望对应的一些新的思路可以给大家带来启发开始之前快速作家做过介绍大家算来上通用之后同事多年汽车领域的业务架构设计目前在负责企业的云平台的规划和落地大家好我叫顺文杰来自Docloud然后是担任人建开发的一个工程师经常参与一些云元生项目的一个研发大家好我叫黄敏杰然后我也是来自上海道客网络科技有限公司现在担任的话是高级软件工程师然后我也是参与多个云元生的项目然后也是多个世界赛福社区的一个memberOK接下来我们快速回顾价上集同银汽车在过去的一段时间在云元生方面的技术分享的一个例子在2016年的时候因为意识到未来容器相关的一些技术可能是找到了一个重点方向我们开始在这方面做了一些技术方面的一些研究和探索我记得当年Docloud和Cribnatives还处于这么一个如何如图一半一半的一个阶段之后我们当时内部也是做了多个维度的一些评估最终选择了Cribnatives作为企业云的实现时间来到2017年了之后我们针对于我们重点的一些业务领域主要是BTC和经销商两个领域进行容器化的一些探索和落地的POC工作然后一般年的时候随着对应的POC已经取得了一定的进展我们进一步加大这方面的一个投入开始做多级群的管理时间来到2020年我不知道大家针对这一年还有什么印象当时业界的整个一个套路或者年度词汇是什么我不知道大家还有印象敏态和稳态当年的一个套路是说我针对于传统的一些业务更多使用稳态的虚拟化的传统的技术方案去解决之后我如果是一些TTC的有一定流量层面上凸针的一些业务我们倾向于走心的营养生的一些喘心的解决法可是这两者就针的这么水火不容吗是不是可以融会贯通因此在2020年的时候留给我的我和我的团队的一个问题就是是不是我们可以通过管理传统容器的方法来管理传统的计算资源甚至是IT内部的一些服务同样的如果我们选择Cubanated来管理的话Cubanated本身这层的平台的靠心是这么保证的要回答这个问题首先我们要快速先了解一下Cuba本身是怎么样做治疗管理的接下来我就给大家简单的先介绍一下在KBS中是怎么管理资源的首先KBS它可以它有一套自己内置的一个资源比如说PoD Service Deployment这种然后它是通过它的版本然后类型还有Group这种方式去进行管理我们可以通过创建这种资源来满足基本的这种应用的创建然后第二种方式的话我们可以通过定义CRD的这种方式来拓展我们想要的一些自定义的资源我们定义之后CRD是一种我们知道CRD是一种命令式的一种控制方式它和KBS的理念是一致的所以我们可以定义完CRD之后可以创建自己所需要的资源来进行管理然后通过Cubacontrol去进行管理然后第三种的话是通过自定义API Server也就是我们常说的那个Aggregation API Server它这种方式可以创建命令式的方式和同步的方式来定义自己的API因为我们可能一些原有的一些业务系统里面可能有一些原有就有的一些API然后我们想要集成纳入KBS管理中那么我们就可以利用这种自定义API Server的方式去进行管理这种资源然后这种方式和CRD最主要的区别就是它这种方式更灵活更能够满足我们一些特殊的一些定制化需求比如说我们需要命令式的方式去管理资源或者是通过同步的方式去操作资源那这种方式是比较适合的我们把这种API对接完之后通过API Service注册到我们KBS中就可以进行管理然后最后一种管理的方式就是WebhookWebhook它可以在请求到达API Server之前的话可以对请求进行健全然后进行修改或者是其他的一些自定义操作由此如果我们需要通过Cubanated来管理一个外部资源我们总结一下我们需要做楼下试点事情那第一件我们说访定ABAG和用户组的这个关系我们需要通过ABAG去管理整个一个用户和资源本身的一些对应关系达对的难比方如果我是一个Saturn的Member组织受传我可以针对于我所管理的一些我想把请求进行一些扩容的工作那这时候我们要可以通过ABAG把和修马兴的资源的Edit传给传线付给我的SaturnOK那同样的如果我是一个Expressor我可以做一些资源的申请工作那这时候我们只需要把这个资源的quate传线付给我这个GOOP就可以那这是第一点那第二点我们谈的是说声明是要加低整个一个实现那本身Cube我可以通过加低去实现这些针对于一些外部资源的一些扩展那对于用户来说我们可以意识到正常情况下我如果去管理它申请它迅急那我只关心两颗4G可能5C进一盘零列操作系统但我并不关心这台机器运行在哪个机柜上或者是说具体物理上的一个运行状态因此我们可以通过声明式的方式比较显而易见地去构建的部分而后面的用户无关的逻辑也需要做一些高内锯的实现之可但是同样我们也应该也要意识到我们同样还有一类足球打比方我需要对一台迅急进行重启或者是说我需要去查看某台主机的Zetton Log这时候我们会发现这套模型很难通过声明式的方式去做一些具体的实现往往是一个命令行的方式这时候我们正常情况下我们就要通过一些资源的方式做一些API扩展但是很可惜就截止到目前为止本身Cuba的CRD里面针对资源的扩展其实还是非常有限的所以在这种场景下我们可以尝试如果有必要的话我们可以去尝试直接启动一个第三方的API Server之后通过资源的进一步扩展去扩展某些Kanata Post在懂不同的ATTB语意进而实现这些命令时的需求那最后一点我们说对于企业来说一些必要的流程管控是不可或缺的那传统的针对流程管控的更多是说我在前续环节上做这些事情也就是我具体的一些资源的申请资源的管理的一些请求我进入API Server之前我可以做一些前续的环节但是同样我们应该也要意识到Cubanated本身提供了一个非常完美的中偶核的解决方案我可以在请求经过API Server之后在落到ATTB之前我会有WebCode那通过WebCode的方式我是可以知道我当前这个特定的请求是特定用户针对于特定资源的特定操作那通过WebCode的实现我们可以与先判断这部分特定的操作要不要做一些预售权如果需要的话那我们只需要把这个特定的操作做一些拒绝的处理就划几个外部流程做一些必要的控制当然等对应的一些省批流程通过之后我们只需要把先前那些持久化的请求进行一些必要的回放即可由此我们就可以快速实现了一个通过CoupleNetX管理一个外部的资源或者是IT服务了那接下来我们快速看一下这个架构有没有一些潜在的问题我们可以看到我们自己实现了一个operator或者是一些对应的资源的controller那这个对应的controller我通过原始的Couple的API去访问到我所管理的这些Version Machine或者一些其他的资源的逻辑状态那同样呢我通过这个controller就通过它访问它原始的一些物理API获取到它的物理状态通过逻辑状态和物理状态的整个一个controller那我实现最终的一致性那也就是说在这个环节中我的operator本身是我处理这部分数据基本上是无状态的我的增三改的操作配合查询本身是能做到最终一致性的那这个大概我们可以看到真正有有潜在风险的地方在什么地方其实在真当图的上方也就是说在资源的存储层事实上我们不管是通过原始的CRD去通过Quber的那些原始的CRD的扩充的方式去扩充这些资源的管理还是我们自己启动一个第三方的API server自己实现一个外部的ETGD或者一些自定义的存储去实现的部分API的扩充那针对于存储层的可用性始终是这个方案最为薄弱的地方如果要提升这层的可用性我们看一下业界是怎么做的我们可以看一下传统的在KBS社区提供的我们几种高可用的解决方案首先我们看单级群测的话在KBS社区官方就给我们提供了两种首先第一种是KBS它的控制平面组件和ETCD用多副本的方式部署在多个节点上面这样的话可以保证它的节点可以在某个节点荡机的之后它的组件还能够正常运行它这种优势的话就比较简单当然它也有一些潜在的风险就比如说你荡机完之后它的底层存储和底层存储其实是有受影响的可能会数据损坏之类的所以它提供了下面一种架构方式把ETCD这种存储外置和组件分开通过这种方式的话我们可以降低存储荡机之后它带来的一些风险当然这种在单级群模式下其实比如说我整个机房荡机之后那这个集群其实就挂了所以在社区最近一直在讨论的是我们如何提高这个单级群下面的一个可用性那就是把单级群转成多级群的方式我们通过多级群的方式来提高应用的可用性把应用部署在多个集群上面通过多副本的方式或者是异地多火的这种部署方式来提高应用的这种可用性当一个地区或者是某个机房挂了之后我们其实还可以有另外一个备份的一个应用在正常运行可以对外提供服务减少这种荡机的损失当然还有一些像社区的一些组建像卡马达这种它通过控制平面来提供应用故障转移的这种功能当你一个地区的集群挂了之后那它自动会把在这个集群上面的应用转移到另一个集群上面去能更小的减少荡机的时间减少损失那么我们可以看到这个多应用多集群的这种方式的话其实它也是存在一个风险的控制面它还是存在一定的单点风险如果大家做过架构大家应该意识到高可用架构的本质是解决一个什么问题解决一个概率问题也就是说我通过同层组建的鲁鱼和上层的一个附载均合是可以显著地提升当前这个组建的可用性的但是由此带来的代价是什么不达性这就好比大家为了保护牙齿抓牙我引入了牙刷那牙刷的可用性怎么保证你说你铁纸铜牙 鲁鱼准备一个十把牙刷那这是一个方案你说现在比较高级有一些高科技的超声波牙刷清洁器帮你牙刷做清洁这也是一个方案可是这个引入了超声波牙刷清洁器它本身的可用性又怎么保证难道再引入一个超声波牙刷清洁器为超声波牙刷清洁器清洁吗如此层层套牙有没有更加贬乏的话要知道我们本身为了做这件事情的最初的一个目标其实只是为了在通过Kuber管理外部资源的时候去提升这一层的控制层的可用性所以在这个有限范围内是不是有一些更加贬乏的话要回答这个问题我们需要快速先回顾一下Kuber本身针对于加厉这类资源整个一个集成的一个流程我们可以看到当我的请求经过APR Server在落到ETGD之前我会经过两个Webhawk一个ValidationKuber内类本身提供两种Validation模型一种叫Vatating 一种叫Validation分别对应了资源的可写的预处理和解读的角叶我们需要注意到一般性根据对价实践我们往往要求这两层Webhawk的实现仅可能是期限密的为什么要这么做因为在后续的ETGD落地之后我在做对应的Controlation Operator或者Controller在做Controlation的时候会频繁地对管理的这类资源进行读写当然你说这个读写又会再次突发走刚刚那个路径去突发可能或者突发对应的Webhawk当然你说我可以通过一些技巧通过一些社会Counter我把这些特定的请求过滤掉那这里面复杂性又增加了这是第一点第二点我们可以需要注意到本身针对Controller或者是Operator的成了可用性是怎么去保证的呢目前我们的对价实践其实还是一个比较偷懒的方法我们会通过IT三代拜的方式做这个事情也就是说我会起多个Controller副本之后我可能是这些副本同一时间去抢某个ConfigMap或者是某些antation的所的服务如果抢到的话我是属于IT否则我属于三代拜OK那想清楚这两点想清楚这两点之后我们脑洞一下我们是不是可以简单点构建两个集群之后我的业务的Operator始终以IT三代拜的这种模式运行在特定的一个集群上而其他的集群的Operator或者是说当天集群另外副本的Operator组织三代拜的模式之后我们想方设法去实现这两集群之间我所关心的这类数据比如我刚说的温存保兴管理这种数据的装上的同步是不是就可以实现这个目标了也许你会说这里面还遗漏的一个环节就是一个很重要的用户前端提交或者通过这种命令行或者其他方式前端提交这个访问APS这个场景我们可以注意到这个场景其实跟刚Operator的遗志性保证有点像我的增三改的操作配合本身的查询其实可以做到最终的遗志性的所以基本上这层的实现我们只需要通过一些网络制作一些必要的ETM处理或者做一些复杂均衡转Fargic进一步打开来看我们可以去实现一个风布式的锁之后这个锁为两边的Operator主意ATF3.8进行一个锁服务之后我们去实现一个生产者的这么一个组件之后这个组件我去握持当前的集群里面我所关心的支援对象的这些状态当我对应的对象发生改变的时候我通过Q扔到对面集群由对面的行动进行消费之可当然这只是一个逻辑上的一个抽象概念但是真要实现这部分东西首先我们先要了解Qubinatis的本身对对象的版本移制性管理是怎么做的现在我们在社区中可以看到有人曾提出了一个有人曾提出了一个关于就是K8SAPI是否具有强益自信的一个问题那从而引发了一个我们对K8S的一个Resource Rossing的一个属性的一个探讨那它实际上是实现K8S就是一致性强关键性的一个重要因素之一然后Resource Rossing它允许多个客户端然后在进行支援操作时能够保证它的一个准确的一个工作并避免一些冲突和一些数据不一致的一个问题那在K8S中我们来看一下Resource Rossing和Generic它是怎么去进行工作的那Resource Rossing和Generic在K8S中它其实主要是用于并发控制和版本管理的两个关键属性首先针对Resource Rossing它其实是每个K8S就是资源对象的一个内部版本制服串我们注意的话它其实表示的是支援的一个版本号那这是一个它其实是一个单调地增的一个止毒的且集群内唯一的一个制服串它是有K8S系统自动分配和更新的一个制断就是当我们的支援对象进行更新的时候然后我们可以发现这个Resource Rossing它的值其实是地增的然后它可以表示我的这个支援对象发生了变化那因此我们作为用户我们可以通过来比较这个Resource Rossing的值来判断我的对象是否有没有变化或者是有没有冲突那K8S其实它是通过定义就是Resource Rossing来进行就是兵发乐观控制和版本管理的一个状态那就是在写入ETCT的时候那个Resource Rossing K8SAPS我APS我会对Resource Rossing进行进行它的值进行比较来进行那个数据冲突的一个检测当请求的数据和我们K8S版本中支援请求的那个版本号不一致的时候那我的K8S肯定会返回那个支援冲突的这样的一个错误那作为用户我们就需要重新获取数据并重新发起更新的一个请教那讲到这里的话那我们肯定会试考Resource Rossing它到底有谁来生成的呢它其实是基于底层的就是ETCT它的KV就是Revolving的一个版本机制进行生成的那支援对象每次进行Update的时候那它其实都会进行更新Revolving当你更新支援的时候那个ETCT它其实是根据自身的KV版本机制然后生成对应的Revolving和Model Revolving然后生成之后它会把这个值返给我们的K8S那K8S其实它就会根据Revolving来生成我们大家就是常见的Resource Rossing这样的一个字段返回给大家那其次针对这里的话还有另外一个属性就是GeneracingGeneracing它其实是一个表示对资源期望状态的一个序号它其实也是由系统生成的是一个单调的地增止读的一个字段它其实发生在它是有K8S生成的当你的资源对象的配置发生变化的时候Generacing的值会发生地增的这样的一个状态然后相对于Resource RossingGeneracing它其实更用于版本的就是用于我们资源版本表示生成而不是一些更加吸力度的一个管理因此我们通过以上可以总结出来可以看到K8S它通过对Resource Rossing的定义来进行实现我们的API抢一自信的一个关键然后它确保了我们对集群中的资源的一个并发操作是可靠的正确的且是一致的那通过Generacing来定义通过Generacing来管理资源的状态的一个序号来实现你对版本迭代的一个管理由此我们是不是又可以一样化葫芦直接构建一个跨集群的版本号呢接下来我们看一下如果要构建一个跨集群的版本号我们在哪环节加入可能是比较合适的一般性根据Cuba的套路我们往往会有三个地方有机会去做一些额外的代码处理第一个是说我用户提交的时候可以做这个事情第二个是说我再做Controlation或者对应的一些operator再做处理的时候可以做这个事情第三个就是Webhawk接下来我们快速看一下这三个点各有什么优利币我们可以看到如果通过用户提交的时候做一些额外的捐赠相版本控制的话首先用户提交可能会涉及到多个渠道我可能是通过命名行可能是有一些前端的UR或者处理等等这时候其实就涉及到多个渠道的代码补取了另外一点是从控制域的角度来说版本号这个事情其实是一个非常严格的事情如果把这部分东西轻易地外放到用户层面上让用户去做这个其实相对来说会失控所以第一个方案并不是最好的方案第二个我们说在有Controlation的时候做技术上完全可以做这个事情但是同样我们应该也要意识到一点就是本身根据Cuba的这些资源对象很多对象并不是孤立存在的有很多负责和引用关系达最简单的比方就由我们先前的谈的训议机来说我一谈训议机可能挂靠了一个磁盘我这个磁盘通过PV和PVC预备性出来这时候其实就涉及到至少四个对象这时候你如果通过硬带码去做一些版本的管理其实就涉及到很多硬带码的一些偶和相关的一些开发层面上的东西所以并不是非常好所以最终我们在维不后可层面上去做对应的跨机圈的版本号的加入接下来我们再来谈数据的同步刚谈到两个机群之间我通过Q做数据同步这个其实也是这个方案里面最为复杂的一个点我这里只是先简单提一下这里面需要涉及到点或者数首先第一个点是说刚谈到Q把很多对象有负责关系这个负责关系如果大家做过一些业务大码的开发其实大家应该意识到有引用关系的这些对象通过Q的时候在特定场面下会发生什么事情所以我们一般人会通过一些同时对列去做对应的处理第二个有Source和Subway Source因为维不后可的关系我的Source和Subway Source同处会被维不后可给handle到那这时候其实需要做一些区别处理第三个是说我的资源的删除如果大家做过一些Operator的开发甚至是说我们看本层demo的Operator的Operator的demo的其实大家应该也看到针对于资源的删除这一段其实会有一段单独的逻辑代码块所以一样的道理我们在做数据同步的时候针对于资源的删除和准备删除预删出这些环节我们需要做一些区别的处理最后一点就是说我的资源的集群可行刚刚谈到的有Source Welcome这个其实是一个典型的例子当然这些例子我们需要在做数据同步的时候去做一些过滤和一些区别处理为了避免我两个集群甚至多个集群在做数据同步的时候导致的来回TPU甚至产生了一些潜在的网络分报问题当然从方案的完整性角度来说必要的一些metrics或者一些model team对应的一些解决方案还是要考虑的打比方我们需要去考虑我的Operator的当前的组统所的一个状态我是要考虑我的同事对列的一个情况以及整个对列的吞吐量等等今天的技术部分的风响差不多告一段落了之后最后尝试做一下总结吧我们今天谈的其实是一个非常技术上非常小的一个非常小的一个点但是在这背后的一个逻辑和动机我觉得借这个机会可以简单给大家做一下风响个人思考也就是说主机场针对源源生的理解以及为什么会在这上面做一些投入我相信如今在2023年整个业界针对源源生的发展方向这个无终聚益了那这样同样的对于主机场来说是不是光去使用就行了回答这个问题我们需要看两方面那第一个方面我们谈说这里写第二点就所谓的我封闭的事务甚至是封闭的一些足够封闭的IT系统那随着时间的推议会逐步从有趣走到无序那我们说引入了一些外部的管理手段基础框架也好基本上是让它变Open或者是说让它去降伤OK第二个点我们说复杂性走很远的就是说我们的系统的固有的业务复杂性其实就放在那里 摆在那里当我引入一些新的技术方案也好开源框架也好让开发的效率看似提升了但是这背后的逻辑是说我的复杂性并没有屏空消耻而是下层到我所引入的这些框架也好下层的框架也好平台也好引入到这里那因此我们说主机场针对运营这个事情其实是有两个境界那我说第一阶段我们说运营那这里面运营呢我们通过引入了一些原生的标准化的框架也好专业化的一些能力也好那我将我的开发层面上的原先的一些能力逐步下层到平台层面上这样对开发来说我可以更加专注业务的成了实现就好比我们引入了Service Match我的开发只需要简单地提交几个玩玩苗大概知道Match怎么用就可以我把几个场景的Match如何怎么样用玩苗准备好就可以我不需要再像原先一样可能百分之六七十的开发都需要了解什么Spring Call的服务发现语约卡高可用原理等等数月有端工买这是第一点那第二点我们谈的是说鉴云那这里面谈的鉴云并不是说我完全推导同来之后把所有的东西都推成开源的或者怎么样而是说我借鉴云所带来的体系化和标准化去快速地做自身的减法我企业可以划条线那线以下的同句话已经标准化了那我可以交给友商快速地低层本地去实现这个事情那线以上的涉及到的体系能力和处理旁通的那我这时候可能友商未必能买得到那这时候我们需要做一些具体的投入那这里面说的投入并不是针对具体的某一个clownated project而是说云这件事情带来的体系能力和处理旁通能力就像打比方就像我们今天谈的通过Cuba的方式去管理传统的IT主要或者服务或者是说我们通过一些传统的应用高可用的方式去提升Cuba这层的可用性就是这个道理那说到底我们所做的这一切最终还是为了促进我的研发测的效率提升正所谓我们说打开门不再闭门倒车用业界通用的轮子把大家通的更远今天分享结束谢谢大家