作者简介:刘宏岩,福州大学数计学院2016级计算机科学与技术(实验班)本科生,主要研究方向为软件定义网络SDN、网络功能虚拟化NFV。
陈翔,福州大学数计学院2015级计算机科学与技术(实验班)本科生 ,对软件定义网络SDN,特别是对P4语言感兴趣。
OpenNF简介
网络功能 (Network Function,NF) 通过一系列方式对数据报进行检测和修改。例如IDS (intrusion detection system)、负载均衡器等。NF在网络安全、网络测量等领域扮演着至关重要的角色。近年来,网络功能虚拟化 (NFV) 通过在通用服务器上运行基于软件的NF取代基于专用硬件的NF,显著降低成本;同时,软件定义网络 (SDN) 可以引导流量通过NF以执行策略和管理网络。通过SDN与NFV的结合,可以实现通过动态调度流量均衡NF负载的应用,如NF负载均衡 (load balancing) 和NF迁入迁出 (scale-in/out)。OpenNF正是Aaron Gember-Jacobson等人在SIGCOMM 2014会议上提出用于协调控制NF状态和路由策略的全新架构。
本文通过介绍OpenNF的设计思想和实验流程,希望更好的能够实战化SDN与NFV结合的实现设计与实验方案。
SDN和NFV的结合可以实现以下三个目标:
1.在NF性能或时效性方面满足严格的服务水平协议 (SLA);
2.准确监控和调度全网流量;
3.最小化NF操作开销;
然而,同时实现这三个目标非常困难。如图1所示,考虑如下场景:一个IDS实例过载,必须向外迁出一些流量以满足SLA对吞吐量的要求。基于NFV我们可以轻松启动一个新的IDS实例,基于SDN我们可以把原本发往过载IDS实例的流量重新路由到新的IDS实例。但是,由于在新的IDS实例中没有用于处理先前流量的状态信息,很可能会导致错误的数据报处理。为解决这个问题,SDN控制程序可以等待某些经过过载IDS的流量终止后,再重新路由流量到新的IDS实例,但这会造成低效的迁移并增加了违反SLA的风险。同时,由于某些NF状态信息没有被复制到新的NF实例或者在不同NF实例之间共享,NF处理流量的准确性也会受到影响。
在本例中,同时保证NF准确性、性能和流量迁移一致性的唯一方法是允许控制程序快速安全地将一些流的状态信息从原始实例移动到新实例,并同时更新路由策略。在SIGCOMM 2014会议上Aaron Gember-Jacobson等人提出了OpenNF,OpenNF提供了对NF状态和路由策略的高效、协调控制,从而允许在不同NF实例之间快速、安全、细粒度地重新分配流量,避免进行不必要的开销。
图1:一个需要通过NF迁出来满足SLA对吞吐量要求的场景。IDS 处理网络流量的拷贝,以检测HTTP流量中的端口扫描攻击和恶意流量。此时第一个IDS实例 (IDS1) 已经过载,如果将红色流量分配给第二个 IDS 实例来保证SLA,则必须更新SDN交换机的流表并迁移这条流所对应的状态信息来保证NF状态迁移的一致性。
实验内容
本实验展示了如何使用OpenNF迅速且安全地把一条TCP流量从一个NF实例迁移到另一个NF实例。
实验环境
Ubuntu 16.04,64位。
安装依赖
1.安装OpenNF控制器、NF共享库和本次实验所需的依赖软件:
1 |
sudo apt-get install git tcpreplay mininet ant oracle-java8-installer gcc make wget |
其中mininet推荐使用源码安装,参考:mininet安装;oracle-java8-installer安装,参考:oracle-java8-installer安装。
2.为了避免其他流量对本次实验的干扰,执行以下两条命令 (会造成断网):
1 2 |
sudo service openvswitch-controller stop sudo service network-manager stop |
4.本次实验我们用到了PRADS (一种被动监听网络流量,并获取网络上的主机和服务信息的网络功能)。安装PRADS的依赖软件:
1 |
sudo apt-get install libpcre3-dev libpcap-dev python-docutils |
下载Floodlight控制器和PRADS
1.创建一个名为tutorial的文件夹
1 |
mkdir tutorial |
2.下载floodlight-0.90的源代码并解压到tutorial目录下:
1 2 3 |
cd tutorial wget https://github.com/floodlight/floodlight/archive/v0.90.tar.gz tar xzvf v0.90.tar.gz |
3.下载PRADS的源代码到tutorial/目录下:
1 2 3 |
git clone https://github.com/gamelinux/prads.git cd prads git checkout 930ff5 |
下载OpenNF控制器源代码
必须在注册之后才能下载OpenNF的相关软件源码(注册链接)。注册登录后下载以下软件,并解压到tutorial/目录下。
- NF控制器:NF控制器代码。
- NF共享库:用C语言写的提供给NF的共享库,用于控制NF和NF控制器之间的通信。
- 应用代码:使用OpenNF控制器的程序代码。
- PRADS patch:PRADS补丁,用来修改PRADS以支持OpenNF。
- Mininet拓扑脚本:本次试验用到的mininet 拓扑脚本。
编译PRADS源码
1.编译网络功能共享库:
1 2 3 |
cd tutorial/shared/ make sudo make install |
注:执行这一步时,遇见以下错误:
1 2 3 |
SDMBNJson.h:9:23: fatal error: json/json.h: No such file or directory #include <json/json.h> compilation terminated. |
错误原因:在编译网络功能共享库的过程中,gcc编译器无法找到json-c头文件。
解决方案:
编译在Linux系统中,/usr/include/ 是C/C++等的头文件放置处。因此将编译安装完成的json-c文件夹改名为“json”放在/usr/include/目录下,即可解决:
2.编译PRADS:
1 2 3 4 |
cd tutorial/prads/ patch -p1 < ../prads.patch make sudo make install |
编译OpenNF控制器
1.为了让Floodlight控制器支持OpenNF控制器,向位于/tutorial/floodlight/src/main/resources/META-INF/services/目录下Floodlight的model list文件(net.floodlightcontroller.core.module.IFloodlightModule)中添加如下几行:
1 2 |
edu.wisc.cs.wisdom.sdmbn.core.SdmbnManager edu.wisc.cs.wisdom.sdmbn.apps.testing.TestTimedMoveAll |
2.编译Floodlight控制器:
1 2 |
cd tutorial/floodlight/ ant |
3.链接库:
1 2 |
cd tutorial/controller/lib/ ln -s ../../floodlight-0.90/target/floodlight.jar |
4.下载GSON jar文件,并放入路径tutorial/controller/lib/下。
5.编译OpenNF控制器:
1 2 |
cd tutorial/controller/ ant |
6.编译应用:
1 2 |
cd tutorial/apps/ ant |
实验配置
1.修改OpenNF控制器配置文件 tutorial/apps/testTimedMoveAll.prop 中的一些参数:
1 2 3 4 5 6 |
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633 edu.wisc.cs.wisdom.sdmbn.core.SdmbnManager.stateport = 7790 edu.wisc.cs.wisdom.sdmbn.core.SdmbnManager.eventport = 7791 edu.wisc.cs.wisdom.sdmbn.apps.testing.TestTimedMoveAll.TraceReplaySwitchPort = 1 edu.wisc.cs.wisdom.sdmbn.apps.testing.TestTimedMoveAll.TraceReplayHost = 192.168.0.1 edu.wisc.cs.wisdom.sdmbn.apps.testing.TestTimedMoveAll.TraceReplayFile = youtube.pcap |
2.由于本次实验需要收集大量的TCP数据报,通过重放这些数据报到NF实例,来模拟NF过载的场景。我们通过tcpdump来抓包,建议在抓包时浏览网页或观看视频,增加NIC收到的数据包,加速抓包的过程。
1 2 |
cd tutorial/apps tcpdump -i <本机的活动端口,比如eth0> -c 25000 -w youtube.pcap tcp |
3.修改NF共享库中的配置文件 /usr/local/etc/sdmbn.conf:
1 |
ctrl_ip = 192.168.0.254 |
运行实验
1.启动OpenNF控制器,等待连接6633端口:
1 2 |
cd tutorial/apps/ java -jar SDMBNapps.jar -cf testTimedMoveAll.prop |
2.新建终端,运行实验拓扑。连接成功时控制器端会有新交换机连接的提示:
1 2 |
cd tutorial/ sudo python tutorial_topo.py |
3.开启三个主机的xterm:
1) H1:等待控制器命令,重放TCP流量;
2) H2:运行PRADS实例
3) H3:运行PRADS实例
1 |
mininet> xterm h1 h2 h3 |
4.在h1的xtrem中执行:
1 2 |
cd tutorial/apps/ bash scripts/traceload_server.sh h1-eth0 . 192.168.0.1 8080 |
5.在h2的xtrem中执行:
1 |
prads -i h2-eth0 |
6.在h3的xtrem中执行:
1 |
prads -i h3-eth0 |
7.这时,假设一切正常,将会看到如下事件发生:
1) 控制器终端感知到从主机h2、h3发来的PRADS连接请求;
2) 控制器向h1发出指令,重放TCP流量;
3) 在h1上,开始重放TCP数据报,而主机h2上的PRADS实例接收到了大量的数据报;
4) 几秒钟后,控制器启动状态迁移;
5) 停止向主机h2发送数据报,向主机h3迁移流量;
6) 在h2、h3上体现出状态迁移:
8.实验结束时,效果如图所示:
总结
本文对在SIGCOMM 2014提出的OpenNF进行了简单的介绍,并对OpenNF教程中的实验进行了复现。我们首先详细介绍了实验环境的搭建过程,然后通过收集并重放TCP流,模拟了NF实例过载的场景,最后经过OpenNF控制器的调度,在保证状态迁移一致性、准确性的前提下,实现了最小开销的状态迁移。
参考资料
1.OpenNF tutorial:http://opennf.cs.wisc.edu/tutorial
2.Gember-Jacobson, Aaron , et al. “OpenNF: enabling innovation in network function control.” Acm Conference on Sigcomm ACM, 2014.
3.Floodlight:http://www.projectfloodlight.org/
4.PRADS:https://github.com/gamelinux/prads
5.Json-c:https://github.com/json-c/json-c
6.SDNlab:https://www.sdnlab.com/