中CNI Migration的一些我们的研究和想法大家都知道这个Cubanitis的网络它本身就是一个非常复杂的主题也是Cubanitis正常运行的基础而CNI它是Cubanitis网络的基础因此我们首先会先花一些时间简单讲解一下Cubanitis网络和CNI的一些基本的背景然后会简单介绍一下和用户会有切换CNI的需求再次基础上为大家介绍一下CNI Migration的基本的原理也就是这个NATO的approach然后最后会给大家分享两种能做到CNI Migration的两个方面吧第一个就是去解决它是由泡的网络秘密空间中的本地的这个完美之后来解决的第二个问题是泡的与泡的之间的通信问题这个问题的解决就是由我们今天的主人公CNI Plugin来解决然后这个四层的服务与七层的Ingress的问题它们这两个问题的解决是在泡的可以通信的基础上然后我们加上Cubi Proxy的功能或者说Ingress Controller的功能得到解决最后是泡的Egress的问题这个问题一般来说大多数情况下也是由CNI Plugin来解决其实我们看到有这么多非常基本的方方面面但是它最基础其实就是泡的之间的通信问题因此我们先看一下Cubanitis这个泡的networking它是怎么去解决的简单来说泡的networking它可以总结为以下两个方面的问题一是通过这些不同的网络虚拟化的技术把各个泡的网络命名空间它连接起来解决它的二层的互联问题第二呢我们在这个图上我们可以看到这里面的图它就是利用了WizPair和Bridge作为了连接手段解决了这个二层的互联问题第二呢就是通过一定的泡的IP的管理机制就是常说的IPIM然后我们对每一个泡的网络命名空间分配上IP地址并且在主机上通过一定的手段然后我们去维护到别的主机的自忘的路由这样的话就解决了三层的可达性的问题在可达性的问题上可以通过networking的方式也可以通过overlay的方式最终实现不同主机间的泡的之间的通信所以我们看到其实我们要解决的就是一个二层互联的问题以及一个三层可达的问题我们就可以把同一主机上的泡的与不同主机上的泡的通信问题全部解决然后我们知道了要解决什么样的问题其实这个工具是什么就是我们常说的CNN platin在一个正常的一个CNN solution中它一般会包括两个组件一个是CNN binaryCNN binary它就是负责去实现互联的问题它会为泡的所在的网络命令空间去创建它的网卡然后它还会有一个搭配炮制的一个长期炮制的一个地门它的基本职责就是去解决互通的问题它会去创建和动态的管理它所在的主机上与别的它所在的主机上的路由表我们看到这个Binary它都会有一个config文件对应的config文件这个config文件是container runtime它去创建创建泡的时候它会去读取config文件然后对它它这个文件里会对CNN platin会有一些描述它会找到对应的CNN Binary进行调用调用它然后为泡的网络命令空间建网卡然后这个地门除了最基础的这种管理routing的这种这种功能其实它还承担着其实更多的职责在一些比较丰富的那种CNN的solution中它其实还有可能会存在一个controller去提供更多丰富的网络功能这是一个我们总结的比较经典的这种CNN Binary和Dimm的这种架构图吧但是因为就是时间关系我们今天就不能再去展开讲过多的功能了但是基础的功能其实就是刚才我们说到的这个Binary去处理它的互联问题Dimm去处理它的可谈问题在我们产品长期是不同CNN集权的管理过程中我们会发现用户会因为以下的原因会有切换CNN的需求比如说这个CNN Plug-in它在某些方面它有Limitation它性领上会有一些问题或者说它缺少一些商业上的支持还有一些Plug-in的它的社区不是特别活跃我们闷吞起来非常的麻烦还有现在就是有很多新兴的CNN它有非常更先进的feature用户都会嗯就是想去试一下那么就是有了这样的需求我们就就去思考就是我们怎么去做这件事情呢一般来说就是两种办法第一种就是很简单那我们就是用户你去创建一个新的集群那你装上新的CNN然后呢你把你的workload从老的集群上迁移到新的集群上这个方法就是很简单但是动于用户来说它呢需要去做workload的这个backup restore然后它需要去它需要能承担它需要能接受就是一定时长的这个服务的当time同时你的这个Kubernetes的这个管理的平台你要有管理多类型集群的能力第二种方法就是我不需要去建新的cluster我直接在我当前的这个cluster我给你直接convert的成你想要的那个CNN那这种方式的话操作就是会更复杂一些然后风险也更大但是对用户来说就是对他们来说很方便如果这个feature就是这种的话就是需要比较完备的这种调研以及实现工作如果feature做得好的话用户是愿意去用这个事情然后因为这样的话他们不需要再去做这个workload的迁移今天我们就重点就是看一下这个inplace的CNN migration在以后的集群上我们先看一下它的基本的原理从一个节点来看从一个节点来看这个原来是flano它装了flano的Deeman以及flano的Binary然后所有的pod的网络都是由flano来解决最终我们迁移成安雀首先我们会把这个节点上的workload全部准掉然后我们把老的CNN installation包括Binary 包括Deeman包括他们工作过程中生成的一些interface和device都都删掉比如说Bridge和Tanel interface都删掉然后我们把新的CNN installation包括它的Binary它的Deeman安装上最后我们在这个node上把它之前的pod重新recreate在k8s的这种环境中就是把它再re-schedule回来就可以了然后所有的pod会重新生成然后它的网络就是由新的CNN来提供这个就是最基本的过程就是对一个节点来说这个CNN的替换过程那么当这个过程放到多个节点的时候会有发生什么样的情况呢就是多个节点的时候我们就是一个节点做刚才说的那几步我们有四个节点那么先把第一个节点convert的成安全然后接着第二个第三个第四步就是rolling update所有的节点那么在这个过程中我们会发现除了第一步和最后一步它是由同一个CNN在管理中间的这个过程中它一定是由几个节点一部分节点它是在用新的CNN然后有一部分节点它一定是在用老的CNN在管理它的网络就是这样的过程它会有什么问题呢我们会看到它生成了两片网络区域这两片网络区域它会有什么问题我们直接就把结论告诉给大家就是就是说当这个pod它是落在两个网络区域上到这个pod它会出现通信问题它是无法沟通的那么pod出现了通信问题而这个pod它其实pod的通信其实是Service和Ingress访问的基础所以进而这个Service和Ingress它也会有服务的Done Time这样就产生了我们所说的Done Time那么这个Done Time它产生的原因就是说两个NATOG Partition为什么会造成这个问题然后呢它有几个影响的因素第一个就是两种CNN那么你可能你用了不同的Node IPame然后呢Node IPame还设置了不同的Cluster Sider这个Node IPame指的就是说一种机制我从这个大的这个Cluster的这个Sider中向每一个节点分配一个Subnit之后这个Node这个节点上所有的pod的IP都会是来自这个小的这个Node的Subnit就是这个Node IPame是做这个事情然后呢第二个就是他们主机间的这个pod的这个通信问题呢它可能用了不同的这种模式可能是用的NATO的柔挺或者说用的Overlay的方式但即使它这个两种CNN它用了同样的Overlay的方式它可能会用不同的封装协议比如说我的Flyno就用的是VXLAN的协议Android用的GNU的封装协议就也会产生这样的问题又或者说两种CNN它用了同样的封装协议但是它的那个服务端口也不同就是也是会造成类似的问题除非这几种因素完全相同那么除非这几种因素完全相同否则生成的两片网络区域它是一定会生成的两片这个网络区域它会因为两种CNN它配置的不同并且它没有办法知道对方的这个网络的信息会导致产生这个POD的通信问题我们就是直观给大家直观的看一下这个东西我们为了简化分析我们今天就定义我们欠一钱后的两种CNN它使用了不同的Node IPIME例如这个Flyno它使用直接从etcd去分配Node subnet的这种机制然后呢安雀亚呢欠以后的安雀亚它是使用Controller Manager去管理自己的Node IPIME然后呢它欠一钱后Node IPIME的Cluster大Decider也有了变化大家在分析自己的这种CNN的组合的过程中如果是因为别的因素的不同也可以按照刚才的就是我们之后会介绍的思路去分析会得到类似的结果我们看一下泡的的这种communication它会出现什么问题这两个这两个节点已经欠一成了安雀亚这两个节点呢还是Flyno那么这这两个安雀亚呢它是没有办法知道这边Flyno节点的这个subnet是什么自然也就没有到他们的路由同理呢Flyno这边的节点它也是没有办法知道新生成新转换的这两个安雀亚的节点的路由是就是subnet是什么它也没有到他们的路由因此如果你这个时候你从这个泡的1A你想去访问比如说泡的2A或者泡的1B都是它自己这片网络区域它这个包是可以通过正常的转发路径转发过来的但是如果你要去想去访问Flyno这片区域上的任意一个泡的它都会因为不知道到他们的路由是什么会把包丢掉那么同理Flyno这边如果有一个泡的想去访问安雀亚这边的一个泡的它也是会有会因为同样的原因它会把这个包丢掉但是如果它访问自己这片区域上的泡的它是也可以正常转发过来的然后这是Cluster IP Service的访问我们都知道Service的访问其实最终它会被数据平面的规则它会被转化成它后端的泡的IP假如说我们泡的EA想去访问Service1Service1的后端它有三个泡的泡的EB2A和4B假如说泡的EA想去访问Service1然后Service1被数据平面的规则假如说是转换成了泡的EB泡的2A那么最终对Service的访问它会转换为一个对泡的的通信问题如果如果被转换成了这两个泡的那它对这个Service的访问其实最终就是对这个泡的的访问它是最终是可以拿到响应的但是如果就很不幸它转成了这个泡的4B那它对这个Service的访问就拿不到这个响应了那么同理从Flinow这边想去访问一个Service比如说Service2然后呢它会这个Service2的Backhand泡的是这三个然后如果被转成了在访问这个Service2的时候被转成了这两个泡的那它是可以拿到响应的但是如果被转成了这个泡的它拿不到响应就是这个的分析结果我们其实可以看到适合这个适合这个泡的的适合这个泡的Communication的分析结果是一样的原因是什么呢就是因为这个对Service的访问本质上也是泡的的同性问题它最终的原根原根目的最终是会转换成泡的那么后面的这几页图呢都是不同的对Service的就是不同的方式去访问Service或者说去访问不同类型的Service的分析甚至是Ingress的一些分析因为时间关系我们没有办法就是一夜一夜给大家过这个图如果大家有兴趣可以之后就是看这个这个slide就是通过刚才我们的分析其实我们可以就有了一个结论就是说这个CNI in place的这个migration它确实它是会带来就是那talking上的Dontime的包括对这个泡的连通性的DontimeService访问的Dontime还有Ingress访问的Dontime就其原因都是因为这个服务它最终其实它依赖的都是泡的的通信而泡的的通信它这个源和目的如果落在了不同的这个network partition那它的访问就会失败如果落在了相同的network partition它的访问就会成功虽然我们刚才看到了很多种类型的Service以及Ingress就是我们不管它是怎么去做这个访问也不管它是多么fancy的Service或者Ingress的实现它最终都是最终都会转化成泡的之间的通信所以呢这个Dontime我们去说这个Dontime的时候就是它在所有的节点RollingUpdates的过程中就是一定会产生Dontime那么最坏的情况就是我在整个过程中我每次的访问这个源最终转化的这个源和端口都落在了两片区那么这个Dontime就会持续整个这个RollingUpdates所有节点的事件刚才就是介绍了说我们这种做这种inplace CNI切换的话它的基本原理以及这个源就是我们基于这个基本原理的分析我们知道了它为什么会产生Dontime那么就是我们肯定会想就是我们能不能去克服这个Dontime能不能想一些办法第一个我们会思考的思路就是说这个Dontime的产生是因为这个源和目的它落在了不同的这个Network Partition那么我们能不能在这个过程中我们把所有我们使用一定的控制手段我们把这个所有的炮的都控制在放在同一个Network Partition那么自然而然也就不会出现我们刚才所提到的那个Dontime了另外一种就是另外一个思考的角度就是我们是因为产生了两个Network Partition这两个Network Partition互相不知道对方的网络的一些knowledge那么我们能不能想办法就不让它去产生这个Network Partition我们我们尝试就是说在一些节点上在节点上我们去安装在一些可能会产生Network Partition的阶段我们在这个节点上去装上这两种CNI装上两种CNI之后那么节点与节点之间它是永远会知道对方的网络信息的这样的话其实就不会再产生Network Partition了就是这也是一个可以去实践的一个方向然后我们就就沿着这两个两个想法去进行了一些实践然后会有李安昭来帮我们介绍我们的实践和结果接下来我介绍一下就是这两种Live Migration的方法就是在我们的然后首先就是我们那个介绍的第一种方法就是那个我们采用的就是Node Group就是我们贪图产品里面有定义了一个Node Group也就是说有一些相同属性的那些Node我们呢就是根据上面说的那个Network Partition我们可以理解Node Work Partition一个网络区就是在同一个属里面的这些Pout是可通性的那么就说那有了这个概念的话就是我们可以有两种思路就是这种方法我们可以提供两种思路去做远达第一种的话就是很简单那么我们就是采用出来另外一个Node Group然后跟它一样的大小那这样的话就是说在这个新的这个里面我们就是我们是Eflano这种的话就是第二种我们做Antria这种它没有workload那么然后呢就是我们把这些workload然后通过就是然后我们这样通过Datent的这种形式让k8s让一次性的把这些workload牵述到这里就是到Antria的这边这是在第二步然后呢就这种方法就是说可以看到就是说我们就是不让它中间就是一个一个的migration存在这种Node Work Partition的这种这种两个node然后呢就是说从而保持了它的这个pod communication而这种情况也很那个它的问题来的就是说我们需要我们需要speal出来就是通通大小的这个Node Group对这个s 层的资源就是要求比较高那么当然如果没有这种足够的这些那个足够的资源的时候那我们就考虑第二种方法第二种方法就是我们可以我们可以就是说在现有的这种Node Group里面我们不断的改变现有Node Group的大小然后压缩一下现有泡的所在的这些node然后让它们保持在同一个这个Node Partition里面然后再做迁移它跟这个传统的这种一层一层的就是一个一个node的这种Rolling Update其实一致的只不过我们在中间做了加了一些tent当然我们在做这个之前我们也可以可选择的就是说先增加给你的资源的数量先增加一到多个这种这种节点那么它的思路也很简单就是最开始比如说最开始的话我们这是Flinno的然后我们Rolling一个但是打成tent的那么这样的话就是剩余的是在这儿在这儿运行然后直到什么情况直到是一半一半的时候一半一半的时候这时候我们一次性的做这种就是打tent然后可以把s把它签过来然后通而来保持就说然后接着的话就是再Rolling Rolling的那么这时候它也是一个一个的进行Rolling Update那么就是一个人是基本的Rolling Update这种就是Node Group的这种形式那么这种的方法就是说总结一下这种Node Group的方法的机密原则就是让泡的适可处于同一个网络区那么代价的话就是你需要计算好相应的s资源来承载你的泡的然后方法其实比较简单直观的那有一点注意的话就是相对于之前的那些那个Native的方法就是说它需要一次性迁移泡的这些操作那么这时候就是说可能会有一定的这种就是根据你的泡的那个大那个量包括是不是有PDB有PV这时候有一定的耗时在时间中的话就是说根据客户的需要就是说我们可能就是说有一些特殊的work load比如说他不跟别人有交流我们这时候可以提前给他们做就是一部分做真正性的一个定制然后然后另外一种方法就是说我们就是探索的是利用Multus就是说除了让就是说定制的方法让泡子在同一个Native的互爬认识里面我们思路就是说就是不产生Native互爬认识然后呢让Node同时可以看到两个CNN的信息然后呢就是Multus他支持CNN的就是按讯的就是多个CNN按讯的那个共同工作那基本思路就是这样的就是说最开始呢最开始呢我们是最开始是最开始Node上只有CNN-A然后呢我们切换着MultusMultus里面然后做了两个CNN一个A和B然后A主B-Fu然后切换一下它的顺序B主A-Fu最后呢就是E除A只剩下CNN-B整个过程主要改变的就是CNN-Banerade主要就是主要是切换了就是CNN-Banerade那个CNN-A的那个配置文件前面讲了就是那个改变它的那个优先级然后让让某个CNN发挥作用那么我们去分析一下就是在这种情况下尤其是在切换的时候然后它如何保持数据联统性的然后我们那个先简单介绍一下过程就是这是一个Node为例子就是最开始的话就是一单个Node的话我们只装了一个CNN-A然后我们另外Flinocluster然后呢然后我们接着就安装Multus和Antria这是我们装了两个CNN-A但是呢我们会配置一下就是这个Antria的CNN-A就是让让其实是让这个MultusMultus发挥作用Multus它们的配置文件里面呢我们是定义的就是主要的是Flinocluster是Antria然后呢就是说就是在这一个节点上我们recreate这些炮子然后呢这时候呢就是说这些那个炮子的话它就会持有两个两个那个interface就是然后第三步的话就是我们做这个就是通过更改这个Multus-CNN-A的配置然后改变它那个CNN-A的这个就是主副顺序然后那个就是Primary变成了Antria然后就是Flinocluster然后这时候呢就是recreate所有的炮子那这时候呢就是说那个炮子里面的interface其实还是一致的一个Antria创建的一个是Flinocluster给它创建的但是相应的就是因为主副不同可能他们的默认路由啊路由稍微有点改变然后最后一遍最后呢就是说这时候切换成Antria为主之后第四步就是切换为FlinoclusterFlinoclustersorry切换成Antria然后呢就是让Antria应该法会作用然后从而最后就是清理工作嘛清理的话就是说最后是清理的话你需要清理到Flinocluster也需要清理到Multus然后同时比较重要的是你清理到就是说他们创建的那些interface那些路由就是你需要就是说你清理网络设备的时候相应的路由就被清理掉了就是说因为我们直接删除Flinocluster或删除Antria或者删除Multus它里面的那个那个网口就是说有可能会有遗留然后呢这是了就是一个比较大的一个一个一个图就是多个节点的情况下然后呢整个签议的过程就是我们看一下是如何保持联统性的图就是我简单说一下吧就是我们是以Flinocluster到Antria为例黄色代表的就是Flinocluster我们就是33对这上面没写是吧我忘了写就是在这儿了太小了然后呢就是Antria的这些网络然后最开始了就是说是一个都是Flinocluster那很明显它是可以通信的然后第二阶段了就是如果是第二阶段我们切换成Multus如果是切换完成了都是Flinocluster为主Antria为次那也可以通信那么切换的一半的过程中比如说有一些class的是Flinocluster还没有完成切换叫not converted另一半就是已经切换成Flinocluster加Antria这种形式的话其实所有的通信即便因为AntriaFlinocluster为主可以通信的这也很清晰然后第三个步骤的话就是说我们就是去切换它的order从Flinocluster变成AntriaFlinocluster那么就是如果完全切换完之后完全切换完之后呢那么就是Antria都是为Antria为主那么通信很明显但是呢如果就是有一半是Flinocluster另一半是AntriaFlinocluster这时候的通信就会就是这时候的通信的话就是说就是说是就是是有一个那个小技巧就是需要做的话就是这时候就是说我们在就是从这个FlinoclusterAntria的Flinocluster这时候回报的时候我们会发现就是有一些那个它的那个包它在那个Antria的那个那个那个interface它被丢掉了这时候呢我们发现就缺少那个转发的过程这时候我们加上IPTB这时候让它那个就是然后两个设备之间这时候就是只有这一点就是说可能需要注意在切换order的时候因为就是包的内部那个内部路由的那个那个改变所以就跟这是这是当然这是细节问题就是说这是第四步那最后一步然后我们切换到这个从Motors切换成Antria然后就是那都是Antria的话那就是通信的问题就不存在就是就是那肯定都是联通了那么它整个的这个思路呢就是说整个的思路它也是就是一个一个的Rolling Update就是比如说从Stab1到Stab2它也是一个一个的做的它不存在就是我们上一个思路上面介绍的那个依次性把所有workload前移到另一个就是另外一大片区里边过这个过程它就是更像一个就是普通的升级一样就是做一个Rolling Update然后呢就是这个方案的好处很明显它没有就是所有workload的同时前移然后呢就是简单的通过单个几点的就是Rolling Update然后同时保持了网络的时刻的联通性然后不过就是不但是没有完美的方法就是也多了几次的powder recreate然后呢还有一些就是当然因为Miles本身现在你两个CNI那你肯定要不同的NOTE IPAM不然的话一个powder里面不同的网口不可能对然后整个CNI就是整个这个过程其实是比较清晰的但是就是我们这里介绍的是Fulano的安吹亚如果因为就是我们的产品最开始用的Fulano后来就是引入了安吹亚就是但是如果你要涉及到其他的那个CNI的这种这种迁移的话你可能要分析那个CNI迁移的这种联通性就有这样类似这样一个图然后看看是不是要在做做动画的时候是不是要做加一些规则这里主要就是介绍一下这几种我们的方法然后就是这样好