欢迎大家来到CoopCon 2021Channel的CNN Maintainer Track Session然后本次CNN社区带给大家的topic是CNN 1.0的回顾和CNN 2.0的展望首先做一个自我介绍,我是马文君,我英文名是Bruce Ma然后我是来自蚂蚁金服金融科技的云计算研发公众师然后在看社区的话,我是CNN社区的Maintainer同时我是阿里云红贵云融器网络插件Hybrid Night的Owner然后下面是我的GitHub和WeChat如果大家有什么融器网络或者KBS相关的问题都可以问我我是欧米生,然后我是来自阿里云融器服务的研发公众师然后同时我也是阿里云融器网络插件Toy的一个Owner然后下面也是我联系方式,然后大家有什么问题也可以在GitHub和WeChat上跟我去沟通然后下面是我们今天Topic的一个目录首先我会去介绍CNN1.0的一个整体的回顾然后是马文君会介绍CNN2.0的一个展望首先CNN1.0是在今年8月份也就是最近去发布的一个CNN整体这个项目的一个稳定版本然后在这个版本中它会去重写以及固化了CNN的一些标准首先我们还是看一下CNN这个项目在整个融计生态中的一个位置CNN的项目是融计的运营石然后融计运营石的上游就是我们所熟知的像KBS这种调度系统然后像融计运营石中常见的像康泽尔蒂帕德曼这种它会在创建融计的整个生命周期的过程中在融计创建好之后它会去调用CNN的插件然后去对CNN的整个对融计的网络去做一个整体的配置然后CNN就是content networking interface的一个缩写然后有很多插件去实现了这样一个融计的CNN的一个API首先我们看一下CNN的一个标准它和其他的一些API标准不同它是首先它是通过二斤制的方式去做一个插件的一个执行然后它通过二斤制的方式会有四个API都是通过二斤制的一个参数的方式去做传递包括了Add,Delete和Check,Version四个API然后它会把网络的配置通过二斤制执行的时候它的一个标准输入方式去传递给Delete的一个插件然后为啥是通过二斤制的方式而不是类似于Ci,Ci,Ci这种通过加PC的方式呢这是一个比较常样的故事首先Ci它是源自于RocketRocket它这个运行室就是一个Dimitless的一个运行室所以它相关的插件也都是二斤制的方式然后另外一个原因就是在我们所处置的Ci以及容器这个生态都是沟浪去实现的然后在沟浪早期的版本例如小于1.10版本里面去管理多个网络的空间其实是一个很不可靠的一个方式比如说在早期的版本里面通过GoRoutine去创建出来有可能会在一些不可用的网络空间里面然后导致一系列的网络问题但是这些问题看起来在现在的生态里面都得以很好解决所以我们也计划在Ci的2.0协议里面会考虑使用加PC的方式去做调用然后我们看一下典型的一个Ci的在整个容器运行时的一个执行过程然后在容器的一个setup阶段就是容器的创建阶段里面运行时首先会创建这样一个网络空间例如在RomC的运行时里面它会去创建一个插箱的容器然后它会去执行Ci插件的爱的方法让Ci插件去配置这个网络连接就是相当于给这个容器去插上网线然后同时它会去把这个结果返回给RomTimeRomTime会记录这个插件执行的结果并且放到一个开启的目录里面然后另外两个API就是check和delete的API分别扮演的就是检查这个容器网络是否是预期的然后以及在那个容器的生命周结束的时候去释放这个容器相关的网络资源我们看一下Ci的一个配置的一个格式Ci的配置通常是以接层格式存放在节点所在的那个磁盘上面的然后我们首先看一下一个典型的例子这三个可以就是前三个可以用绿色标出来的是必须的一些自断比如说Ci的Version Name和Type这三个是标明了Ci的一个必须的自断然后里面关键这个Type是标明了对应的到底是要执行哪一个二经济文件然后这个配置文件是同时被Rontime和Plagin去消费的Rontime的话它首先会根据这个配置目录里面的文件顺序去选择正确的配置文件去做配置然后其次是会解析这个配置文件找到它对应的Plagin的Type去选择选择要执行哪一个插件然后会通过执行的过程中将这些配置文件内容去传递给插件的标准输入然后插件会读到这个标准输入并且按照这个配置去设置整个容器网络的一个命名空间通常来说Ci的Plagin就是Ci的插件会通过一些自动的方式去安装这些配置例如在K8s里面我们通常会通过dimensite去安装配置文件到每个节点上面去下面是个例子我是从flano的一个安装脚本里面去解决到的就是它会通过dimensite然后通过intel的container把flano的二斤制以及flano的配置文件拷贝到每个节点的一个对应目录里面来实现这个配置文件的一个安装然后刚才是每个节点里面会有一个Ci配置文件来标明这节点使用的一个具体的Ci插件那如果我的每个容器就是这节点上运行的每个容器会有不同的配置要怎么去动态的去配置呢在Ci的0.3的版本里面有一个Runtime Config这样的一个能力它可以支持每个container有自己独立的配置我们如何去声明它的就是在刚才所介绍的配置文件里面通过capabilities这个字段然后去声明对应的我们需要的一个具体的特化配置的例如说我们比较常用的pod mapping就是每个容器可能有自己独立的一个素主机的短口音设的然后这种达在Runtime去执行的时候它会把这个对应的capabilities这个可以去替换成特殊的这个容器配置比如说替换成这个这个容器它对应的具体的素主机音设端口是哪一个然后其次这个Runtime Config里面可以去配置很多其他的可以然后具体的可以在这个现在文档里面去找到我们通常可以在官方的Parkins这个插件集合里面这个项目然后或者是在一些第三方的CNH插件项目里面去找到我们所需要的CNH插件然后这两种项目会有一些典型区别官方这个插件组合里面项目它通常是一些原插件的一些组合然后它需要把这些插件都通过违派或者是通过那个链的方式去组合在一起来实现一些复杂网络配置然后但是第三方的一些项目例如我们常见的Flinocalico这些项目它都是一些all-in-one的一些配置通常它会把所有的网络连接 IPMQOS等等这些能力都放到一个二件这文件里面去做去做统一的解决方案官方这个Plugins这个项目里面是很多的一些网络插件组合它分为了三种类型首先Mend的类型是主要是包含了网络接口也创建类似于比如说Bridge, IPvlan, Macvlan这些给我们常见的网络接口的一些创建能力然后IPM这个插件通常是一些做IPD纸的一些分配管理的一些插件然后还有一些其他插件通常是对上述的两个插件做完之后再对网络的容器去做一些再次封装的一些能力然后如何组合这些插件呢就是有两种方式一种是通过伪派方式就是我插件可以把或需要一些功能去让另外一个插件来实现最典型的就是IPM的能力我可以很多插件是通过伪派方式让另外一个IPM插件去分配它所需要IP然后去配置到它的网卡创建上面去然后另外一种组合方式就是通过电的方式这种方式的话插件是作为类似于一个流水线然后分别去对这一个容器的网络去做它的一个加工以及处理下面是两种典型例子一种是我们常见的一些安德雷网络配置我们通过MacVlan去创建这个容器的训练的网络接客然后通过DHCP然后MacVlan去要用底层的DACP的一些协议然后去做网络地址一个分配然后这种就是典型的MacVlan里面去伪派了DHCP去做地址分配这种组合方式然后另外一种组合方式就是通过链的方式这种我们常见的比如说我们通过一个Bridge的网络插件去做容器网络的一个地址分配以及网卡创建然后再通过后续的类似于BandOS这种插件去做一些KOS这种配置然后这种是链的一种典型的方式然后对于第三方的网络插件的话它通常来说不像官方网络插件可以做一些组合它通常来说会把所有的能力去放到奥英湾的一个Banner里面然后这个主要原因有总结有主要三点然后首先是早期的CNN版本并没有提供Plagin Chain然后这样的话我并不能通过链的组合去结合其他的插件然后来提供能力所以很多早期的时候这些插件实现里面都把所有的都包到自己的一个二进制里面然后其次的话很多网络插件它跟刚才所介绍的官方的网插件里面所使用的技术不太相同可能官方的主要是用Bridge和VPH这种Linux的网络占的一些协议然后可能第三方网插件是比如说它用Openware switch然后并不能跟官方去做建容所以这种它并不能去跟官方的去结合在一起然后还有一些原因是这些插件它本身实现比较偶和比如说像Kalico它的IPM跟它的网络的路由配置这些都是紧密偶和在一起的所以它也不方便的去把这些去分拆到不同Pagin里面去然后我们如何去选择第三方网插件的第三方网插件通常会有三种类型就是Android的然后基于路由的或者是Overlay的类型然后我们通常需要根据自己的基础设施然后以及自己对网络插件的一个灵活度的需求然后以及对性能需求然后去综合考虑去选择我们所需要的网络插件类型以及具体哪一个网络插件下面我将把时间交给马上军帮我们来介绍CNN2.0的一个展望非常感谢秉生带来的1.0的回顾然后在秉生的讲究里面我们大概了解到了CNN1.0的历史它的眼镜以及它当前的一些约束规范和使用的姿势那么在我的部分我会给大家做一个CNN2.0的展望为什么要做这样一个展望呢其实就是希望能够把在CNN1.0历史的一些问题包括使用上的一些困扰做一个统一的解决然后现在CNN2.0还没有在CNN社区正式启动那么现在仅仅停留在一些Maintainer的一些想法上然后我们其实也把这些想法也都通过提促的方式开在了社区做一些公开的讨论我们在启动2.0之前一定是需要很多的建议和讨论的然后首先说一下为什么我们需要CNN2.0然后这里我提了两个问题其实这两个问题我作为CNN的Maintainer其实都很难回答然后第一个问题就是CNN1.0是不是真的足够易用那么我们都知道CNN1.0作为一个接口类的应用它其实是包含了两部分的第一部分是面向容器运行时的也就是它的LeapCNN的部分这一部分的话通常容器运行时通过一个包的方式引入LeapCNN来做一些网络插件的调用第二部分就是CNN运行时就是说LeapCNN去调用Plagin的方式在这个时候的话刚才炳盛也说到了主要是一些RGN制的方式这两种方式其实都不是标准JRPC的方式其实对于实用来讲其实是有一些困扰的那么第二点就是说在我们现在是把网络功能分成了不同的插件但是插件和插件之间在交换的在交流的在交流的过程当中肯定是需要一些参数的传递的那么这些参数的传递其实是在CNN0.3.0的版本才正式引入了一个动态配置的能力而且这个配置的能力其实是需要容器运行时来做一些粗暴的转化的其实它也是不太易用的第二个问题就是我们一直在思考的一个问题就是CNN社区真正的官方职责到底是什么如果我们开发过容器网络插件我们一定会遇到很多的问题比如说我们现在需要记录或者展示一些容器的当前的网络状态比如说我们需要一个中心化的iPad比如说我们需要为容器去构建多张网卡那么这些都是否应该属于CNN的官方职责其实对于我来说CNN的2.0的设计不仅仅像1.0一样应该提供一个标官方的容器网络的接口和一些被官方所维护的网络插件其实CNN2.0更应该提供的我觉得是一个容器网络的生态这个生态一定是可扩展的用户有好的而且被管换接受和使用的那么接下来其实刚才我也谈到了也谈到了CNN的接口其实分了两部分第一部分是leapCNN就是CNN runtime的部分第二部分就是CNN的plugin那么我分别从这两部分来讲一下当前CNN2.0从我们maintainer层面的一些设想第一个就是plugin层面的我们是否需要更多的方法我们现在都知道plugin现在支持的三个方法应该是add,delayed和check然后check的方法也是在0.4.0刚刚引入的那么我们现在所有的官方维护的插件包括一些第三方的插件其实都是共享了这个同样的方法但是一下的场景是否能真正的被covered down比如说当我们去再做一些容器网络的挂载的时候我们需要做一些准备的工作一个通常的例子就是我们在把容器挂载到一个网桥上之前我们需要先准备好一个网桥第二点就是说我们是否可以在不重建的情况下去更新容器的一些网络相关的一些参数比如说一个网卡的内核参数第三点就是当我们一个几点下线的工作我们需要去对它做一些彻底的容器网络相关的一些规则的清理根据伍衣山我列的三个场景我们现在的方法add,delayed,check是否够用的我觉得是不够用的所以在CN2.0里面我们提出了一个新的设想首先我们发现这个方法是构建在容器和插件之中的那么在1.0里面我们是有add,delayed,check三个在2.0里面我们是否可以引入更多的呢比如说update和finalizeupdate的方法可以用于当容器想进行一些网卡或者网络参数的一些动态更新的时候调用的一个方法finalize则像KBS里面泡的finalizer一样其实是在一个流程的最后一步当我们一切准备就绪的时候我们需要做的一些操作一个比较经典的例子就是路由表的配置如果我们是在一个拍拍单里面每一个动作都去执行一些路由的配置的话那其实它的中态我们是无法确定的而如果我们在最后一步去执行路由表的一个配置的话我们会得到的是一个稳定的结果所以它更适合被声明成一个finalize的方法然后对于一些全局类的一些插件比如说我刚才提到的一个网桥的构建这样一个插件其实我们更多的可能需要的是unit和gabbage collection这两个方法unit的方法可能更多的用于当一个节点刚上线的时候的一些前期的准备工作主要包含的是在宿主机上的一些网桥包括网络设备的构建gabbage collection可能更多的用用于当节点下线的工作当中我们需要针对这个节点去做一些彻底的清理然后plugin的第二个部分就是我们现在已经有了更多的方法那么更多的方法是否适合于所有的plugin呢包括我举个例子比如说我现在有一个bridge的插件我是否真正的需要gabbage collection这个方法不一定所以说基于我们想要引入更多的方法的这个前提我们是需要对plugin进一步做一个细化的分类的这个分类的结果是我们希望更多的plugin能够更好地被共享和组合然后plugin如何分类呢这里我可能列举了几个标准比如说根据它的用途比如说根据它的这个有无状态还有就是说比如根据它的输入输出那么下面这两段图其实就是对比了plugin分类和不分类的两种不同的形态在不分类的场景也就是说1.0的场景其实是所有的网络插件都开放了一个add的结构然后leapCni也就是说Cni runtime通过add的方法去练试的调用network configuration就是网络配置里面声明的那些插件然后我们可以看到这个行为是比较明确的那在2.0里面如果不同的插件有不同的类型比如说像右边这样图bridge插件有可能是一个全举的插件bridge插带的插件有可能是一个单网卡的一个插件appm则是更多的测重于一个IP分配和管理的一个插件syscontrol则更多的倾向于对于网桥配置的一些一个插件那么我们把插件分成这四类了之后那么Cni runtime才能够知道我要用不同的方法去掉不同类型的插件来完成一个整体的网络的功能OK 第二部分我们首先我们先刚才的两部分是聊到了plavin的一些可能的一些眼镜那后面我们会针对Cni runtime一个眼镜也去展开一些探讨Cni runtime其实就是说给容器运行时开放出去的接口也就是说我们熟知的LibCni那么首先先看一个我们其实并不怎么期望的一个现状就是很多的容器运行时都会在LibCni上也就是说在Cni runtime上再封装一层完成他们自己的一个容器网络的接口一些举个例子比如说在CiIO社区里面的OCI-Cni项目比如说在continental D社区的GoCni项目甚至比如说Motus其实都是利用了LibCni去封装出了自己的容器网络接口这个其实是有点违背Cni社区最初创立的目标那么我们对这几个仓库做了一个深入的调研之后我们发现有以下的原因驱使这样一个现象的产生首先第一个原因就是很多容器运行时社区有自己的私有的API的定义他们可能需要封装LibCni来完成自己的独有的一些API然后第二点就是LibCni刚才也提到了在0.3.0版本引入了一个动态配置能力但这个动态配置能力其实中间是需要一个解析也就是说是需要一些验证然后再注入到Cni里面的这里面其实需要一些转化的工作那其实不论是OCICni还是GoCni也好都在做了这一部分相关的工作还有一部分是针对网络配置这一块其实对于LibCni来讲其实就是简单获取了一个素质金目录下的一个配置这个配置其实是不可被更新的那么如果我们认为这个配置是一个动态的那么很多的容器运行时它实现的这个库或者是类其实就是对这个文件有一个WATCH的能力可以动态更新还有一些容器运行时自己实现的网络接口还有一些缓存一些数据的能力可以提供一些数据然后右边这张图其实就是展示了当前的一个状态就是Continual runtime先调自己的私有的网络的库然后再调LibCni其实这是我们不希望的一种行为我们希望Cni runtime足够通用到可以直接被Continual runtime调用然后为了改变这种现状我们也在Cni runtime层面提出了两个改进的点第一个点就是Cni的进程化这个刚才秉身也提到过就是说这个其实对于Cni社区来讲其实是一个很久的一个话其实我们一直想做一个改变但是对于1.0来讲确实是一个比较大的改变所以我们希望能够在2.0里面其实是做这样一个改变的一个很好的一个时机一个起点那么想要做这样的改变需要做什么事情首先我们需要通过GRPC来封装成为我们Cni runtime对外标准的接口的方式然后第二点就是当Cni runtime去调Cni的插件的过程当中是希望它既可以通过GRPC的方式也可以通过Bannerware的方式也就是说插件可以决定自己是进程化运行还是二进一制方式存在这也是提供一个向下兼容的一个能力同时因为Cni是通过进程的方式运行的它会记录很多的状态在这个宿主机上那么它其实像Continuity一样可以提供很多的状态的结果供上游来调用那么显而易见的通过做这些事情我们可以得到如下的收益首先是我们有了一个明确版本的一个API这个也是GRPC的一个标准能力我们可以看到在不同的版本里API究竟发生了什么样的变化而不是纠结于一个打上了Tag的一个代码然后第二点就是说我们可以利用这个API去传递很多非结构化的资段这些资段可以用于在某一个固定版本上去做一些动态的扩展尤其是用户自定义的部分包括一些配置包括一些上下游的就是插件之间上下游的参数之类的都可以通过这种方式来传递第三点就是既然我们是通过进程的方式运行我们一定是有状态的这种状态可以帮我们记录很多的容器当前的运行的状态包括它之间做过什么操作这些其实在API层面其实是有利于去我们去做一些高阶的事情比如说密等径那么在容器运行时其实第二个我们想做的改进是网络配置网络配置就像刚才比证所说的它在1.0里面其实就是一个流水线其实就是一个堆叠的JSON的文件它存在磁盘上面它里面记录了我这一次网络组长所需要多少个插件需要先调A再调B再调C它是一个顺序执行的过程同时CNI提供的机制就是LeaveCNI提供的机制只能在如果两个plagin之间想要传递私有信息其实不可以的只能传递一些官方的一些result比如说有几个网卡被创建出来了比如说有几个IP被分配出来就是这些基本的信息用户的自定义信息是无法传递的那么其实如果我们把CNI的接口做得足够通用的话那么network configuration也就是说网络配置我们希望它是什么呢我们是希望它是工作在CNI接口上的一个清亮的一个编程语言那么我们为容器去组装一个网络就会变成什么呢就会变成一个编排的流程而不是简单的一个流水线如果想要实现这个能力我们需要做到什么呢首先我们是要用编程的思想去编排整个plagin的组织其中可能会涉及到一些磨板渲染包括一些引入一些特殊的语譯比如说缚写款比如说aflx等简单的语譯这个就有点像help的实际然后既然我们是有一种编程语言来组织plagin那么plagin本身的引入就应该像包管理一样它可以做到一个自动发现和自动注册然后对于一个编程语言来讲上下文也肯定是必不可少的我们希望能够有一些用户自定义的参数可以被network和configuration来编排和自由的在不同的plagin里面传递比如说我们想把一个ipamplagin产生了一个ip定向的塞给另外一个plagin我们希望可以做到一个这样的事情然后第四点对于一个网络配置来讲我们希望它是低规的也就是说我们可以在一个plagin里面调另一个plagin这样的好处就是我们可以灵活地把多个plagin组成一个单个的plagin也就是说我们可以完成一些功能的组合然后在组合的技术上继续提供服务的话就能够让网络配置文件能够更聚合 更简单最后一点作为一个编排系统肯定我们也希望能够有一些跟外部的互动那么引入一个webhook就可以解决这样的问题比如说当我们有一些外部成熟的iPad方案需要被CNR引用的时候我们可以希望在network configuration里面也能够标准的便捷的引入到外部的API来为我们做一些事情那后面的就是一些比较创新的一些点这些点可能并不一定是CNR2.0里面我们遇到的最核心的问题但是这里提出来给大家分享一下首先 第一个就是动态更新的能力现在KBS推崇的一个更新的里面就是POD的重建是无损耗的也就是说我们可以通过删除重建的方式来更新一些东西那么其实在从CNR的角度来讲我们是希望能够有一个动态更新的能力比如说更新一些参数比如说动态的挂载一些网络的一些设备然后第二点就是多租户然后多租户的话可以帮助我们在同一个插件里面去通过不同的租户来隔离一些东西然后第三点就是事件及时我们现在CNR社区其实已经包括那个容器运行使社区其实已经购建出了一条从Cublate到容器运行室再到CNR的一条事件通知的一个机制那么其实当CNR的Runtime和CNR的插件都本身变成精神化之后那它自己本身也可能产生很多的事件如果把这些事件及时的回馈给到容器运行室的话其实可以产生一个双向的效应可以做一些很多实时性相关的事情然后最后一点就是说我们可以看到在很多的开源的一些容器网络解决发达里面都会自己定义一些object比如说IPR比如说网段这些东西的话网段这些那么从CNR的角度来讲随着KBS成为一个业界PASS的事实标准那么其实我们也是希望能够给KBS贡献更多的这个官方的一些定义然后能够让大家的代码更联动说了这么多其实这些都是CNR2.0的一些设想一些不成熟的设想还是需要一些大家更多的参与那么如果大家想对CNR2.0真正感兴趣的话我们可以通过如下的方式加入进来首先第一个就是在CNCF Slack里面有一个CNN和CNN Dev的Channel大家可以加入然后我们的明天都在里面可以为大家解答问题大家可以提出自己的一些想法第二点就是在这个CNN社区里面去开一些e-show可以供大家公开的一些讨论最后的话如果大家这个其实也可以联系我跟岭生通过这个私有联接的方式联接我们俩联系我们两个提出对CNR2.0的一些设想然后CN社区的每天的列表其实在仓库里面大家也可以通过这个email的方式联系都可以今天的topic就到这里谢谢大家谢谢大家