http://www.cnblogs.com/frankdevhub/p/7249935.html
简介
根据SDN的实现深度,可将其分为狭义SDN与广义SDN。其中,狭义SDN是指基于OpenFlow协议,将转发面和控制面完全分离的革命性SDN。广义SDN是指数据包转发依然基于现有设备上的协议,但将网络的部分控制功能上移到控制端,是一种既能利用现有网络设备,又能获取SDN部分优点的演进型SDN。
广义SDN因其高效、颠覆性,受到学术界及创业公司的关注。而对于传统设备厂商和运营商来说,不太可能短时间内,大范围地将现有设备替换为OpenFlow设备。因此,对于传统运营商来说,演进型SDN的研究部署同样迫切。
中国科技网是由中科院计算机网络中心负责运营的,学术性、非盈利性互联网基础设施。在全国部署上百个骨干、接入节点,同时拥有多条通往美国、日本和韩国等国际出口,是中国主要的互联网运营商之一。
科技网中网络设备的提供厂商较多,比如Cisco、Juniper、华为和华三。当前用独立分散的方式对网络设备进行管理,比如,当路由器执行新的防火墙或路由规则时,需要SSH登陆路由器进行手动配置。网络设备多而杂,这样的人工配置方式耗费人力,且易出错。利用广义SDN的思想,对网络设备进行统一自动管理是科技网在自动化运维方面的尝试。
目前,我们基于ONOS控制器进行二次开发,对juniper测试路由器进行集中控制,执行防火墙限速等功能。ONOS中主要通过NETCONF协议远程读取、修改网络设备配置,所以我们也基于NETCONF协议来实现对Juniper路由器的管理。主要工作分为如下几部分。
1 在ONOS中开发juniper路由器的简单driver,链接路由器。
2 进一步在driver中添加所需功能,比如实现XML文件解析,利用NETCONF协议下发相关XML文件,执行基本配置读改、设置防火墙限速等动作。
3 在命令行下发模块(cli)中,开发新的执行命令,使得用户可在命令行中执行2的动作。
4 由三台juniper测试路由器,组成测试demo,验证相关功能。
相关实现代码已开源:https://github.com/CNICCSTNET/OpenJuniperDriver
下面对上诉工作进行详细介绍。
前期准备
ONOS中基于NETCONF协议对路由器配置进行远程控制,由于之前对NETCONF协议不太熟悉,首先学习了NETCONF协议,并用分别用NETCONF协议的Python函数库(ncclient),和juniper的NETCONF Java Toolkit实现了简单读取和修改路由器配置的小程序。升级路由器,使其支持NETCONF协议。同时学习juniper路由器的配置命令,弄清实现不同命令时NETCONF协议下发的XML文件。 相关的学习链接如下:
NETCONF RFC6241:https://tools.ietf.org/html/rfc6241
ncclient:https://pypi.python.org/pypi/ncclient
NETCONF Java Toolkit:http://www.juniper.net/techpubs/en_US/junos14.2/information-products/pathway-pages/netconf-java-toolkit/netconf-java-toolkit.html#overview
一 、Driver初步实现,链接路由器
1.1 新建juniper APP
ONOS需要不同的Driver来对不同设备厂商的设备进行控制,在ONOS中开发driver的步骤跟实现一个普通APP的过程相识。具体可参见ONOS的wiki或者毛健炜同学的博客:
https://wiki.onosproject.org/display/ONOS/Creating+and+deploying+an+ONOS+application
1.2 修改pom.xml等文件
建好名字为juniper的APP后,将其移动到onos/drivers/目录下,并修改onos/drivers/juniper目录下的pom.xml文件:
同时修改onos/drivers/下的pom.xml文件,添加juniper module,使得编译drivers模块时,也编译juniper的driver:
在drivers/juniper/src/ 目录下,新建resources文件夹,并新建一个juniper-drivers.xml文件,用于存储juniper驱动的相关调用关系。目前是空的,在后面实现具体修改路由器配置时,可添加ONOS中api接口和具体实现的对应关系。
新生成一个导入juniper-drivers.xml文件的java文件JuniperDriverLoader.java,放在onos/drivers/juniper目录下:
1.3 编译并启动drivers
在drivers目录下,执行mvn clean install编译后,重启ONOS。执行如下命令,启动相关的drivers APP:
若APP启动成功,则执行drivers命令。可以看到我们的juniper 及 NETCONF的driver都启动成功:
1.4 链接路由器
在tools/test/configs目录下,生成netconf-cfg-juniper.json文件,作为链接juniper路由器时的读入文件。此文件定义了接入设备的名称,调用的driver,及用于NETCONF协议登陆的用户名和密码,路由器的IP和通信端口号。其中,830是NETCONF协议的固定通信端口号。
我们的juniper driver继承了NETCONF driver,调用NETCONF协议(onos/protocols/netconf)中的方法实现和路由器的通信。ONOS为利用NETCONF driver,链接远程路由器实现了相关命令onos-netcfg。我们也可以通过此命令,将juniper路由器和ONOS中的juniper driver相链。
ONOS中NETCONF相关的wiki链接:https://wiki.onosproject.org/display/ONOS/NETCONF
链接路由器成功后,在ONOS中执行devices命令,可查看到此路由器已经通过NETCONF协议和控制器相连。
至此,我们juniper的driver开发已初步完成,通过此driver,成功将路由器和ONOS控制器链接。下面我们将在此driver上,增加用于解析NETCONF协议中XML文件的类,并通过下发相关XML文件,实现读取并修改juniper路由器的功能。
二、Driver进一步开发
在本部分中,我们将进一步在Driver中添加相关功能 。新添加的功能可分为两大类,一是将用户输入的命令转为NETCONF命令(即XML文件), 另一个是将相关的XML文件通过NETCONF协议,下发到路由器 。
Driver文件的结构如下图所示:
Tools文件夹中的类主要是针对用户输入的命令生成相应的NETCONF命令,以及对juniper路由器返回的命令进行解析。而在juniper文件中的类主要是完成对driver的加载以及命令的下发。
2.1 NETCONF命令生成
在juniper驱动开发的最关键的一步就是NETCONF指令的形成。NETCONF命令是XML格式的String字符串。在NETCONF中,发送的命令一般是包含在标签中。而设备返回的命令一般是包含在当中(具体命令的格式我们会在后续的文章中介绍)。
为了能够高效的形成XML形式的字符串,使用了XMLConfiguration这一工具类。
熟悉NETCONF命令的同学都知道,NETCONF命令中读取和修改的命令都具有固定的格式。为了方便使用。我们将命令的格式写进了netconfEdit.xml文件中。当有命令进来的时,只需要在固定的框架中填充一定的内容就可以了。
对于传入参数的设计,我们参考XMLConfiguration里面的命令和对实际情况进行讨论分析。我们决定用“;”进行每个路径的分割。如果输入的某个路径无法唯一被确定,可以使用path1;path2[@name=”name”]的方式进行路径的指定。下面是我们解析路径的部分代码:
2.2 NETCONF命令的发送
当用户加载完路由器的驱动以后,ONOS系统会自动与在配置文件(1.4介绍的netconf-cfg-juniper.json)中配置的路由器进行连接,并将产生的session保存在NetconfController中。当路由器需要下发命令时,首先要获得对应的session,然后调用我们上面写好的函数生成对应的Netconf,接着调用session的requestSync方法进行命令的发送,并获得返回信息(ONOS发送信息的具体步骤我们会在后续的文章中介绍)。
当收到返回信息以后,利用tools中xml解析类对返回的信息进行解析,得到相应的信息,并对返回的信息进行解析。
三 、新命令开发
我们在onos/cli模块中,实现了多个新的命令,比如获取路由器详细配置、修改路由器某个参数、设置防火墙限速及执行commit使得配置生效。下面以获取路由器详细配置信息的命令为例,说明新命令的开发流程。
3.1 新建接口程序
在onos/core/api/src/main/java/org/onosproject/net/behaviour目录下,新建ConfigDetailGetter.java接口程序:
此接口程序的具体实现在juniper driver目录下的ConfigDetailGetterJuniperImpl.java中。为了使得调用此接口时,自动跳转到juniper driver的实现,需要在juniper-drivers.xml文件中添加两者的对应关系:
利用外部XML文件指定接口和实现间的关系,是ONOS中常用的处理方法。此方法可减少核心core中的代码量,将大部分实现放在第三方的接口程序中。
3.2 调用接口程序,实现命令
在 onos/cli/src/main/java/org/onosproject/cli/net/vnet目录下,新建DeviceConfigDetailGetterCommand.java文件,实现具体命令:
uri,cfgType,firstLevel等是从用户输入的命令中传递过来的,这些参数中包含了用户希望进行配置的具体信息。利用deviceId,我们找到对应的设备。再根据设备的信息,调用具体的驱动,也就是我们的juniper driver。XmlStructureParserGet用于处理用户传进来的参数,将其转化为2.1中生成XML文件所能识别的结构化字符串。因为一个接口可能拥有多个实现。所以需要通过ConfigDetailGetter.class 找到接口的具体实现类。以本系统为例,configDetailGetter接口的具体实现是ConfigDetailGetterJuniperImpl类。
四、测试Demo
完成第一到第三步的开发,并编译成功后,建立由若干路由器组成的测试网络,验证相关功能。实验网络如下图所示,一台运行ONOS的服务器,此服务器也用来测试文件上传和下发速度,三台juniper M10i路由器,操作系统升级为最新的Junos 15.1,服务器和路由器在同一网段。利用ONOS下发对某个IP进行限速的指令,然后让此IP所对应的服务器从路由器上下载、上传文件,验证限速的有效性。
根据第一步中的方法,将ONOS和路由器链接后,首先下发限速所需的防火墙规则:
其中set-speed-limit 是我们实现的专门进行限速的命令,netconf:159.226.101.32:830 是路由器设备的ID,myFirstTest是此防火墙的ID,159.226.101.80/32 是被限速的服务器IP,速度限制为2M,burst速率限制为10K。返回的ok表示设置成功。
将防火墙规则绑定到某个Interface:
其中,filter-interface 是我们实现的将某个防火墙规则绑定到Interface的命令,此命令将我们刚才生成的防火墙myFirstTest绑定到Interface fxp0中。159.226.101.80/32对应的数据流通过fxp0端口进行转发。
最后,利用commit-router命令,使得上诉配置在路由器中生效:
登陆路由器,确认相关配置在路由器中生效后,在159.226.101.80/32所对应的服务器上,利用scp 方式从路由器获取文件,或者将数据上传到路由器,确认限速成功。
五、总结及未来工作计划
目前,我们在ONOS上开发了juniper的driver,在driver中通过NETCONF协议控制路由器,成功实现了远程获取路由器配置、限速等功能。这是中科院网络中心网络研究团队在广义SDN方面做的一次尝试,证明利用现有开源控制器,可实现对现有网络设备的集中控制,为在科技网上实现SDN控制积累相关经验。
在ONOS开发过程中,我们对其NETCONF具体实现、driver相关模块、XML文件解析等有了一定了解。NETCONF协议和数据搭建模型YANG是紧密相关的,我们本来也打算用YANG对路由器配置信息进行建模,方便XML文件的生成。但后来发现目前ONOS对YANG模型的支持还不太完善,需要自己实现的东西太多,最终放弃。未来,我们团队打算在如下方面继续开展工作:
1 基于我们对NETCONF具体实现、Driver相关模块、ONOS中如何利用外部XML文件实现Driver模块的热插拔等方面的认识,写成详细文档和大家分享。
2 ONOS社区中华为的Patrick Liu团队在推进brigade-dynconfig项目,此项目将实现通用driver,并基于这个项目,完善ONOS中对YANG的支持。我们打算跟进这个项目,并最终基于这个通用driver和YANG实现我们现在的功能。
brigade-dynconfig项目链接:https://wiki.onosproject.org/display/ONOS/Dynamic+configuration+brigade
3 基于ONOS,进一步开发集中控制流量调度的模块,争取在广域网上实现SDN的流量自调度。