Open Vswitch简介
什么是OpenvSwitch
OpenvSwitch,简称OVS是一个虚拟交换软件,主要用于虚拟机VM环境,作为一个虚拟交换机,支持Xen/XenServer, KVM, and VirtualBox多种虚拟化技术。
整个OVS代码用C写的。目前有以下功能:
- Standard 802.1Q VLAN model with trunk and access ports
- NIC bonding with or without LACP on upstream switch
- NetFlow, sFlow(R), and mirroring for increased visibility
- QoS (Quality of Service) configuration, plus policing
- GRE, GRE over IPSEC, VXLAN, and LISP tunneling
- 802.1ag connectivity fault management
- OpenFlow 1.0 plus numerous extensions
- Transactional configuration database with C and Python bindings
- High-performance forwarding using a Linux kernel module
- IPv6 support
- STP support
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交换机工作时候的流表内容
ovs结构图
ovsdb-server
ovs数据处理流程
流表的匹配
收到数据包后,会交给datapath内核模块处理,当匹配到对应的datapath会直接输出,如果没有匹配到,会交给用户态的ovs-vswitchd查询flow,用户态处理后,会把处理完的数据包输出到正确的端口,并且设置新的datapath规则,后续数据包可以通过新的datapath规则实现快速转发。
ovs相关概念
Packet
网络转发的最小数据单元,每个包都来自某个端口,最终会被发往一个或多个目标端口,转发数据包的过程就是网络的唯一功能。
Bridge
Open vSwitch中的网桥对应物理交换机,其功能是根据一定流规则,把从端口收到的数据包转发到另一个或多个端口。
Port
端口是收发数据包的单元。Open vSwitch中,每个端口都属于一个特定的网桥。端口收到的数据包会经过流规则的处理,发往其他端口;也会把其他端口来的数据包发送出去。
Open vSwitch支持的端口有以下几种:
- Normal Port: 用户可以把操作系统中的网卡绑定到Open vSwitch上,Open vSwitch会生成一个普通端口处理这块网卡进出的数据包
- Internal Port: 当设置端口类型为internal,Open vSwitch会创建一快虚拟网卡,此端口收到的所有数据包都会交给这块网卡,网卡发出的包会通过这个端口交给Open vSwitch。
Note: 当Open vSwitch创建一个新网桥时,默认会创建一个与网桥同名的Internal Port- Patch Port: 当机器中有多个Open vSwitch网桥时,可以使用Patch Port把两个网桥连起来。Patch Port总是成对出现,分别连接在两个网桥上,在两个网桥之间交换数据。
Interface
接口是Open vSwitch与外部交换数据包的组件。一个接口就是操作系统的一块网卡,这块网卡可能是Open vSwitch生成的虚拟网卡,也可能是物理网卡挂载在Open vSwitch上,也可能是操作系统的虚拟网卡(TUN/TAP)挂载在Open vSwitch上
Flow
流定义了端口之间数据包的交换规则。每条流分为匹配和动作两部分,匹配部分选择哪些数据包需要可以通过这条流处理,动作决定这些匹配到的数据包如何转发。流描述了一个网桥上,端口到端口的转发规则。比如我可以定义这样一条流:
当数据包来自端口A,则发往端口B
当数据包来自端口A,并且其源MAC是aa:aa:aa:aa:aa:aa,并且其拥有vlan tag为a,并且其源IP是a.a.a.a,并且其协议是TCP,其TCP源端口号为a,则修改其源IP为b.b.b.b,发往端口B
Datapath
Datapath是流的一个缓存,会把流的match结果cache起来,避免下一次流继续到用户空间进行flow match
flow table
每个 datapath都和一个“flowtable”关联,当 datapath接收到数据之后, OVS会在 flow table中查找可以匹配的 flow,执行对应的操作,例如转发数据到另外的端口
网桥的工作原理
网桥处理包遵循以下几条规则
- 在一个接口上接收到的包不会再往那个接口上发送此包
- 每个接收到的包都要学习其源MAC地址
- 如果数据包是多播或者广播包(通过2层MAC地址确定)则要向接收端口以外的所有端口转发,如果上层协议感兴趣,则还会递交上层处理
- 如果数据包的地址不能再CAM表中找到,则向接收端口以外的其他端口转发
- 如果CAM表中能找到,则转发给相应端口,如果发送和接收都是统一端口,则不发送
- 网桥是以混杂模式工作
相关操作
查看学习到的MAC地址
1
ovs-appctl fdb/show br0
创建网桥
1
ovs-vsctl add-br ovs-switch -- set Bridge br0 fail-mode=secure
创建端口p0并配置其OpenFlow端口编号为100
1
ovs-vsctl add-port br0 p0 -- set Interface p0 ofport_request=$i
设置端口设备类型为internal
1
ovs-vsctl set Interface p0 type=internal
查看创建的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[root@k8s201 ~]# ovs-vsctl show
aea2e0f0-9994-4703-9ff0-9ec12f3a1d50
Bridge "br0"
fail_mode: secure
Port "p1"
Interface "p1"
Port "br0"
Interface "br0"
type: internal
Port "p3"
Interface "p3"
Port "p2"
Interface "p2"
Port "p4"
Interface "p4"
ovs_version: "2.0.0"
[root@k8s201 ~]#查看所有的 flow table
1
ovs-ofctl dump-tables br0
查看流表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23[root@k8s201 ~]# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=7310.456s, table=0, n_packets=0, n_bytes=0, idle_age=7310, priority=0 actions=resubmit(,1)
cookie=0x0, duration=7357.2s, table=0, n_packets=0, n_bytes=0, idle_age=7357, dl_src=01:00:00:00:00:00/01:00:00:00:00:00 actions=drop
cookie=0x0, duration=7348.329s, table=0, n_packets=0, n_bytes=0, idle_age=7348, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
Notes: dump-flows字段解释
Cookie:流规则标识。
duration:流表项创建持续的时间(单位是秒)。
table:流表项所属的table编号。
n_packets:此流表项匹配到的报文数。
n_bytes:此流表项匹配到的字节数。
idle_age:此流表项从最后一个匹配的报文到现在空闲的时间。
hard_age:此流表项从最后一次被创建或修改到现在持续的时间。
Priority:流表项的优先级,数字越大优先级越高,范围是:0~7。删除OpenFlow端口号为100的所有流表项
1
ovs-ofctl del-flows br0 "in_port=100"
屏蔽广播包
1
ovs-ofctl add-flow br0 "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
开启stp支持
1
ovs-vsctl set bridge br0 stp_enable=true
关闭stp
1
ovs-vsctl set bridge br0 stp_enable=false
查询stp
1
ovs-vsctl get bridge br0 stp_enable
设置stp优先级
1
ovs−vsctl set bridge br0 other_config:stp-priority=0x7800
设置stp Cost
1
ovs−vsctl set port eth0 other_config:stp-path-cost=10
移除stp配置
1
ovs−vsctl clear bridge br0 other_config
配置OpenFlow版本
1
ovs-vsctl set bridge ovs-br protocols=OpenFlow12,OpenFlow13
移除openflow支持
1
ovs-vsctl clear bridge br0 protocols
设置接口的vlan编号
1
ovs-vsctl set port p0 tag=30
设置接口为trunk
1
ovs-vsctl set port p0 vlan=trunk
设置trunk允许通过的vlan
1
ovs-vsctl set port p1 trunk=4,5,6
设置网桥的faild-mode
1
ovs-vsctl set-fail-mode ovs-br secure
调试一个数据包的规则
1
2
3
4
5
6
7
8
9
10
11
12
13[root@k8s201 ~]# ovs-appctl ofproto/trace br0 in_port=1,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02
Flow: metadata=0,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,dl_type=0x0000
Rule: table=0 cookie=0 priority=0
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: drop
No match
Final flow: unchanged
Relevant fields: skb_priority=0,in_port=1,dl_src=00:00:00:00:00:00/01:00:00:00:00:00,dl_dst=00:00:00:00:00:00/ff:ff:ff:ff:ff:f0,dl_type=0x0000,nw_frag=no
Datapath actions: drop查看模块的log配置
1
ovs-appctl vlog/list
配置模块的日志级别
1
ovs-appctl vlog/set dpif:console:dbg
添加flow规则(屏蔽某个ip)
1
ovs-ofctl add-flow xenbr0 idle_timeout=0,dl_type=0x0800,nw_src=119.75.213.50,actions=drop
数据包重定向
1
ovs-ofctl add-flow xenbr0 idle_timeout=0,dl_type=0x0800,nw_proto=1,actions=output:4
更改源ip转发
1
ovs-ofctl add-flow xenbr0 idle_timeout=0,in_port=3,actions=mod_nw_src:211.68.52.32,normal
查看端口的统计信息
1
ovs-ofctl dump-ports br0
查看有哪些网桥,哪些port,哪些interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19root@l-network-1:~# ovs-vsctl list-br
br-ex
br-int
br-tun
root@l-network-1:~# ovs-vsctl list-ports br-tun
patch-int
vxlan-ac1c0509
vxlan-ac1c050d
vxlan-ac1c051c
vxlan-ac1c053f
root@l-network-1:~# ovs-vsctl list-ifaces br-tun
patch-int
vxlan-ac1c0509
vxlan-ac1c050d
vxlan-ac1c051c
vxlan-ac1c053f
# iface与ports同名.查看某个port,interface属于哪个bridge
1
2
3
4root@l-network-1:~# ovs-vsctl port-to-br vxlan-ac1c0509
br-tun
root@l-network-1:~# ovs-vsctl iface-to-br vxlan-ac1c0509
br-tun
流表常用字段
常见actions
参考: http://fishcried.com/2016-02-09/openvswitch-ops-guide/
参考: https://opengers.github.io/openstack/openstack-base-openflow-in-openvswitch/
参考: https://opengers.github.io/openstack/openstack-base-use-openvswitch/
实验: https://vcpu.me/openvswitch/