SDN学习目录
1 基本概念
1.1 交换机
交换机(Switch)是一种在通信系统中完成信息交换功能的设备。它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。其他常见的还有电话语音交换机、光纤交换机等。目前,二层交换技术发展比较成熟,二层交换机(Layer 2 switches)是指只支持OSI第二层(数据链路层)交换技术的交换机。
1.2 工作原理
交换机拥有一条很高带宽的背部总线和内部交换矩阵。交换机的所有的端口都挂接在这条背部总线上,控制电路收到数据包以后,处理端口会查找内存中的地址对照表以确定目的MAC(网卡的硬件地址)的NIC(网卡)挂接在哪个端口上,通过内部交换矩阵迅速将数据包传送到目的端口,目的MAC若不存在,广播到所有的端口,接收端口回应后交换机会“学习”新的MAC地址,并把它添加入内部MAC地址表中,并刷新CAM表,表中有MAC地址,对应的端口号,端口所属的VLAN信息,交换机在二层转发数据时根据CAM表查找出端口。使用交换机也可以把网络“分段”,通过对照IP地址表,交换机只允许必要的网络流量通过交换机。通过交换机的过滤和转发,可以有效的减少冲突域,但不能划分广播域。交换机在同一时刻可进行多个端口对之间的数据传输。每一端口都可视为独立的网段,连接在其上的网络设备独自享有全部的带宽,无须同其他设备竞争使用。当节点A向节点D发送数据时,节点B可同时向节点C发送数据,而且这两个传输都享有网络的全部带宽,有着自己的虚拟连接。
1.3 作用与功能
交换机的常见功能如下:
- MAC地址学习:以太网交换机了解每一端口相连设备的MAC地址,并将地址同相应的端口映射起来存放在交换机缓存中的MAC地址表中。
- 转发/过滤:当一个数据帧的目的地址在MAC地址表中有映射时,它被转发到连接目的节点的端口而不是所有端口(如该数据帧为广播/组播帧则转发至所有端口)。
- 消除回路:当交换机包括一个冗余回路时,以太网交换机通过生成树协议避免回路的产生,同时允许存在后备路径。
2 Open vSwitch (OVS)
在网络中,交换机和桥概念类似,Open vSwitch是一个虚拟交换软件,也就是说,Open vSwitch实现了网桥的功能。学习Open vSwitch的第一步要弄清楚网桥的概念。网桥是连接两个局域网的设备,工作在数据链路层,根据MAC地址来转发帧。在Open vSwitch中创建一个网桥后,此时网络功能不受影响,但是会产生一个虚拟网卡,之所以会产生一个虚拟网卡,是为了实现接下来的网桥(交换机)功能。有了这个网桥以后,还需要为这个网桥增加端口(port),一个端口就是一个物理网卡,当网卡加入到这个网桥之后,其工作方式就和普通交换机的一个端口的工作方式类似了。以下是一个网桥的具体信息:
Open vSwitch(OVS)是一个高质量的、多层虚拟交换机。OVS遵循开源Apache2.0许可,通过可编程扩展,OVS可以实现大规模网络的自动化(配置、管理、维护),同时支持现有标准管理接口和协议(比如NetFlow、sFlow、SPAN、RSPAN、CLI、LACP、802.1ag等)。此外OVS支持多种Linux虚拟化技术,包括Xen/XenServer,KVM,和VirtualBox等。虽然是虚拟交换机,但是其工作原理与物理交换机类似。在虚拟交换机的实现中,其两端分别连接着物理网卡和多块虚拟网卡,同时虚拟交换机内部会维护一张映射表,根据MAC地址寻找对应的虚拟机链路进而完成数据转发。
OVS交换机有两种工作模式
- 一种为SDN交换机,另一种为普通交换机。作为SDN交换机时,显示Fail_mode为Secure,在这种模式下OVS交换机需要控制器发送转发规则,指挥交换机去工作
- 作为普通交换机时,显示Fail_mode是Standalone。其和物理交换机工作模式一样,记录端口号和MAC地址的对应关系,基于对应关系转发数据帧。交换机默认状态是SDN交换机。
OVS 架构分为三个部分:
- 内核空间:包含了流表(Flow Table)和Datapath模块(类似于网桥,主要负责对数据分组进行操作)。
- 用户空间:运行着OVS的守护进程(Open vSwitch Daemon, vswitchd)和数据库(Open vSwitch Database, ovsdb),他们是ovs的核心功能模块。
- vswitchd类似于OVS的心脏,维持OVS的声明周期。可以配置一系列特性:
- 基于MAC地址学习的二层交换
- 支持IEEE802.1Q VLAN
- sFlow监测
- 连接OpenFlow控制器
- 通过Netlink协议与内核模块Datapath直接通信
- ovsdb相当于OVS的大脑,存储OVS的配置信息和数据流信息。
- vswitchd类似于OVS的心脏,维持OVS的声明周期。可以配置一系列特性:
- 配置管理层:包括ovs-dpctl, ovs-ofctl, ovs-appctl, ovs-vsctl和ovsdb-tool等,主要用于和vswitchd,ovsdb之间进行交互操作以及ovs的安装配置和部署
3. OVS安装使用
OVS可以运行在任何基于Linux的虚拟化平台,包括KVM, VirtualBox, Xen等,其代码都是基于C编写,所以易于移植到其他环境。安装有两种方法:一种通过二进制文件安装apt-get;另外一种是源码安装。
3.1 ovs安装
docker 安装参见【Ubuntu安装Docker与最常用配置】
1 | docker pull ubuntu |
note:进入容器后,若发现无法联网请参见文章【Docker容器内网络无法连接】
3.2 ovs-vsctl 命令使用
ovs-ovsctl命令是对交换机上网桥和端口等信息进行配置的命令。获取或者更改ovs-vswitchd的配置信息,此工具操作的时候会更新ovsdb-server中的数据库。下面的操作需要连接控制器,控制器的安装可以参考【OpenDaylight安装】
1 | ## 查看网桥 |
ovs连接控制器成功后,可在opendaylight界面看到:
ovs连接本地docker容器后,可以在OpenDaylight界面看到:
1 | ## 查看docker容器的网卡物理地址 |
ovs连接容器方法有诸多坑存在,将单独整理一篇文章讲解
上面说到,创建桥的时候会创建一个和桥名字一样的接口,并自动作为该桥的一个端口,那么这个虚拟接口的作用,一方面是可以作为交换机的管理端口,另一方面也是基于这个虚拟接口实现了桥的功能。Open vSwitch的内核模块实现了多个“数据路径”,每个都可以有多个vports。每个数据路径也通过关联流表(flow table)来设置操作,而这些流表中的流都是用户空间在报文头和元数据的基础上映射的关键信息,一般的操作都是将数据包转发到另一个vport。当一个数据包到达一个vport,内核模块所做的处理是提取其流的关键信息并在流表中查找这些关键信息,当有一个匹配的流时它执行对应的操作,如果没有匹配,它会将数据包送到用户空间的处理队列中,作为处理的一部分,用户空间可能会设置一个流用于以后碰到相同类型的数据包可以在内核中执行操作。
ovs-vsctl关于网桥管理的常用命令如下:
命令 | 含义 |
---|---|
init | 初始化数据库(前提数据分组为空) |
show | 打印数据库信息摘要 |
add-br BRIDGE | 添加新的网桥 |
del-br BRIDGE | 删除网桥 |
list-br | 打印网桥摘要信息 |
list-ports BRIDGE | 打印网桥中所有port摘要信息 |
add-port BRIDGE PORT | 向网桥中添加端口 |
del-port [BRIDGE] PORT | 删除网桥上的端口 |
get-controller BRIDGE | 获取网桥的控制器信息 |
del-controller BRIDGE | 删除网桥的控制器信息 |
set-controller BRIDGE TARGET | 向网桥添加控制器 |
3.3 ovs-ofctl 命令使用
ovs-ofctl 命令是对流表的操作,包括对流表的增,删,改,查等命令。简单来说流表类似于交换机的MAC地址表,路由器的路由表,是ovs交换机指挥流量转发的表。
OpenFlow是用于管理交换机流表的协议,ovs-ofctl是Open vSwitch提供的命令行工具。在没有配置OpenFlow控制器的模式下,用户可以使用ovs-ofctl命令通过OpenFlow协议连接Open vSwitch来创建、修改或删除Open vSwitch中的流表项,并对Open vSwitch的运行状况进行动态监控。ovs-ofctl关于流表管理的常用命令如下表所示:
对于add-flow、add-flows和mod-flows这3个命令,还需要指定要执行的动作actions=[target],[target]…,一个流规则中可能有多个动作,按照指定的先后顺序执行。
常见的流表操作如下表所示
在OpenFlow白皮书中,Flow被定义为某个特定的网络流量。例如,一个TCP连接就是一个Flow,或者从某个IP地址发出来的数据包,都可以被认为是一个Flow。支持OpenFlow协议的交换机应该包括一个或多个流表,流表中的条目包含:数据包头的信息、匹配成功后要执行的指令和统计信息。当数据包进入OVS后,会将数据包和流表中的流表项进行匹配,如果发现了匹配的流表项,则执行该流表项中的指令集。相反,如果数据包在流表中没有发现任何匹配,OVS会通过控制通道把数据包发到OpenFlow控制器中。在OVS中,流表项作为ovs-ofctl的参数,采用如下的格式:字段=值,如果有多个字段,可以用逗号或空格分开,一些常用的字段列举如下表所示。