大家好 我是来自英特尔的徐义周然后今天这场就分享是由我来自英特尔和来自林确银的刘用欣同学一起提出的然后我们这个演讲的主题叫不受CNN限制的EBPF网络性能加速器然后今天我们主要会涉及的一个方面就是说首先会讲一下KBS当中目前存在的一个TZPIP协议站的一个开销问题然后接下来我们会介绍一下EBPF还有它的一些背景知识然后我们还会介绍一下就是如何我们用EBPF里面这些组件来实现这个bypass的这个功能然后接下来是梦欣同学他会分享一些他在生产实践当中使用这个EBPFbypass项目中拿到的性能数据他会分析一下然后还有一些他们在couple world的加速当中的一些实践这些其中也涉及到了EBPF然后基本上今天要讲的就是这些剩下的时间可能会留给大家如果有什么问题可以来问我们然后首先的话呢就是在KBS里面每一个pod都是有他自己的一个网络协议站的所以当一个包从一个pod流向到另一个pod的时候就是右边的那个右边的那个上图他是会穿越两次tcpib协议站的然后这个的开销其实如果在没有服网格的情况下还是可以接受的但是当有了服网格之后这个开销就成倍的在网上增加我们可以看增加了服网格之后有了sidecard注入以后这当一个包想要从一个client来发送到另一端的一个server的时候他就会进行六字穿越实际上是相当于过去翻了三倍然后他会在从pod里面出来到sidecard这边穿一次再从sidecard到sidecard再穿越一次然后再sidecard到真正的后端server穿一次所以服网格就把这个开销给放大了所以因此我们就很我们就希望可以在本在同一主机上可以把这一段tcpib给他bypass掉然后把这段开销给省下来这个就是我们做这个项目的初中然后我们为什么要用edpib来实现这个方案首先因为edpib是近年来Linux kernel社区非常火的一个也是他们非常推荐的一种扩展内核的方式然后他对于用户来说实际上是相对比较透明的因为他完全工作在内核然后所以如果你实现的比较好的话你的用户应用可以基本上甚至是可以不做修改的然后就来使用到edpib的这功能然后同时因为他工作在内核他和这个常用的kbs当中的cni是不会有很大的冲突的比如说像calico这种当然如果你用的是像celium这种他主打用edpib的他也许会有冲突但我没有试过然后最后的话这个edpib他在设计之初还有他的各种使用上都是考虑到了安全的方面就是他每一次载入代码都会做验证这种是社区他们都有考虑包括他设计的epf整个使用的情况都有考虑安全这一方面然后另外的话他也比较高效这种相对于传统的想要修改内核的这种方式如果你是传统上想要对内核做一个修改你要我们修改原代码然后要重新编译或者你写一个内核模块来加载这两种方式相对ebpib来说都是会消耗更多精力的然后我们接下来介绍一下我们要实现这个方案的时候用到了ebpib两个主要的一个组件一个就是map还有一个是programmap的话它是ebpib里面提出的一种用于ebpib程序之间或者是ebpib程序和用户态程序之间共享数据的一种方式因为ebpib工作在内核中然后它很快就运行很快就结束所以它没有空间给你来储存数据所以他们发明了map这个东西来作为一个中间传导数据的一个工具然后map它基本上就是一个可以认为是一个建值对的形式但是它里面存放的数据是多种多样的比方说我们用到的这个soc harsh map它里面是允许你在y6里面存一个socate的一个引用然后这样的话当你匹配到这个key的话你就可以直接拿到这个socate然后同时它也允许一些ebpib程序直接去挂载到这个map上然后这样的话就可以监听这个map里面所有的socate里面的一些行为然后就会触发这个ebpib程序来运行我们的程序里面也用到了这个功能然后另外一个组建就是programprogram的话它基本上就是carnal里面给ebpib预留的一些互可点然后就是当carnal运行到这些点上的时候就会跑你提前加载好的这个ebpib程序但是它都是很短小的然后很快就结束的然后通过我们在program能做的行为实际上是严格受到限制的就是carnal它为了安全期间所以你在ebpib这个program所做的事情很可能就只能通过一个叫helper function的它提前限定好的一些helper function你只能做这些操作然后你在特定的program的数据路径上可以拿到特定的数据结构比方说在socops这个program里面你就可以拿到socate你可以看到socate里面的一些信息然后你来做判断然后soc message你可以拿到这个message然后对这个message来做裁定然后决定它是bypass还是说挡掉可以做这些操作然后主要的组件就是用到的这两个然后我们通过这样组件我们来实现它基本上的一个流程就是首先我们会对host上的socate进行一个全局的补货这个是通过socops来完成的我们会补货这个host上所有的就是建立了连接的socate然后把这些socate加入到一个socmap里面然后将那个socmessage这个第二个ebpi program然后由它来监听这个map里面的socate然后当一旦有数据进入到这些socate里面它会触发这个socmessage由socmessage来查找它对端的socate然后来进行转发这个就是我们实现这方案里面的一个大致的原理但是实际上细节当中我们会需要考虑到更多的东西然后接下来我们可以按照具体的一个一个场景来看首先就是这种是比较简单的一个k8s里面一个posed到另一个posed的一个bypass的场景我们可以看到当这个连接建立以后有两个socate的被补货然后可以看它这个socate是很有规律的就是说它的sauce和designation这两个地址是完全对称的所以这种场景其实是最简单的一个场景我们当我们补货到这种socate的时候我们要做转发就只需要把它转发到对调的一个地址的socate上然后这个转发就完成了然后接下来的话我们来看一下surfsmash里面就是入方向的一个bypass的一个场景在这种场景当中同样是补货两个socate然后我们可以看到这两个socate的一样是对称的结构但是它有一个不一样的地方就是说Envoy这边的socate它的原地址是127.0.0.6这个地址是一艘规定好的一个蓝节的地址也就是所有的进入surfsmash里面的server服务的流量都会被sidecar蓝节然后它会用这个固定的地址来建立一个新的请求来发送到server端因此我们实际上可以在蓝节的时候就针对这个地址有针对性的把这种socate的蓝节下来加入到我们socashmash里面然后接下来的一种场景是服网格里面想要访问外部服务的一个client然后当这种场景出现的时候我们看到它相对于我们之前看到的那种这两个socate是完全对称的形式它不太一样 它多了一种复杂性就是说我的client它想要访问的外部服务它认为的外部服务是坚定在80端口上的但实际上真正最后跟它建立连接的端口它是跑在127.0.0.1然后15001的socate上然后这个转发是由Esto来完成的然后它是通过apptables实现了一个流量的重定项它对于client方面是完全透明的但是连接是全部需要和固定的sidecar上的端口来建立的因此对于这种场景的socate的补货的话我们就需要多做一步除了要把socate放进Hardsmap里面我们还需要建立一个这两个socate之间的对应关系因为它们俩实际上是没有什么规律的只是因为另一端是固定的一个端口然后这样的话我们在真正有数据来的时候通过这上面这张表来查找它真正要转发到对端口然后最后一种情况就是sidecar到sidecar之间的一个bypass这种情况其实跟上一种很类似就是说apptables这一次又做了一个修改就是它会把所有进入右边的sidecar流量重定向到1506端口上因此原来的目标端口实际上是失效所以我们还是要再记录一次就把这两个socate来建立一个对应关系然后最后在bypass的时候可以来查询这张表然后以上基本上就是我们在普通的k8s pod到pod之间包括还有serious mesh里面我们需要考虑的bypass场景里面需要处理的问题然后目前的话我们这个项目已经开圆了然后在github上大家可以通过访问eSto TZ PIP bypass来下载下来然后直接apply这个是一个demo site然后就可以运行了然后欢迎大家来使用我们这个项目然后同时提出意见还有也欢迎大家来贡献我这边的关于原理方便的分享就到这里接下来是孟鑫同学然后我给大家来介绍一下就是我们利用就intel他们提供的这套加速的方案然后在我们的一些场景下的一些性能的表现首先介绍一下我们的场景就是一周他们那边做的事情可能更多的是考虑了serious mesh的场景但是在我们的场景中我们其实发现了它的另一个比较有用的用途就是它其实做的是一个同主机之内socket到socket的一个重定项然后这样的一个说法就是它其实并不只是一个单一的针对serious mesh加速的方案而是一个你更宽幻的来讲它是一个同节点之内pull的到pull的之间网络加速的一个方案这个其实对于我们来说正好符合了我们的一个新的场景因为我其实本人是做signite的我们之前signite可能相关比较关注的是跨节点之间的这个容器网络同性的性能但是在实际场景中会有这样的一类场景就是在一些边缘的场景就是你整个的k8机群其实并不是有很大量的机器的可能只有三台到五台机器这种情况下你就会面临一种场景就是你的大量的应用之间的网络同性其实并不是跨节点其实是同节点的这个时候其实你跨节点的性能并不重要而同节点的性能反而会变得很重要而这个其实是我们之前是比较忽略的一点但是就intel这个方案其实都很好的就去满足了这种同节点之间的一种网络加速的一种场景我来简单介绍一下就是我们测试的一个方案就是我们会在同一个节点上部署两个性能测试的pull的然后我们会用qpull去进行就相当于是两边进行tcp的一个对打然后我们会去测它的tcp的延迟和tcp的吞躲量然后我们测试的数据包是从一个字节一直到16k然后就是部长是4倍这样一点一点的去往上找然后去看就是有优化前和没有优化之前还有上了这种优化方案之后的一个性能的具体表现然后左下面这张图测的是延迟相关的一些表现这个绿色的这个可能不太清楚这个绿色的这个柱子其实就是优化之后的一个延迟的性能然后蓝的是个原生的就是没有任何优化的一个性能可以看到优化之后就是延迟的提升其实是很明显的就延迟变得很稳定就是基本上从一字节到16k这种的大小的tcp的数据包它的延迟基本上都保持在20微秒左右的这样的一个情况但是如果补上这道方案的话可以看到基本上都在40然后一直到60 然后这个程度上去波动所以就是从延迟的表现上来说其实就这个方案能给延迟带来很大的一个提升因为它把中间的什么tcp、rptable那段vthpair包括你下面的深爱就是完全都都跳过了变成了一个sulted到sulted之间的直接的数据对传所以它的延迟表现其实是很出色的在我们来看但是在吞吐量这块然后这张图画的其实是吞吐量的一个对比图就是我们会把优化后的datapass的吞吐量除以优化之前的datapass的吞吐量所以理论上来讲如果它高于1的话就说明我们优化之后效果是好如果小于1的话会说明我们的效果反而是比较差的然后这个其实就会发现其实在就是我们也发现的就是这种优化的一个问题就相当于它是在比较小的包的时候你可以看到从1一直到256其实应该是到512左右吧所以整体的比值都是小于1的然后只有当这个数字包相对来说比较大比如到了1k之后它的吞吐量会有一个比较大的提升就是大于1k的话可能会有50%到70%这样的一个性能的提升然后这个我们经过一个分析的就是我们有具体的去研究的很细但是我们具体一个大概的分析大概是这样的就是因为我们这套方案其实它绕过了整个的tcpip站所以带来的一个负面的效果就是tcpip站它本身的一些对于小包的优化其实也跳过去了因为如果大家了解tcpip处理的话会知道tcpip它小包其实是有一个聚合的功能的就是它并不是说你逐包处理的它可能是一字接的包它累积到1k或累积到4k的统一的去处理一次但是如果换成我们这种eBPF方案的话带来的一个负面效果我们其实是逐包进行一个处理这样的话带来的一个负面的效果就是在比较小的包的情况下大家可以看到这个性能其实是从吞吐量的角度来说其实是有下降的但是当数字包比较大比如说1k这个可能是这个可能就跟应用场景相关了如果你的包是相对稍微大点因为1k也不是特别小的包相对大一点的话其实这种优化方案还是有比较大的一个性能提升的然后这个总结大概就是这样就是tcp的延迟会有比较好的一个性能提升就tcp不管是在很小的或者是很大的包它的延迟都会有延迟就会比较稳定而且会有40%到60%相对之前的一个就是latency的一个下降但是吞吐量的话就需要分情况看就是如果你是大于512字节的就在我们比较细的测试中基本上大于512字节基本上是一个分界线就大于512就基本上我们性能都会好一些这样的话就相对比较大的包的话它的吞吐量会有40%到80%的提升但是如果你的应用你的场景下你的包是小于512的话那么它的吞吐量其实是会有还是比较明显的一个下降的所以这种性能方案优化的方案的话大家可能还是需要根据自己的一个应用场景自己的应用测试然后去考虑去试试前面是tcp到p之间的一个加速然后我们和intel在合作的过程中我们其实还发现了另外一个就是也是跟容器网络相关的一个我们认为还是比较所以现阶段来说还是比较大的一个问题就是我们在couple world的场景下我们会发现有比较严重的一个性能衰减就是现在的couple world如果大家是用那种bridge模式的话应该是和pode是一样的都是用的那个相同的SNI去做就是它这一个SNI寄给容器提供网络也给couple world的需机提供网络但是在我们测试的情况下就即使在同样的SNI同样的机器下两个vm和两个pode之间的网络性能差距会差得特别多这个具体的数据可能会根据你的硬件环境或者是你的一些配置有关但是基本上还是会有比较明显的下降的就是在我们的测试里面我们会发现就是如果就同样的情况下它的vm latency相比于pode的话会有60%的提升而PPS就基本上可以理解为吞吐量的话其实会下降到原来的50%这个可能不同的测试环境可能测试数据不一样但是应该都还是一个比较明显的因为我们其实在别的一些用户或者是社区来其实也会发现类似的问题就是只要你是coolboard那你不跟pode比还好但是你应该pode比你就会发现性能其实会有很明显的衰减然后这里面我们考一到了几个可能的因素然后其中的一块可能就是因为就是在coolboard最上面它其实是个vmvm里面其实它有一套自己完整的一套网络站所以相当于你的整个的网络链路既要走外面的vm的网络站还要堵原来的容器的这一套的网络站所以可能这一拖会手一定的性能损耗但是这一拖其实我们现在现阶段没有太好的处理方式因为相当于你设计到vm里面那套哦啊 现在那套东西其实你没有办法做一个很通用的方案然后第二个方案就是如果是在这种bridge模式下的就是如果大家了解一下coolboard的bridge模式它大概是这样就是它的Ci应该是vth一端是在主机上然后另一端是放到pode的容器里对于容器来说就直接走eth0就结束了但是如果是coolboard的话它如果是bridge模式的话因为bridge就是别的模式先不说就只说bridge因为bridge相对来说兼容性是比较好的就bridge的话它会在你的容器的code的ins里面起一个bridge然后bridge把eth能接进去然后上面再起一个tap然后通过这个tap设备然后再接到最上面的那个vm里面来所以我们就猜测有可能是就多出来的这一段的就这个bridge有可能也会是这样的一个性能平均然后我们最理想的情况下其实是我们希望比如说我深爱这边出了一个vth之dor然后我会把这个vth之dor直接的就送到这个vm里这个可能是我们当时想的如果是这样进行一个短路的话就有可能会达到一个性能的提升然后还有一点就是如果大家知道cata的话cata其实是一个比coolboard早一些的就类似的一个虚拟化项目他们其实做了一些类似的事情就是他们是用tcmiro然后直接就bypass了中间的bridge那一段然后去做这个性能加速所以我们就想是不是在这种场景下我们在coolboard上也可以利用ebpf或者是tcmiro这样类似的技术然后也达到这个对coolboard这样的一个通用的一个性能加速因为这个相当于是一个外挂的我不需要赶你的深爱我也不需要赶你的coolboard我只需要在后面在外挂一个bypass这样的一个逻辑其实就可以达到这个性能的提升然后因为cata用的是tcmiro我们本来最开始就是其实现在有两条路都可以做这个事情一个是tcmiro一个是bpf的redirect然后这两个方式其实是都可以的但是经过我们的测试就是还是跟刚才那样从小包到大包从延迟到存土量整体的测试了一圈下来之后我们会发现尽管他们俩都可以实现同样的事情但是tcmiro的性能总是会比bpfredirect要好那么一点点就是不是很明显但是就是好一点点就是所有的测试用力下来都是好一点点所以我们最终决定还是用tcmiro做这套方案而且tcmiro还有一些额外的好处就是如果你是用ebpf的话它其实是对你的内核版本稍微有一些要求的应该是4.19或者是更高的那种版本你才能去有bpfredirect相当于它的辅助函数但是如果你是用tcmiro的话其实很早的内核就3.2G的内核其实都会有这个功能所以就鉴于它的鉴容性会比较好而且它的性能确实稍微好一点所以我们最终是用tcmiro来做的这个事情但是就比较遗憾的一点就是我们其实最开始想做的就是想从这块或者是这块直接通到上面这块或者是从上面出来这个流量上直接通到下面这边来就是我们想绕过整个的这个东西但是我们现在基本上看了一些bpf的方法包括一些比较新的一些喊出方法其实目前来说都没有找到能够绕比较远的路我们现在只能做到的就是把这个bridge绕过去但是绕更远的比如说从VM直接绕到外面或者从外面直接绕到里面是这个方法我们暂时是还没有发现所以如果大家如果有知道这块还有什么更远的一些绕路的方法的话也欢迎和我们来一块讨论吧然后我们就我们这个tcmiro其实还比较简单我们做完之后的之后就会有一个吞吐量的提升就是延迟的下降就是延迟会有5%的下降就这个不是很明显就我们认为就就还算好因为你是一个通用的就5%的延迟下降其实还好但是会发现一个比较比较不好的一个现象就是我们发现我们的吞吐量也下降了20%就是可能就就就就从1k从1字节到16k可能下降的幅度不一样就可能有的会好一些有的会坏一些但整体来说在比较小的时候都会有比较大的这个吞吐量的一个性能的摔退然后当时其实我们也没有分析出来为什么我们只是随即的调了很多的三数然后我们突然发现这个CheckSum是一个导致这个性能摔退比较厉害的一个原因就是我们就是我们当时是随即的就是把这个上面的那个想一下应该是VNT0应该是ETH0这两块就是我们会把它的RX和它的TX的CheckSum全部给disable掉然后就会发现这个性能就会有一个很大的提升这个其实我们最没有细咎具体的原因因为我们尝试过就是我们不加这套性能优化然后我们也把CheckSum给关闭掉但是会发现相当于原来的链路你关CheckSum其实对性能是没什么影响的但是有可能开启了TCMRO的链路的话因为你如果是从Linux通用的网络逻辑来说如果它是纯内部的这种网络通信就比如说它的VNT0、Bridge、ETH0这个其实都是纯内部的网络通信理论上它就Linux内核会做这个优化它不会做CheckSum也不会做CheckSum的教验但是不知道为什么我们加了TCMRO或者加了BPF ReadyRack的之后可能是触发了某些逻辑吧会导致它必须要做CheckSum它可能认为你是一个外国来的数据包或者是怎么样的所以当我们把这个但其实这个CheckSum是没有必要的因为它没有走到外面去完全是主机内的一个教铺不可能出现这个比如说你哪个数据包出错这样的情况所以我们做的事情就是把它的RX和TX的CheckSum就全部都关闭掉了然后关闭掉之后这个性能就会见到一个比较明显的提升然后下面这个图也就是我们是类似的跟前面那个Po的类似的然后我们是做的CoupleWart里面的就相当于我们在VM里面再起了一个QPoF然后我们这次是测的UDP的一个延迟还有它的一个吞吐量的一个表现就可以看到左面这个图是延迟然后红色的这个是我们优化后的就很稳定的会好一点就是好得不多但是基本上会小包的话应该是在5%左右但是包比较大的话比如说到4K或者到16K的话这个延迟其实就很大的包的情况下这个延迟会有一个比较大的下降就整体的话可能是一个4%到30%的一个延迟的下降吞吐量的话其实提升还是比较明显的就吞吐量的话基本上从一次节一直到16K都会有接近50%左右的这样的一个就吞吐量的一个提升然后整体的提升就是应该是在20%到70%之间所以这个就是我们做的就我们和Intel联合一块做的两个工作一个是对童节点内迫的一个加速还有就是也是就童节点迫的那个通用的加速就是我们不关心你的CNR是什么只要你用这套方案它就肯定会有加速还有就是针对cooler world这种也是你不管你下面CNR是什么然后我们做的一个通用的加速这样的话对于这两种比较特殊的场景就都会有一定的这样的一个性能的提升然后下面是我们就未来设想的一些就是还没有具体的去展开的一些工作就首先就是对于UDP的一个童节点的一个加速因为我们前面讲的童节点内迫的到迫的东西其实是针对TCP进行的一个优化因为TCP的链接和UDP的链接还是不太一样所以那套方案还不能完全地去附用所以下面我们有可能会考虑针对UDP的场景我们也把TCP的那种机制类似的迁移过来这样的话TCP和UDP在童节点的性能都会有这样的一个提升再有的话就是我们前面也说了就是针对TCP的场景在小包和大包的情况下其实它的表现还是不太一样的因为小包会有一些性能衰减所以我们可能会有一些力度的控制比如说根据你的包大小我们去选择是走kernel的data pass还是走我们优化过后的EVPF的data pass再有的话就是我们会考虑一下就是前面是童节点的POD但是童节点的VM其实也有类似的一个情况但是童节点的VM面临的一个就跟前面不一样的一点就是如果你童节点的两个POD的话Sockit是直接能看到的因为你主机上是可以直接看到就两个不同Night S里面的Sockit的但是如果是VM的话它的Sockit其实是相当于在虚拟化的操作系统里面的所以你在主机上其实是没有办法做这种的Sockit到Sockit的之间都对考的但是有可能做的一点就是我们可以根据它的IP比如说根据IP或者是根据Duncle去判断出来他们两个是在同一个主机内的通信然后我可以直接在网卡上比如说我的就是看一下比如说前面出来的VTH0然后我们直接在这一端直接可能绕过最底下的那个Ci直接在VTH0的那一端然后直接进行一个Redirect这样的话也有可能做到这个童节点的这个Couple Word之间的这样的一个性能加速OK好以上就是我和Intel一周那边的一些工作然后看一下大家有什么问题吗你说有我就想问一下的话你刚刚知道方案跟Cinema的Sockit LB然后童节点的加速的方案然后的话有什么区别因为我感觉看起来的话两者的话是非常类似的是一周你要说一下就应该是大家思路是类似的因为能听见因为实际上就是Cinema它们的方案底层最后用的都是这个Sockouts加Sockmessage方案我不太了解它具体的细节但是就目前Curl里面针对这个EVPF里面针对这个加速的支持应该都是底层使用的这个原理所以性能上应该是差不多的那我想问一下就是它的话你们CNL的话有没有测过跟那个VXLAN还有MACVLAN的然后这种场景然后加速的一个情况VXLAN和这个还暂时还没有就是你们更多的针对就是说然后我使用VTL队然后从破的然后到组织然后把这些路径给bypass掉了对吧对我们其实主要考虑的是同主机上因为这种场景下它的全部主机上的Socket都是可以被拿到的在这种场景下做这个bypass是很合适哦好那我这边有问题没那那用这个的方式有没有安全性的问题安全性的会有就是比如说如果你是Socket到Socket对考的这种方式的话你的所有network policy是失效的然后主要其实主要就是这个相当于你的network policy我们完全都绕过去了会有这种问题别人还有问题吗所以一键连接的对不加速是吧新铁连接还能不能找总原来的bypass的话是要加速的IP或是解析就IP原先的对连接还是有原先不管你是IP table什么的做修改什么都不会变的哦就这边已经接的点了对对对就这样好好谢谢大家