第三届未来网络发展大会
网络全球 决胜未来
谢谢大家今天给我这个机会在这里跟大家分享一下我们UCloud包括在共有云领域使用交换机的一些工程一些实践上面的心得。首先我会分享一下可编程交换机的配置,然后会讲一下我们为什么会采用可编程交换机,以及我们是怎么去使用这个可编程交换机的。
其实大家可以看到我们的第一个场景,这个是我们2017年底和2018年初去研发的,在2018年的下半年已经上线了,主要是运用于混合云产品和转线接入的场景,这个事情我们为什么用可编程交换机做呢?其实有几个原因,最大的原因是因为我们用的是一个网络+E的封装格式,因为它的头不比VXLAN比较小,这个可能就会碰到MTU的问题。另外一个问题就是我们有很多DPDK的设备,这个DPDK的设备已经很多是针对封装的模式去写了,这个如果你把全部的DPDK设备权利改成OXLAN的话可能是一笔很大的开销。除了这个之外我们还有一个很大的原因,实际上是从控制面的角度考虑的。大家可以知道,传统的VTB在EVPN之前可能都是厂家专有的,他会自己写一个SDN,如果我们云厂商要和SDN集成的话,我们会调用北向的API,这个中间就多了一个适配层,我们要通过协议对它进行编程,这个中间是有一个设备层。另外中间多了设备层之后,它一开始就是到了厂商的处理中心,那么我就可能到不了这个数据了,那这个在实时性上就会有问题,这个就是为什么我要用可编程交换机做这个东西。
它实现的功能其实很简单,基本上就是L2交换3层路由,然后我在里面内建了INT的一些特性,然后结合DPDK,我基本上可以看到它里面交换机的情况,总的来说这个现场跑下来还是比较好的。
它的优点其实我们在开发这个的时候,我们在2017年9月份已经开发了一个实验,但是最后没有上线,而且在上线前我们把它推翻了,然后采用可编程交换机来做,其实最大的好处就是它的性能,就是对比DPDK的实现来看的话,它时延的优势是非常明显的。另外带宽的PPS、VPS优势也很明显,因为我们上一版做的时候是用UPS网卡做的,那么实际上在现有的网关的时候其实已经出现了向端口拥塞的场景了,也就是说它不是拥塞在我们DPDK转化性能上,而是拥塞在多打一的交换机性能上面了,那么我用可编程交换机,我可以用一个很低廉的成本,事实上它的成本比DPDK的服务器要低,特别是在基本上和25GDPDK服务器差不多,但是如果你要考虑到这个可编程交换机给你的是32个100G的口的话,你会觉得它的性价比还是挺高的。这也是一个原因,当然性价比不是我们最终的考虑,我们最终考虑的还是它的性能,因为我们线上确实是出现了这个拥塞的场景。我们现在用100G的线和口,我可以比较放心的说我上游的交换机也不会出现拥塞,我这里也不会出现拥塞。
上面这个第一个例子还是比较常见的。那么第二个使用场景就会变成非常非常的好,我们用它的来源做局域网接入的带宽的计费和带宽的控制。这个也许是我孤陋寡闻了,反正我是没有太看到有硬件是这样做的。那是什么意思呢?我不太这一台交换机,基本上80%以上的点用来做每一个EIT出路的计费,实际上我们的应用场景就是从共有云,从里面出来之后,打上OVERLAY之后直接送到英特网入口,然后在这个入口做一些带宽的控制。这个里面之前的版本实际上我们用的是LinuxPC做的,但是LinuxPC我们在实践中发现,其实它的多核的可扩展性还是有问题的。基本上在16核或者是20核以上,你会发现LinuxPC的性能有一个雪崩,会发现如果开到20核的话,你会发现性能还不如8核的使用场景,也就是说它的单机性能实际上会发生问题。然后我们会切换到OVSDPDK上去,因为OVSDPDK在2.8的版本就提供了这个功能在里面,但是实际上DPDK其实和上一个场景的问题一样,就是说25G的线可能会拥塞,但是你用这个100G的口,你又发现服务器的成本,因为你上了100G之后,配套的CPU档次就上去了,而且可能你一般来说,如果你要两个口的话,可能还要现在PCI总线可能也没有支持到100G,如果是两个单口的100G卡的话,他可能需要双路的CPU,那么双路的CPU的成本就更高了。所以我们会发现这个场景成本比服务器集群的成本要低很多,而且时延要好。第三个场景实际上我们是用它来做三层的负载均衡,其实所谓的三层负载均衡,也就是ECMP,那ECMP其实每一台交换机都支持,有的交换机还支持弹性ECMP,比如说到了一根线,然后把流量切到其他三根线上去。但是我们实现的是不一样的,我们实现的和弹性ECMP不一样的就是它的一致性哈希算法,它跟传统的弹性哈希比起来,它的好处就是说你这个服务器增加很多很多台,然后再去掉很多很多台,它还是能够达到一个比较好的效果。当然这里可能解决的一个最大问题还是说传统的哈希去掉一台的话会导致哈希错位,哈希错位会导致很多有状态的应用,它的TCP连接需要重建,所以一致性哈希是很重要的。但是另外一个好处就是说我们这个设备,现在它可以根据OVERLAY里面的HAD来做哈希,然后我不去改OVERLAY里面的HAD,我改的是UNDERLAY里面的HAD,最常见的场景比如说我根据OVERLAY做完以后改的是UNDERLAY里面的物理IP,这种场景其实传统的交换机还是比较难做的。
这个里面我们还做了很多其他的工作,包括刚才阿里云的同志也说到了,网络里面我们经常要在线升级,在线升级传统网络上的在线升级就很难做,而我们可以做的是在传统的哈希基础上做更高级的控制,比如说我来自与某一个租户的某一个虚机的流量,我就加一个覆盖的规则在里面,我说你就不要做哈希了,你符合这个条件了,你就给我去另外一个新升级的集群,然后通过这种方式,我把这个负载均衡器,其实就升级成为了一个灰度网关,然后来做一些更细致的控制。当然了,这个OVERLAY的格式和这个INT,反正一个场景最初的原动力都是它,但是出了这个原动力之后我们会发现,还有更多更多的使用场景可以去挖掘。这个使用场景是我们目前正在开发中的一个使用场景,我可以用可编程交换机来做智能网卡所支持的OVS、TC Flower和Datapath,我们其实可以在可编程交换机上去实现这个OVS、TC Flower,然后它实际上在过去的交换机和OVS之间其实是有很大的鸿沟的,基本上你可以发现,你为OVS写的OPENFLOWER流表是没有办法跑到OPENFLOWER上去的,所以我的原动力基本上就是这个。
接下来可能另外一个方向也是我们在预研的,但是我们还没有开始启动,基本上就是说把这个可编程交换机用在Tor这个场景,我们也评估了一下,像SONIC这样一个分层的架构,其实如果我下面是可编程的,那就意味着我每一层都要去改,所以改起来还挺累,可能Stratum和P4结合的更紧密一些,所以可能更容易定制,所以目前我们在SONIC这个阶段还是在观望的状态,看看在中间选一个更合适的。
好的,上面其实我们也是分享了一下我们的一些应用场景,其实我总而言之总结一下的话,就是说基本上就是二三层你没有状态的业务,你能够想的,可能用可编程交换机,也不是说百分之比,我觉得八九成应该是可以实现的,区别就是实现到什么程度,因为硬件上的资源还是有限的。就像刚才我们说到的SRv6,这个标准化可能三年半,然后互操作性等等还要花比较长的时间。那么可编程交换机给我们带来的最大好处就是闭环,我基本上从有想法开始,然后到我把它写处理,到我去上线,基本上我们的团队没有多少人,反正自己都可以搞定。
这个是我们UCloud的虚拟网络转发面的演进史,其实2012年也就是缘故时代了,它可能就是和阿里云的经典网络差不多,那个时候是EBTables和IPTables,2013年的时候我们就使用了OVS,当然Linux内核其实也是支持的,然后2015年,我加入UCloud之后,陆陆续续的开始做了一些DPDK的网关,其实我本人是软件工程师出身,然后就开始做DPDK,然后做可编程交换机。然后2017年开始,我们在主机上开始走SmartNIC这条路,然后逐步逐步的就把很多无状态的应用往可编程交换机芯片上去移植了,从2017年底就引入了很多很多的应用。在这里我插一句,就是SmartNIC,这个基本上我们已经是应用的蛮多的了,基本上我用的这个是属于可编程的ASIC的场景,就是说它的性能还是比较高的,但是可编程性很差,为什么呢?因为我们现在比如说我为了让它去支持我们的方式,我也是求了他半天他才答应帮我做,然后我们才能用上它的卡。那么如果是众核的方案呢?可编程性其实是挺好的,这个我们其实也测过一些类似于智邦的场景,它是纯ARM扩展,大概就是16个2.2G的ARM口,但是测下来发现比较差,可以说是和DPDK性能差不太多。但是FPG有爱一个很大的缺点,价钱实在是贵,功耗也很贵,然后NP其实总的来说各方面都是比较均衡的,但是据我们所至,像华为什么的有很多是在用这种场景的。然后纯ASIC的卡就是说可扩展性太差了。所以基本上我们现在在SmartNIC领域,基本上走的还是可编程ASIC,但是我这个东西其实也没有什么扩展性了,我就是智能网卡能支持就OK了。
这个PPT我主要是对比了一下DPDK和Tofino的特性,基于DPDK做的就是两个20G到100G,Tofino就是64个100G,PPS就是差一个数量级了,这个是一个核5兆PPS,我做20个核,大概可以做到100兆左右。但是CPS这个,可编程交换机上的CPS是什么呢?我指的是下流标的速度,或者是下规则的速度。这个对DPDK来说其实是很快的,因为它的架构是一致的,组成访问一下就可以了,但是对于交换机芯片来说这个就比较复杂了,因为你这个规则从远程过来,然后先要到CPU这边,然后放在内存里,内存处理好了再DMA下到交换芯片去,这个时间还是比较长的。基本上我们现在测下来大概是两万数量级的样子。所以你要是碰到类似于做扩展均衡,你每一个连接都要上CPU去做的话,其实实用的程度还是比较差的,因为你CPS也只能做到两万,所以基本上我们做到三层负载均衡就算了,做四层还是比较困难的。时延又是好几个数量级,这边是毫秒,那边是微秒。当然缺点也很明显,你这个DPDK的内存是按G算的,这边是按兆算的,所以最终我们的结论就是说DPDK适合有状态的业务。无状态的,或者是状态比较少的可以用可编程交换机去做。当然,还有其他更高级的用法,比如说通过IDMA去扩展它的内存,这个反正我们还没有开始引入使用,因为我觉得这个需要投入的还是比较多的,所以我们团队暂时没有在这方面做努力。
刚才我也说到了,在我们调研可编程交换机之前也花了很大的力量做一些OPENFLOWER交换机的研究,结果我们发现,这个OPENFLOWER交换机兼容性还是挺差的,基本上你OVS的流表是没有办法跑到OPENFLOWER的交换机上的。为什么呢?其实和芯片有关,所有基于博通芯片的OPENFLOWER交换机,他都是按照博通所定义的标准来做的。换句话来说,这个标准其实和OVS的转发频率是有很大差异的,实际上OVS无的流表可以写的很花,比如说我们团队,我们团队就写了一个类似于叫结构化流表,什么意思呢?有一点像结构化编程,换句话来说,我可以从一个表跳到另外一个表,有点类似于我结构化表里面调用一个字程序一样,我把这个参数设在这个里面,然后到这个流表里,然后去查找,然后再调回来,就是这种流表你放到OPENSwitch就解决不了这个问题。
接下来可能就是一些更细节的信息了,就是说我们怎么去做,这个是我们2017年底的做法,那个时候基本上还是P414的时候,基本上我们整个组网的模式其实和DPDK差不多,我们在可编程交换机上面放一个接入交换机,然后这个可编程交换机的网关就只到这个交换机上,然后我们会把交换机芯片的认为是网卡芯片。我其实实现了一个很简单的网卡的转发逻辑,并没有去实现一个非常复杂的交换逻辑,我们做的其实就是一个自动网卡的方式。基本上可以看到控制面的所有报文,比如说ARP、Ping等报文,我们是通过Linux协议去处理,然后通过Netlink写回到交换机里面去。然后我们进来的时候我们会判断,如果他是一个OVERLAY的报文,我们就通过BGP协议去处理,如果是UNDERLAY的报文基本上就是全部交给Linux协议处理。另外值得一说的点,就是在P4-14的时候,这个时候它其实是缺乏批量处理的API,就导致我下一条流表,我要等这个流表出来,性能远到不了两万这么高,基本上也就是几千的数量级,所以我们自己在Switch里面自己做一个插件,然后通过我们自己的协议,把这个数据传给插件,后这个插件再调P4程序声称的SBK,把它写到交换机芯片里面去。同时,我们会在交换机的CPU这个里面,通过Zebra接口,来远程配置虚拟网卡,创完这个虚拟网卡之后,我远程通过Zebra接口来配置虚拟IP,然后通过Bgpd接口配置这个虚拟路由,基本上你把这个网卡插进去了,我们就可以自动把这个配置起来,把整个的UNDERLAY的网络跑通。然后所有的OVERLAY的处理我就通过GRBC把这个流量下发下来。
这一页其实是Barefoot到了8.4的时候,这个里面有一个Barefoot的Runtime,而且它的有关了一些新的特性,这个新的特性还是挺有趣的,这个时候他有一些新的特性是什么呢?就是说它这个交换机都有好几各Pipeline,每一个都有它自己的内存。我们做了一件很有趣的事情,我们给不同的Pipeline跑不同的应用,这样不同的Pipeline上面的P4转发面就是不一样的,所有下来的转发面的数据也是不同的。那么具体是怎么做的呢?我这里有两个颜色,绿色和蓝色,这个实际上是两个应用,他都会调用这个Barefoot的Pipeline接口,来下这个表,但是下的时候他会指明他是Pipeline几,这个时候他下的数据就只会写到这个Pipeline里面去,同时这个Barefoot给你的程序也是不一样的,但是可能Barefoot这一点还没有做好,就是说你这个程序必须同时下下去,就是你两个P4放在一起便宜好了之后,然后你可以远程请求把两个同时下去,这个两个的逻辑是完全不同的。在控制面我们是怎么做的呢?实际上前面我们说了,我们每一个接口,实际上我们都会创一个虚拟网卡,不同的Pipeline,它对应的物理的网卡和虚拟的网卡是不一样的,那么我们把虚拟的网卡放到这个里面去,其实有点像VRF,然后我把我这两个程序放在我们自己的控制里面,是两套独立的控制面,这样就可以跑在一太交换机上,也许你可以称之为是交换机的虚拟化。当然了,目前我们线上,我们也尝试了很多种用法,一种用法是跑一个程序的两个版本,然后我在升级的时候,我从这个老版本升级到新版本,另外一种用法就是我跑两个完全不一样的应用,基本上我们在线上都在试。当然处于一些不同的考虑,因为如果你跑两个完全不同的应用,我们那个系统管理员它很郁闷,他说你这一台交换机在CMDP里面到底叫什么?后来我想想,算了吧,还是跑一个应用的两个版本吧,反正我也要搞两台设备,这样的话管理起来就会稍微方便一点,但是怎么用还是取决于你自己。
这个其实是我们前面说到的第一个场景,VPC的一个场景,前面也说到了Tofino的TCAM和SRAM是有限的,新的便宜其指出Pipeline的串联,这样你可以拿到更多的内存,但是这个串联怎么做呢?其实很简单,它就是你这个端口进来处理到Pipeline最后的时候,然后进去以后又有新增加了一倍的资源你可以用,但是代价就是你接线的物理POT就少了,你本来是32个100G,但是你用了串联之后就只能用16个100G,但是能够取得的就是你每一个应用的资源就更多了。当然这个可能还不够,还不够怎么办呢?我们也考虑到了可扩展性,我们就是类似于数据库的点,我们根据业务就做了一个切片,在前置的,我们这个前置的设备其实是一个64口的可编程交换机,然后下面的这个是32口的可编程交换机。当然,我内存不够嘛,我会怎么办?我就在这个64口的交换机下面接了很多台小交换机,但是因为在我这边举的例子里面,我其实每一台交换机上连是3个100G,我下面就接了18个分片,然后我上面就根据业务,比如说根据租户,对我们来说最直接的就是根据不同的租户去不同的分片。另外一个额外的好处就是说我可以做灰度发布,比如说你可以看到我17、18是用来做灰度发布的,我要升级的时候我就先升级这两个,然后可以按照租户、按照虚机,然后在这个里面下策略,然后把它切到新的灰度的上面去,然后实现一个灰度发布的作用。
最后一点,就是说可编程交换机这个玩意儿还是一个挺新的东西,不可避免的会有很多BUG,大家可以看到Tofino的SDE基本上6到8周都会发布一个新的颁布,每次发布的时候我们都会纠结要不要上新的版本,怎么办?因为我们团队大多数都是做DPDK出身的,基本上我们的思路就是用软件的方法去解决,我们会写BDD,做很多单元测试,然后我们采用godog方式来写BDD测试,每次测试的时候我都会推送一部分数据到交换机上面去,然后我给他发一个测试的报文,然后测试的报文里面我指定我的IP口是255,然后你看它处理到最后一部分的时候就把这个包再送回来,这个时候我测试的口径就收到了,然后我就检查看看我这个里面的OVERLAY报文设的对不对?然后UNDERLAY的报文对不对,我在这个报文里面我会把之前的原始信息放到这个里面去,这个时候再和预期的结果去对比,然后发现这个情况怎么样。后来用了一下,发现这个方式还挺好,好到什么程度呢?好到我们上线之后,也在用这个方法去测试,怎么测呢?为每一条转发面的数据都生活一个测试的报文去测试。大概三十秒测试一次,三十秒验证一次整个交换机里面的数据和我数据库控制器里面的数据是不是一致。线上跑下来确实不错,还是发现了很多问题,当然很多问题不一定是交换机的问题,交换机的问题说实话没有那么多,很多是我们控制面的问题,比如说没有及时的把数据下下来,或者是没有及时的把数据同步,或者说这个版本的不一致,然后导致这个数据下错了。现在在线分钟级别的话,就是三十秒到六十秒的力度,分钟级别的测试成了我们现在线上保证可编程交换机正常工作的一个利器了,可以对全量的数据做测试。另外还有一个就是我们根据Snapshot API开发了远程诊断工具,但是我们发现最有用的还是全量数据测试,因为它测的不仅是可编程交换机,他实际上测的是整个控制器是不是有问题。
好的,我的分享就到这里了,其实只是一些很简单的可编程交换机应用的一些体会。也是抛砖引玉,希望社区里面能够更活跃一些,然后涌现出更多的用例,然后可以大家互相交流。谢谢大家。