SDN & OpenFlow & Open vSwitch
SDN
SDN(软件定义网络)是一个概念、是一个思想、一个框架、是一种网络设计理念,它有三个特征
- 控制平面与转发平面分离
- 控制平面集中化
- 网络可编程
OpenFlow
OpenFlow是控制平面和转发平面之间的通讯协议,类比编程中的概念,SDN可以看做是定义的接口,OpenFlow可以看做是接口的一种实现
Open vSwitch
Open vSwitch(下面简称为 OVS)是由 Nicira Networks 主导的,运行在虚拟化平台(例如 KVM,Xen)上的虚拟交换机。在虚拟化平台上,OVS 可以为动态变化的端点提供 2 层交换功能,很好的控制虚拟网络中的访问策略、网络隔离、流量监控等等。
Openvswitch的架构图如下所示
主要组成解释如下
- ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-based switching。
- ovsdb-server:轻量级的数据库服务,主要保存了整个OVS的配置信息,包括接口啊,交换内容,VLAN啊等等。ovs-vswitchd会根据数据库中的配置信息工作
- ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则
- ovs-vsctl:主要是获取或者更改ovs-vswitchd的配置信息,此工具操作的时候会更新ovsdb-server中的数据库
- ovs-appctl:主要是向OVS守护进程发送命令的,一般用不上
- ovsdbmonitor:GUI工具来显示ovsdb-server中数据信息
- ovs-controller:一个简单的OpenFlow控制器
- ovs-ofctl:用来控制OVS作为OpenFlow交换机工作时候的流表内容
Open vSwitch端口
端口是收发数据包的单元。OpenvSwitch中,每个端口都属于一个特定的网桥。端口收到的数据包会经过流规则的处理,发往其他端口;也会把其他端口来的数据包发送出去.主要有
Normal | 用户可以把操作系统中的网卡绑定到ovs上,ovs会生成一个普通端口处理这块网卡进出的数据包。 |
Internal | 端口类型为internal时,ovs会创建一块虚拟网卡,端口收到的所有数据包都会交给该网卡,发出的包会通过该端口交给ovs。当ovs创建一个新网桥时,默认会创建一个与网桥同名的Internal Port. |
Patch | 当机器中有多个ovs网桥时,可以使用Patch Port把两个网桥连起来。Patch Port总是成对出现,分别连接在两个网桥上,在两个网桥之间交换数据。 |
Tunnel | 隧道端口是一种虚拟端口,支持使用gre或vxlan等隧道技术与位于网络上其他位置的远程端口通讯。 |
Flow语法
Open vSwitch支持openflow协议,openflow channel 负责与controller进行交互,交换机基于流表(Flow Table)转发,每个流表包含许多流表项entry,每个entry是对数据包处理的规则,其主要组成如下图
match Fields(匹配字段)主要如下:
in_port=port | 传递数据包的端口的OpenFlow端口编号 |
dl_vlan=vlan | 数据包的VLAN Tag值,范围是0-4095,0xffff代表不包含VLAN Tag的数据包 |
dl_src=<MAC> dl_dst=<MAC> | 匹配源或者目标的MAC 地址 01:00:00:00:00:00/01:00:00:00:00:00(代表广播地址) 00:00:00:00:00:00/01:00:00:00:00:00(代表单播地址) |
dl_type=ethertype | 匹配以太网协议类型,其中: dl_type=0x0800代表IPv4协议、dl_type=0x086dd代表 IPv6协议、dl_type=0x0806代表ARP 协议 |
nw_src=ip[/netmask] nw_dst=ip[/netmask] | 当 dl_type=0x0800时,匹配源或者目标的IPv4地址,可以使IP地址或者域名 |
nw_proto=proto | 和dl_type字段协同使用。当 dl_type=0x0800时,匹配IP协议编号;当dl_type=0x086dd代表 IPv6协议编号 |
table=number | 指定要使用的流表的编号,范围是0-254。在不指定的情况下,默认值为0。通过使用流表编号,可以创建或者修改多个Table中的Flow |
reg<idx>=value[/mask] | 交换机中的寄存器的值。当一个数据包进入交换机时,所有的寄存器都被清零,用户可以通过Action的指令修改寄存器中的值 |
对于add−flow,add−flows和mod−flows这三个命令,还需要指定要执行的动作:actions=[target][,target...]。其中Priority为流表优先级,是一个0-65535之间的数字,值越大,优先级越高。一个流规则中可能有多个Instructions(动作),按照指定的先后顺序执行。
output:port | 输出数据包到指定的端口。port 是指端口的 OpenFlow 端口编号 |
mod_vlan_vid | 修改数据包中的 VLAN tag |
strip_vlan | 移除数据包中的 VLAN tag |
mod_dl_src/ mod_dl_dest | 修改源或者目标的 MAC 地址信息 |
mod_nw_src/mod_nw_dst | 修改源或者目标的 IPv4 地址信息 |
resubmit:port | 替换流表的 in_port 字段,并重新进行匹配 |
load:value−>dst[start..end] | 写数据到指定的字段 |
Cookie是用来标示一系列流的64位数字。
Flow处理过程
如果有多个流表,则数据包按流表id从小到大一次进行匹配,如下图所示
报文在一个流表中进行匹配是,找优先级最高的流表项进行匹配,如下图所示
Neutron
使用Overlay技术解决传统网络问题
大容量的MAC表项和ARP表项
- 4K VLAN Trunk问题
4K VLAN上限问题
虚拟机迁移网络依赖问题
相关概念
Neutron管理下面的实体:
- 网络:隔离的 L2 域,可以是虚拟、逻辑或交换。
- 子网:隔离的 L3 域,IP 地址块。其中每个机器有一个 IP,同一个子网的主机彼此 L3 可见。
- 端口:网络上虚拟、逻辑或交换端口。 所有这些实体都是虚拟的,拥有自动生成的唯一标示id,支持CRUD功能,并在数据库中跟踪记录状态。
网络
隔离的 L2 广播域,一般是创建它的用户所有。用户可以拥有多个网络。网络是最基础的,子网和端口都需要关联到网络上。
网络上可以有多个子网。同一个网络上的主机一般可以通过交换机或路由器连通起来。
子网
隔离的 L3 域,子网代表了一组分配了 IP 的虚拟机。每个子网必须有一个 CIDR 和关联到一个网络。IP 可以从 CIDR 或者用户指定池中选取。
子网可能会有一个网关、一组 DNS 和主机路由。不同子网之间 L3 是互相不可见的,必须通过一个三层网关(即路由器)经过 L3 上进行通信。
端口
可以进出流量的接口,往往绑定上若干 MAC 地址和 IP 地址,以进行寻址。一般为虚拟交换机上的虚拟接口。
虚拟机挂载网卡到端口上,通过端口访问网络。当端口有 IP 的时候,意味着它属于某个子网。
抽象系统架构
无论哪种具体的网络虚拟化实现,一个简化和抽象后的系统架构可以表述为下图所示(Neutron部署后什么样子的)。
- Virtualization Layer可以看做是一个大的虚拟交换机
- 启用 DVR 特性后允许东西向流量和带有 Floating IP 的南北向流量不经过网络节点的转发,直接从计算节点的外部网络出去
- VXLAN和GRE就是各个主机的Virtualization Layer聚合成一个大Virtualization Layer的技术
VXLAN模式
vxlan和gre模型差不多,只是隧道网桥br-tun(Virtualization Layer)的聚合方式不同,,vxlan是通过VNI来建立隧道连接,gre是通过GRE ID
参考文献
漫步云中网络
Overlay之VXLAN架构
OpenStack Neutron 架构指南
neutron的基本原理
世民谈云计算
深入理解neutron