基于模拟实验理解SDN与传统路由交换网络的关系
【前言】
近年来,随着“云架构”或者“新基建”等概念不断被提及,以及与之相关的IT项目落地,SDN(软件定义网络)也随之被炒热,加上媒体或者许多培训机构因为各种目的所进行的“夸张”宣传,使得许多人尤其是相当部分的传统网络工程师认为这一技术将革命性颠覆传统网络协议,甚至会淘汰掉不会编程的网络工程师。针对于“SDN会不会使得传统网络工程师丢掉‘饭碗’”这个问题,答案应是否定的,即SDN的出现不会淘汰掉传统的网络工程师,但会对传统网络工程师职业发展构成挑战。这个答案是个人基于现阶段各类解决方案中,SDN和传统路由交换网络之间的关系所得出的。本文将通过个人近期对SDN的理论学习以及相关实验,阐述一下个人不成熟的看法,一是对相关学习做出总结;二是基于个人认知对SDN做出客观评价;三是对希望了解SDN的朋友提供一些学习方法建议。因水平有限,文章内容可能会有错误之处,欢迎批评指正。
【SDN入门的“三座大山”(学习门槛)】
个人认为,现阶段在国内互联网的资源之下,相对于传统路由交换网络,SDN的初学成本是比较高的,这个成本并不是物质上的成本,而是时间和精力上的成本,本人学习SDN所遇到的问题,主要有以下特点:
1、国内互联网暂无技术中立且成体系的SDN教程,中文资料也相对不足;
2、模拟器匮乏,使得少有机会接触到真实设备的工程师进行实验不便利;
3、学习门槛相对较高,在无法接触真实设备的前提下,仅有的Mininet仿真环境要求学习者有一定的Linux和Python基础。
【个人对“三座大山”问题的解决】
1、针对于SDN教程零散不中立且不成体系的问题,只能将零散的教程在学习进行汇总。 个人了解到,大部分的传统网络工程师都知道SDN最大的特点是“转控分离”,且听说过广泛用于南向接口的OpenFlow协议,但对于“转控分离”如何实现却并不是很理解。在这样的前提下,个人建议首先对SDN的概念有一个初步认识,并SDN模拟器Mininet的操作进行学习,这个步骤可以在bilibili上搜索到课程,链接为:https://www.bilibili.com/video/BV1VJ41117vJ,除此之外,文字性的博客文章,网络上也有很多可供查阅。
在完成上述步骤,并通过Mininet模拟器对SDN有一个感性认识后,接下来可以对华为的HCIA-SDN和HCIP-SDN认证课程进行学习。 需要注意的是,这两个认证课程虽然成体系,但夹杂有华为自己的产品特性在里面,因此在这一点上学习者需要对这些“私有”的东西进行筛选,使得自己所学的知识是通用和中立的。由于在此阶段学习中,相关的实验是在华为Agile Controller-DCN以及相关硬件设备下进行的,而这些设备对于绝大部分人而言是很难获得,因此学习者需要将相关实验中立和通用的部分迁移到Mininet上进行。这一阶段完成后,就需要寻找相关“大部头”资料进行学习,去了解各种使用场景,比如华为、H3C、VMware的技术文档和书籍。
2、SDN模拟器比较匮乏,和传统网络拥有ensp、HCL、eve-ng、GNS3等不同,目前可用于SDN实验的模拟器仅有Mininet一种,并且该模拟器只能在Linux环境下运行,并且需要使用者具有一定的Linux基础和Python基础,用于通过Python脚本创建拓扑以及进行Mininet安装配置和流表操作(流表是SDN网络中的一个重要概念,SDN不再通过传统转发表项进行二层转发,而是通过流表项),如果对Python不是太熟悉,也可以使用Mininet的可视化工具Miniedit,但Mininet仍旧有不足之处,比如在模拟SDN的东西向接口有很大局限性,所谓东西向接口并不是SDN的标准名词,而是一个俗称,是指SDN网络作为一个网络域,通过BGP等域间协议,与传统网络对接。
3、针对于需要使用者具有Linux基础和Python基础的问题,这一点主要是针对于Mininet的使用而言。在真实的SDN网络下,则不需要网络工程师拥有这两个基础,也不需要网络工程师去写脚本程序。但个人仍旧建议网络工程师需要掌握Linux和Python,这并不是因为SDN本身,而是因为在某些情况下,Linux可以实现的网络功能会比路由器交换机更加丰富(如链路聚合),而通过Python编写自动化脚本则可以使网络工程师减少很多重复性劳动。
【从架构的角度看SDN和传统网络的关系】
SDN和传统路由交换网络的联系,主要是由以下问题建立的:
因为SDN具有转控分离的特点,各个交换机(转发器)仅有转发平面而不具有控制平面,控制平面主要由SDN控制器承担,这也就决定了转发器在没有SDN控制器的情况下无法识别和转发任何网络数据。由此产生了一个矛盾点——SDN网络组建初期,转发器和控制器之间的连接应当怎样去建立?
针对于这个问题,答案只能是通过传统路由交换网络去建立起转发器和控制器之间的连接。我们通过查看开源的SDN控制器Ryu,发现可供我们使用的设备主要是以OpenFlow交换机为主。也就是说,SDN在基于二层网络的通信上有很大的作用。由于在数据中心中,大部分网络架构的核心层都是以三层通信为主,而要想在传统三层网络中通过二层通信使得转发器和转发器之间,转发器和控制器之间建立连接,可以使用的技术就基本都是VXLAN了,而在骨干网上,SDN也可以承载于三层网络之上。众所周知,VXLAN是一个典型的overlay网络,而SDN在绝大多数情况下承载于VXLAN网络之上,因此SDN也属于overlay网络之一。而至于underlay网络,则是诸如OSPF、ISIS、IBGP等传统协议构成的。
对于SDN网络的架构,则如下图所示:
总而言之,上面的描述一直表达的都是这样的结论——传统路由交换网络充当的是“地基”,而SDN则是上层建筑;因为SDN建立初期转发器不具备识别和转发任何数据的能力,因此它们要想建立起通信,依赖于以VXLAN为首的传统网络。
【SDN控制器与转发器建立连接的过程】
[注:关于本小节理论参考来源为https://blog.csdn.net/qq_33240671/article/details/107106099 ,实验验证部分为原创]
通过前面的描述我们知道,SDN网络在建立初期依赖于传统网络,在传统网络中,各个SDN转发器就是普通的交换机,而SDN控制器本质上就是一台普通服务器,交换机和控制器之间建立连接的过程如下:
1、基于传统网络协议,控制器与交换机之间建立TCP连接;
2、基于建立起的TCP连接,控制器与交换机之间互发OpenFlow Hello报文,协商OpenFlow版本;
3、互发Hello消息后,控制器向交换机机发送Featrues Request消息,希望获取交换机的ID、缓冲区数量、端口信息等特性,交换机会将相应信息封装在Features Reply报文中回复控制器;
4、set config是控制器用来配置交换机发送的数据包;
5、当流表中没有关于新到达流的数据包或者即使有关于新到达流的流规则但其行为是发往控制器的时候,交换机向控制器发送Packet In消息;
6、Packet Out消息是控制器指定的某个数据包的处理方法。
上述过程我们可以通过实验来观察并验证,实验拓扑如下:
实验步骤为:
1、在Linux系统下,进入预先已经安装完成的Ryu控制器目录,通过ryu-manager命令选择其中一种类型的交换机用于将SDN控制器的流量转发出去,选择完成后,程序将自动创建一个SDN控制器;(本实验选择的是simple_switch_stp_13.py,此交换机表示其支持OpenFlow1.0~OpenFlow1.3协议,并且在SDN建立完成之前运行STP协议来防止环路发生)
2、以root权限打开wireshark,选择环回接口lo进行抓包,命令如下:
3、编写Python脚本,创建网络拓扑,此拓扑仅创建了一个交换机,相关脚本如下:
4、事先安装完Mininet的前提之下,在Linux终端中,进入到Python脚本所在目录,输入命令“sudo mn --custom ./SDN_example.py --topo MyTopo --controller=remote,ip=127.0.0.1,port=6653 --switch ovsk,protocols=OpenFlow13”来启动Mininet模拟器,运行步骤2中编写的SDN_example.py脚本,并与SDN控制器建立连接;(此命令含义为:通过sudo(root权限)运行代表Mininet的mn指令,拓扑为SDN_example.py中的MyTopo类,SDN控制器类型为远端控制器,其IP地址为127.0.0.1,端口为6653,即真实电脑本身,交换机类型为OVSK交换机,并运行OpenFlow1.3协议)
5、进入wireshark界面进行观察,我们可以观察到如下图所示的报文交互过程:(由于是仿真环境,交换机和控制器之间的IP地址均为127.0.0.1)
通过以上几个步骤,SDN控制器与交换机之间的连接建立完成。
【通过下发体现SDN三个基本层次】
SDN网络具有三层,他们分别是应用层、集中控制层和基础设施层,其中基础设施层代表的是硬件设备,集中控制层代表的SDN控制器,而应用层则是基于控制层给出的北向接口开发出的软件应用,通常情况下,网络工程师对SDN网络进行配置就是基于这些处于应用层的应用软件进行流表等配置下发。
下面我们可以通过实验来体现这个层次。实验拓扑如下:
1、编写Python脚本创建拓扑(图中addSwitch()函数的参数dpid指的是Datapath ID,它是由OpenFlow实例ID和设备桥MAC组成,前16个比特是OpenFlow实例ID,后48个比特是设备桥MAC。):
2、启动SDN控制器Ryu:
[注:Restful api是SDN北向接口之一,在mininet中,使用Postman可以通过这个接口进行流表操作]
4、启动mininet并运行Python脚本:
5、确认此时转发器只有到控制器的流表,而没有其他流表:
[知识点扩充:通过上面的初始流表我们发现,每一台设备都有一条前往SDN控制器的流表,因此在相关网络部署中,SDN控制器的逻辑部署位置应当等同于SNMP服务器,分为带外管理和带内管理,一般情况下都使用带外管理,和业务流量隔离]
6、在mininet视图下,通过links命令查看设备接口情况:
7、根据步骤6中的接口详情,来下发流表,下发流表的方式有很多,这里我们在Linux系统视图下使用ovs-ofctl命令来下发流表:
8、在mininet查看流表信息并进行联通性测试:
下图为联通性测试,造成PC2、PC3和PC4无法通信的原因是因为生成树的计算造成了相关接口的阻塞,但需要注意的是,SDN本身是没有生成树的概念的,相关生成树计算是在SDN网络形成之前的传统网络阶段所进行的,待SDN网络形成后,控制器会根据之前生成树计算的结果,向相关接口自动下发行为(action)为drop的流表,代表这个接口会丢弃所有的数据包:
在上述步骤7中,我们可以通过调用Restful api接口来对流表进行操作,需要注意的是,如果要使用Restful api接口,需要在个人电脑上自行安装Postman等应用(Postman有单独的客户端版本,也有基于Google Chrome的插件版本),以及在启动Ryu执行ryu-manager命令时添加“ofctl-rest.py”参数(如步骤7的红箭头)。
一切都成功运行后,打开Postman,成功进入后的界面如下:
此时,我们可以进行对流表进行增删改查等操作,此处我们通过输入url查看了转发器1的流表,该流表默认使用json语言显示的:
个人观点,如果仅是为了使用mininet做实验,建议使用ovs-ofctl命令,因为这个命令的参数书写规则比较统一,不会因为控制器的改变而改变,而通过Restful api接口下发流表的差异就比较大,比如说Ryu控制器和OpenDayLight控制器风格就不同。有关于ovs-ofctl的参数,网络上已经列举得比较详细了,此处不累述,而针对于mininet内转发器的流表操作语法,按照前文步骤7中的风格即可。
根据上述例子,在使用ovs-ofctl命令下发流表时,应用层是真实的Linux电脑本身,ovs-ofctl相当于调用了真实电脑和Ryu控制器之间的北向接口。ovs-ofctl命令原本是为了对Linux内置的OpenvSwitch进行操作,但mininet+相关Python脚本启动和执行完成后,会促使Linux创建相关的OpenvSwitch虚拟网卡来提供抓包和连接远端SDN控制器之用。
而在调用Postman+Restful api这种方式上,应用层是Postman,北向接口则是Restful api接口。
在mininet中,应用层通过北向接口打通集中控制层Ryu,Ryu再通过南向接口协议OpenFlow打通转发器,不过在真实SDN中,南向接口则不一定是OpenFlow。
【SDN并非适用所有场景】
1、以下只是基于个人结合互联网上的观点举出的三个例子:
2、由于目前SDN尚在发展阶段,并且在商业化的过程中涉及到了多方利益(尤其是思科、华为等传统网络设备制造商的利益),导致了“交换机白牌化”这一目标暂时无法实现,从而导致了各个厂商之间的SDN解决方案是互不兼容的,尽管OpenFlow是通用的标准协议,但SDN不等同于OpenFlow。所以,在不适合被单一设备厂商“绑定”的场景下,SDN并不适合。
3、由于SDN相对于传统网络来说,缺乏大规模落地的项目案例,因此在可靠性和技术成熟度上是未知的,因此,在诸如运营商基础骨干网这一场景下,为求绝对稳定,对于SDN或者NFV的部署总体持观望态度。
4、在网络规模不大的前提之下,没有必要花费更大的物质和技术成本去部署SDN。
【总结(个人观点)】
回到本文的主题,本文主要是通过现有解决方案和模拟实验论证以下观点:
1、SDN与传统路由交换网络的关系为——传统网络是“地基”,SDN是上层建筑,可以说在现有的解决方案下,没有传统路由交换网络也就没有SDN;
2、未来,商业化的SDN不会取代传统路由交换网络,传统网络工程师也不会因此失业,它只是作为现有网络的一个新技术补充而非取代,但新技术的出现会对传统网络工程师的职业发展构成挑战,所以在这样的前提之下,传统网络工程师必须去积极掌握这一技能。
【附:本文实验脚本代码及注释】
1、实验:交换机与SDN控制器建立连接过程的拓扑脚本 SDN_example.py:
2、实验2:通过一个实验拓扑阐明SDN对比传统网络之间优势-拓扑脚本 SDN_tranditionalNet_compare.py:
————————————————
版权声明:本文为CSDN博主「木下-俱欢颜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/muxia_jhy/article/details/109674829