OpenFlow与Open vSwitch简介

叁叁肆2018-10-25 11:00

此文已由作者徐城利授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


SDN与OpenFlow

传统的网络架构中,网络流量的转发、处理都是由每个网络设备自己控制,在现在的网络环境中,限制越来越明显:

  • 每个供应商在实现自己的设备时,都有各自不同的策略,导致采购新设备时对供应商有依赖

  • 单独的网络设备缺乏足够的信息来保证全局上的优化

  • 规划与管理上不利于扩容

  • 网络的复杂导致运维人员更倾向于保持现状,不愿意做可能影响稳定性的变动

为了解决这些问题,业务引入了SDN (Software-defined networking),将网络功能从底层设备抽象出来,上层控制平面决定流量的最终路径,底层网络设备只进行转发工作 (数量平面)。通过SDN,能够在一定程度上简化网络复杂性,提高网络的灵活性和扩容能力。
由SDN的定义可以看出,在控制面和数据面之间需要一套标准的方法进行交互,其中使用比较广泛的一种便是OpenFlow。OpenFlow定义了访问网络转发设备 (交换机和路由器) 的标准通讯协议。现在OpenFlow标准由Open Networking Foundation (ONF)管理,当前最新的版本是1.4。

理解OpenFlow规则

OpenFlow中定义了交换机和控制器之间的通讯接口、支持OpenFlow设备的要求等一系列标准,不过作为普通用户,可能更希望了解通过OpenFlow能做到什么,因此我们可以简单的看一下OpenFlow本身定义的一些流表规则。 为了方便起见,我们以Open vSwitch中使用的语法作为例子。

匹配过程

OpenFlow交换机可以有一个或多个流表(Flow Table),在每张流表中按优先级查找任务匹配的流规则,根据匹配的规则执行相应的指令 (转发到指定端口、修改包内容、提交到另外一张流表继续查找等),如果没有任何匹配规则就执行默认行为 (根据不同的设置,可能包被丢弃或作标准交换机转发行为)。 
过程如上图所示 (图片来自于网络)

流规则

简单来说,每条流由流描述(Flow Description)和行为(Actions)组成,前者用于查找匹配,后者在匹配的执行相应的操作,例如:

table=1,priority=1,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21)

表示在流表1中查找匹配MAC地址是(01:00:00:00:00:00/01:00:00:00:00:00)的包,并转发到流表21继续查找。

流描述

在OpenFlow中,可以通过一系列field=value对来描述具体一类流量,常用的有:

Field Value
in_port 交换机上的OpenFlow端口号
dl_vlan 包的VLAN ID
dl_src / dl_dst 数据链路层的源/目标地址 (以太网中的MAC地址)
dl_type 以太协议中的类型,如0x8000是IP包,0x8060是ARP包
nw_src / nw_dst 网络层源/目标地址,如IP协议中就是源/目标地址,ARP中是SPA/TPA
nw_proto 网络层协议中的协议字段,跟dl_type配合决定L4协议,如dl_type=0x0800,nw_proto=6表示是TCP包
tp_src / tp_dst L4包地址,如TCP协议中的源端口/目标端口
imcp_type / icmp_code 当dl_type和nw_proto指定是ICMP时,匹配ICMP的类型和代码
table 指定规则生效的流表
tun_id 隧道ID
tun_src / tun_dst 隧道的源/目标地址

其他可参考OpenFlow协议规范,或Open vSwitch相应文档

匹配到具体一类流后,可以执行相应的行为,主要有:

Actions Descriptions
output 把包发往指定的端口
normal 按交换机传统L2/L3过程处理
flood 把包发住除输入端口和禁用Flood的端口外的所有端口
all 把包发住输入端口外的所有端口
controller 把包发住controller
local 把包发往Bridge对应的网络设备
in_port 将包发回输入端口,原端口返回
drop 直接丢弃包
mod_vlan_vid / strip_vlan / push_vlan 在以太帧中修改/去除/增加VLAN ID
mod_dl_src / mod_dl_dst / mod_nw_src / mod_nw_dst / mod_tp_src / mod_tp_dst 修改L2/L3/L4的源/目标地址
resubmit([port],[table]) 在指定的table重新查找,并将in_port调成指定的端口
set_tunnel 设置隧道ID

其他可参考OpenFlow协议,或Open vSwitch相应文档

Open vSwitch是什么?

Open vSwitch是一个满足生产环境要求的多层虚拟交换机,它支持大量传统交换机的功能,如L2转发、sFlow/NetFlow管理接口、LACP、802.1ag等,同时也支持OpenFlow,在不少系统中作为虚拟化的VEB使用。

模块

Open vSwitch主要由以下几部分组成:

  • datapath:负责数据转发的快速通道(fast-path),有多种实现,用的比较多的是Linux内核模块,对应OpenFlow中的转发设备

  • vswitchd:Open vSwitch用户态的后台进程,主要根据Datapath上传的包,查找相应的流规则并下发到Datapath中,同时负责处理接口调用和给Datapath下发控制指令等。

  • ovsdb:保存了Open vSwitch中Bridge、Port、Interface等的信息

  • 客户端:为了方便使用,Open vSwitch还提供了一些客户端工具,如ovs-vsctl、ovs-ofctl、ovs-appctl、ovs-dpctl等

Open vSwitch的简单用法

这个例子中,我们创建一个简单的虚拟交换机来演示下Open vSwitch的用法

创建一个Bridge (虚拟交换机)

ovs-vsctl add-br br-test

并将一个网卡绑定到虚拟交换机上

ovs-vsctl add-port br-test eth0

或创建一个Internal类型的Port并连接到虚拟交换机上

sudo ovs-vsctl add-port br-test p1 -- set Interface p1 type=Internal

可以查询虚拟交换机的状态

% sudo ovs-vsctl show
    Bridge br-test
        Port br-test
            Interface br-test                type: internal
        Port "p1"
            Interface "p1"
                type: Internal
    ovs_version: "2.0.2"

Open vSwitch可以在不使用外部Controller的情况下,给虚拟交换机设置OpenFlow规则

 sudo ovs-ofctl add-flow br-test in_port=1,ip,nw_src=192.168.1.0/24,actions=drop

也可以通过ovs-ofctl查询现有的规则

% sudo ovs-ofctl dump-flows br-test
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=50.745s, table=0, n_packets=0, n_bytes=0, idle_age=50, ip,in_port=1,nw_src=192.168.1.0/24 actions=drop
 cookie=0x0, duration=497.698s, table=0, n_packets=8, n_bytes=648, idle_age=488, priority=0 actions=NORMAL

通过ovs-ofctl设置的规则都是保存在用户态的vswitchd中,只有当Datapath检测到无法匹配的流时才会查询,我们也可以通过ovs-dpctl查看Datapath中真正匹配生效的流

sudo ovs-dpctl dump-flows

Open vSwitch还通过ovs-appctl ofproto/trace提供了调试功能

admin@10-165-0-64:~$ sudo ovs-appctl ofproto/trace br-int in_port=716,dl_src=fa:16:3e:03:d8:36,dl_dst=00:07:b4:01:32:01,dl_type=0x0800,nw_src=10.165.136.72,nw_dst=172.17.2.144
Bridge: br-int
Flow: ip,metadata=0,in_port=716,vlan_tci=0x0000,dl_src=fa:16:3e:03:d8:36,dl_dst=00:07:b4:01:32:01,nw_src=10.165.136.72,nw_dst=172.17.2.144,nw_tos=0,nw_ecn=0,nw_ttl=0
Rule: table=0 cookie=0 priority=1
OpenFlow actions=NORMAL
no learned MAC for destination, flooding

        Resubmitted flow: ip,metadata=0,in_port=1,dl_vlan=7,dl_vlan_pcp=0,dl_src=fa:16:3e:03:d8:36,dl_dst=00:07:b4:01:32:01,nw_src=10.165.136.72,nw_dst=172.17.2.144,nw_tos=0,nw_ecn=0,nw_ttl=0
         Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
        Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
        Rule: table=0 cookie=0 priority=1,in_port=1
        OpenFlow actions=resubmit(,1)

                Resubmitted flow: unchanged
                Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
                Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
                Rule: table=1 cookie=0 priority=1,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00
                OpenFlow actions=resubmit(,20)

                        Resubmitted flow: unchanged
                        Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
                        Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
                        Rule: table=20 cookie=0 priority=0
                        OpenFlow actions=resubmit(,21)

                                Resubmitted flow: unchanged
                                Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
                                Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
                                Rule: table=21 cookie=0 priority=0
                                OpenFlow actions=drop

        Resubmitted flow: unchanged
        Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
        Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
        Rule: table=0 cookie=0 priority=1,in_port=1,dl_vlan=7
        OpenFlow actions=resubmit(,30)

                Resubmitted flow: unchanged
                Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
                Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
                Rule: table=30 cookie=0 priority=1,ip,in_port=1,nw_src=10.165.136.64/26,nw_dst=172.17.0.0/20
                OpenFlow actions=output:2

                        Resubmitted flow: unchanged
                        Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
                        Resubmitted  odp: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12
                        Rule: table=0 cookie=0 priority=2,in_port=1,dl_vlan=7
                        OpenFlow actions=mod_vlan_vid:306,NORMAL
                        forwarding to learned port

Final flow: ip,metadata=0,in_port=716,vlan_tci=0x0000,dl_src=fa:16:3e:03:d8:36,dl_dst=00:07:b4:01:32:01,nw_src=10.165.136.72,nw_dst=172.17.2.144,nw_tos=0,nw_ecn=0,nw_ttl=0
Relevant fields: skb_priority=0,ip,in_port=716,vlan_tci=0x0000,dl_src=fa:16:3e:03:d8:36,dl_dst=00:07:b4:01:32:01,nw_src=10.165.136.64/28,nw_dst=172.17.2.144,nw_proto=0,nw_frag=no
Datapath actions: push_vlan(vid=7,pcp=0),11,pop_vlan,51,55,57,45,47,79,push_vlan(vid=7,pcp=0),12,pop_vlan,28

以上Open vSwitch一些简单的用法,更多功能请参考相应文档


网易云免费体验馆,0成本体验20+款云产品! 

更多网易技术、产品、运营经验分享请点击




相关文章:
【推荐】 Android之高效率截图
【推荐】 微服务监控探索
【推荐】 nova状态同步