OpenvSwitch简称OVS,是一个高质量的、多层虚拟交换机,使用开源Apache2.0许可协议,由Nicira Networks开发,主要实现代码为可移植的C代码。它的目的是让大规模网络自动化可以通过编程扩展,同时仍然支持标准的管理接口和协议(例如NetFlow, sFlow, SPAN, RSPAN, CLI, LACP, 802.1ag)。此外,它被设计位支持跨越多个物理服务器的分布式环境,类似于VMware的vNetwork分布式vswitch或Cisco Nexus 1000 V。Open vSwitch支持多种linux 虚拟化技术,包括Xen/XenServer, KVM和irtualBox。
SDN交换机跟普通交换机最大的区别就是将普通交换机的数据平面和控制平面相分离,SDN交换机只负责数据的转发,而控制指令则由更上一级的控制器下发。
Open vSwitch supports the following features:
Visibility into inter-VM communication via NetFlow, sFlow(R), IPFIX, SPAN, RSPAN, and GRE-tunneled mirrors
LACP (IEEE 802.1AX-2008)
Standard 802.1Q VLAN model with trunking
Multicast snooping
IETF Auto-Attach SPBM and rudimentary required LLDP support
BFD and 802.1ag link monitoring
STP (IEEE 802.1D-1998) and RSTP (IEEE 802.1D-2004)
Fine-grained QoS control
Support for HFSC qdisc
Per VM interface traffic policing
NIC bonding with source-MAC load balancing, active backup, and L4 hashing
OpenFlow protocol support (including many extensions for virtualization)
IPv6 support
Multiple tunneling protocols (GRE, VXLAN, STT, and Geneve, with IPsec support)
Remote configuration protocol with C and Python bindings
Kernel and user-space forwarding engine options
Multi-table forwarding pipeline with flow-caching engine
Forwarding layer abstraction to ease porting to new software and hardware platforms
OVS由这三大部分构成:
1. ovsdb-sever: OVS的数据库服务器,用来存储虚拟交换机的配置信息。它于manager和ovs-vswitchd交换信息使用了OVSDB(JSON-RPC)的方式。
主要包括以下模块和特性:
ovs-vswitchd 主要模块,实现switch的daemon,包括一个支持流交换的Linux内核模块;
ovsdb-server 轻量级数据库服务器,提供ovs-vswitchd获取配置信息;
ovs-dpctl 用来配置switch内核模块;
一些Scripts and specs 辅助OVS安装在Citrix XenServer上,作为默认switch;
ovs-vsctl 查询和更新ovs-vswitchd的配置;
ovs-appctl 发送命令消息,运行相关daemon;
ovsdbmonitor GUI工具,可以远程获取OVS数据库和OpenFlow的流表。
此外,OVS也提供了支持OpenFlow的特性实现,包括
ovs-openflowd:一个简单的OpenFlow交换机;
ovs-controller:一个简单的OpenFlow控制器;
ovs-ofctl 查询和控制OpenFlow交换机和控制器;
ovs-pki :OpenFlow交换机创建和管理公钥框架;
ovs-tcpundump:tcpdump的补丁,解析OpenFlow的消息;
ovs-testcontroller, a simple OpenFlow controller that may be useful for testing (though not for production).
内核模块实现了多个“数据路径”(类似于网桥),每个都可以有多个“vports”(类似于桥内的端口)。每个数据路径也通过关联一下流表(flow table)来设置操作,而这些流表中的流都是用户空间在报文头和元数据的基础上映射的关键信息,一般的操作都是将数据包转发到另一个vport。当一个数据包到达一个vport,内核模块所做的处理是提取其流的关键信息并在流表中查找这些关键信息。当有一个匹配的流时它执行对应的操作。如果没有匹配,它会将数据包送到用户空间的处理队列中(作为处理的一部分,用户空间可能会设置一个流用于以后碰到相同类型的数据包可以在内核中执行操作)。
1.6.1 Bridge、OpenvSwitch、Datapath和其他vswitch
网桥也叫做桥接器,连接两个局域网的设备,网桥工作在数据链路层,将两个LAN连接,根据MAC地址来转发帧,可以看成一个“低层的路由器”(路由器工作在网络层,根据IP地质进行转发)。
网桥是以混杂模式工作的。
在网络中,交换机和桥都是同一个概念,OVS实现了一个虚拟机的以太交换机,换句话说,OVS也就是实现了一个以太桥。
在OVS中,交换机的一个专业的名词为DataPath。
1.6.2 这里其他的vswitch,包括VMware vNetwork distributed switch以及思科的Cisco Nexus 1000V。
VMware vNetwork distributed switch以及思科的Cisco Nexus 1000V这种虚拟交换机提供的是一个集中式的控制方式,。
而OVS则是一个独立的vswitch,他运行在每个实现虚拟化的物理机器上,并提供远程管理。
OVS提供了两种在虚拟化环境中远程管理的协议:
一个是OpenFlow,通过流表来管理交换机的行为,
一个是OVSDB management protocol,用来暴露sietch的port状态。
root@ent:~# ovs-vsctl
The program 'ovs-vsctl' is currently not installed. You can install it by typing:
apt-get install openvswitch-switch
查看下ovs的运行状况:
ps -ea | grep ovs
10377 ? 00:00:00 ovsdb-server
10537 ? 00:00:00 ovs-vswitchd
添加网桥:#ovs-vsctl add-br br0
列出open vswitch中的所有网桥:#ovs-vsctl list-br
判断网桥是否存在:#ovs-vsctl br-exists br0
将物理网卡挂接到网桥:#ovs-vsctl add-port br0 eth0
交换机增加端口(port),一个端口,就是一个物理网卡,当网卡加入到这个交换机之后,其工作方式就和普通交换机的一个端口的工作方式类似了。
特别注意,网卡加入网桥以后,要按照网桥的工作标准工作,那么加入的一个端口就必须是以混杂模式工作,工作在链路层,处理2层的帧,所以这个port就不需要配置IP了。
列出网桥中的所有端口:#ovs-vsctl list-ports br0
列出所有挂接到网卡的网桥:#ovs-vsctl port-to-br eth0
查看open vswitch的网络状态:#ovs-vsctl show
删除网桥上已经挂接的网口:#vs-vsctl del-port br0 eth0
删除网桥:#ovs-vsctl del-br br0
通常的交换机都是有一个管理接口,可以telnet到交换机上进行配置。创建交换机brname的时候产生了一个虚拟网口brname,那么给这个虚拟网卡配置了IP以后,就相当于给交换机的管理接口配置了IP
设置网络接口设备类型为”internal”: ip address add 192.168.1.1/24 dev brname
ovs-vsctl set Interface p0 type=internal
创建一个name space:ns0,把p0端口接入到ns0里,并且配置ip地址 192.168.1.100/24
ip netns add ns0
ip link set p0 netns ns0
ip netns exec ns0 ip addr add 192.168.1.100/24 dev p0
ip netns exec ns0 ifconfig p0 promisc up
3.1. OVS连接控制器
首先添加一个名为br0的网桥。
# ovs-vsctl add-br br0
列出所有网桥。
# ovs-vsctl list-br
启用该网桥。
# ifconfig br0 up
此时再用ifconfig命令能在网络设备列表里看到名为br0的网桥即启动成功。
root@ubuntu:/home/chulk/sdn/openvswitch-2.3.1# ifconfig -a
br0 Link encap:Ethernet HWaddr a6:0c:7f:2e:0a:47
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth0 Link encap:Ethernet HWaddr 00:50:56:2c:4f:1d
inet addr:172.16.26.136 Bcast:172.16.26.255 Mask:255.255.255.128
inet6 addr: fe80::250:56ff:fe2c:4f1d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21635 errors:0 dropped:0 overruns:0 frame:0
TX packets:3669 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3550892 (3.5 MB) TX bytes:536821 (536.8 KB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:6197 errors:0 dropped:0 overruns:0 frame:0
TX packets:6197 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1925113 (1.9 MB) TX bytes:1925113 (1.9 MB)
ovs-system Link encap:Ethernet HWaddr fa:6e:dd:da:2e:a7
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
我们可以用下面的命令将br0网桥连接至一个指定的控制器。
# ovs-vsctl set-controller br0 tcp::
这里本文使用的控制器地址为172.16.26.136,端口为6653。即:
# ovs-vsctl set-controller br0 tcp:172.16.26.136:6653
查看OVS是否连接上控制器。
root@ubuntu:/home/chulk/sdn/openvswitch-2.3.1# ovs-vsctl show
b784c584-f000-49c9-9c54-3b599cc8ad41
Bridge "br0"
Controller "tcp:172.16.26.136:6653"
is_connected: true
Port "br0"
Interface "br0"
type: internal
ovs_version: "2.3.1"
3.2. 交换机相关操作
查看虚拟交换机的信息。
root@ubuntu:/home/chulk/sdn/openvswitch-2.3.1# ovs-ofctl show br0
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000a60c7f2e0a47
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: OUTPUT SET_VLAN_VID SET_VLAN_PCP STRIP_VLAN SET_DL_SRC SET_DL_DST SET_NW_SRC SET_NW_DST SET_NW_TOS SET_TP_SRC SET_TP_DST ENQUEUE
LOCAL(br0): addr:a6:0c:7f:2e:0a:47
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
查看br0上各交换机端口的状态。
root@ubuntu:/home/chulk/sdn/openvswitch-2.3.1# ovs-ofctl dump-ports br0
OFPST_PORT reply (xid=0x2): 1 ports
port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
tx pkts=0, bytes=0, drop=0, errs=0, coll=0
查看br0上所有的流规则
root@ubuntu:/home/chulk/sdn/openvswitch-2.3.1# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
cookie=0xb, duration=423.374s, table=0, n_packets=0, n_bytes=0, idle_age=423, priority=122,dl_dst=00:00:00:00:00:02 actions=LOCAL
cookie=0x0, duration=1629.020s, table=0, n_packets=0, n_bytes=0, idle_age=1629, priority=3,dl_dst=00:00:00:00:00:00 actions=drop
cookie=0xa, duration=1530.457s, table=0, n_packets=0, n_bytes=0, idle_age=1530, priority=123,dl_dst=00:00:00:00:00:01 actions=LOCAL
cookie=0x9, duration=1628.981s, table=0, n_packets=0, n_bytes=0, idle_age=1628, priority=65535,ip,nw_proto=2 actions=CONTROLLER:65535
cookie=0x0, duration=1629.097s, table=0, n_packets=0, n_bytes=0, idle_age=1629, priority=0 actions=drop
cookie=0x0, duration=1628.981s, table=0, n_packets=0, n_bytes=0, idle_age=1628, priority=3,dl_src=00:00:00:00:00:00 actions=drop
cookie=0x0, duration=1628.981s, table=0, n_packets=0, n_bytes=0, idle_age=1628, priority=3,dl_src=ff:ff:ff:ff:ff:ff actions=drop
cookie=0x0, duration=1629.061s, table=1, n_packets=0, n_bytes=0, idle_age=1629, priority=0 actions=drop
3.3. 网桥管理
之前已经添加了一个名为br0的网桥。
现在可以将网络接口eth0挂接到网桥br0上。
ovs-vsctl add-port br0 eth0
列出挂接到网桥br0上的所有网络接口。
ovs-vsctl list-ports br0
查看结果,如图所示:
ovs-vsctl show
删除网桥br0上挂接的eth0网络接口。
ovs-vsctl del-port br0 eth0
删除名为br0的网桥。
ovs-vsctl del-br br0
3.4. OVS其它常用命令及选项如下表所示:
ovs-vsctl常用命令及选项
ovs-ofctl常用命令及选项
root@liberty:~# ovs-vsctl add-br br-ex
root@liberty:~# ovs-vsctl show
b90fde22-baca-484c-a60f-025168c0c456
Bridge br-ex
Port br-ex
Interface br-ex
type: internal
ovs_version: "2.0.2"
当我们创建了一个交换机(网桥)以后,此时网络功能不受影响,但是会产生一个虚拟网卡,名字就是brname,之所以会产生一个虚拟网卡,是为了实现接下 来的网桥(交换机)功能。有了这个交换机以后,我还需要为这个交换机增加端口(port),一个端口,就是一个物理网卡,当网卡加入到这个交换机之后,其 工作方式就和普通交换机的一个端口的工作方式类似了。
root@liberty:~# ovs-vsctl list-ports br-ex
root@liberty:~# ip l
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: p4p1: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether d4:be:d9:be:84:b5 brd ff:ff:ff:ff:ff:ff
3: virbr0: mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 12:5a:1d:69:c3:2c brd ff:ff:ff:ff:ff:ff
4: ovs-system: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1
link/ether 3a:e8:46:68:cd:43 brd ff:ff:ff:ff:ff:ff
5: br-ex: mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
link/ether 46:56:54:92:bc:4d brd ff:ff:ff:ff:ff:ff
root@liberty:~# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: p4p1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether d4:be:d9:be:84:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.118/24 brd 192.168.1.255 scope global p4p1
valid_lft forever preferred_lft forever
inet6 fe80::d6be:d9ff:febe:84b5/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 12:5a:1d:69:c3:2c brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: ovs-system: mtu 1500 qdisc noop state DOWN group default qlen 1
link/ether 3a:e8:46:68:cd:43 brd ff:ff:ff:ff:ff:ff
5: br-ex: mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1
link/ether 46:56:54:92:bc:4d brd ff:ff:ff:ff:ff:ff
inet6 fe80::5c46:eff:febf:e680/64 scope link
valid_lft forever preferred_lft forever
root@liberty:~# ovs-vsctl add-port br-ex p4p1
root@liberty:~# ovs-vsctl show
b90fde22-baca-484c-a60f-025168c0c456
Bridge br-ex
Port "p4p1"
Interface "p4p1"
Port br-ex
Interface br-ex
type: internal
ovs_version: "2.0.2"
这里要特别注意,网卡加入网桥以后,要按照网桥的工作标准工作,那么加入的一个端口就必须是以混杂模式工作,工作在链路层,处理2层的帧,所以这个port就不需要配置IP了。(你没见过哪个交换的端口有IP的吧)
那么接下来你可能会问,通常的交换机不都是有一个管理接口,可以telnet到交换机上进行配置吧,那么在OVS中创建的虚拟交换机有木有这种呢,有的! 上面既然创建交换机brname的时候产生了一个虚拟网口brname,那么,你给这个虚拟网卡配置了IP以后,就相当于给交换机的管理接口配置了IP, 此时一个正常的虚拟交换机就搞定了。
root@liberty:~# ip address del 192.168.1.118/24 brd + dev p4p1
root@liberty:~# ip address add 192.168.1.118/24 brd + dev br-ex
root@liberty:~# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: p4p1: mtu 1500 qdisc pfifo_fast master ovs-system state UP group default qlen 1000
link/ether d4:be:d9:be:84:b5 brd ff:ff:ff:ff:ff:ff
inet6 fe80::d6be:d9ff:febe:84b5/64 scope link
valid_lft forever preferred_lft forever
3: ovs-system: mtu 1500 qdisc noop state DOWN group default qlen 1
link/ether 6e:36:32:94:6e:1f brd ff:ff:ff:ff:ff:ff
4: br-ex: mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1
link/ether d4:be:d9:be:84:b5 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.118/24 brd 192.168.1.255 scope global br-ex
valid_lft forever preferred_lft forever
inet6 fe80::78fa:9aff:fe31:5777/64 scope link
valid_lft forever preferred_lft forever
5: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether a2:a2:98:c2:ee:eb brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
手工创建br-ex后,重启后,br-ex网桥会自动建立,但是不会自动配置IP地址。需要配置文件/etc/network/interfaces:
root@liberty:~# cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#auto p4p1
#iface p4p1 inet dhcp
# auto p4p1
# iface p4p1 inet static
# address 192.168.1.118
# netmask 255.255.255.0
# gateway 192.168.1.250
# dns-nameserver 202.106.0.20
# The primary network interface
auto br-ex
iface br-ex inet static
address 192.168.1.118
netmask 255.255.255.0
gateway 192.168.1.250
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 202.106.0.20
auto p4p1
iface p4p1 inet manual
up ip address add 0/0 dev $IFACE
up ip link set $IFACE up
down ip link set $IFACE down
参考:http://www.sdnlab.com/sdn-guide/14747.html
执行以下命令:
#ovs-vsctl add-br br0 //建立一个名为br0的open vswitch网桥
#ovs-vsctl add-port br0 eth0 //把eth0挂接到br0中
#ovs-vsctl add-port br0 eth1 //把eth1挂接到br0中
执行以下命令:
# ovs-vsctl add-br br0 //建立一个名为br0的open vswitch网桥
如果使用vbox或virt-manager把bridge设置为br0即可,如果使用cli kvm则先创建两个文件,用于虚拟网卡的添加于删除。假设这两个文件分别为/etc/ovs-ifup和/etc/ovs-ifdown,则向这两个文件中写入以下内容
/etc/ovs-ifup
#!/bin/sh
switch='br0'
/sbin/ifconfig $1 0.0.0.0 up
ovs-vsctl add-port ${switch} $1
/etc/ovs-ifdown
#!/bin/sh
switch='br0'
/sbin/ifconfig $1 0.0.0.0 down
ovs-vsctl del-port ${switch} $1
使用以下命令建立虚拟机
kvm -m 512 -net nic,macaddr=00:11:22:33:44:55-net \
tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown-drive\
file=/path/to/disk-image,boot=on
kvm -m 512 -net nic,macaddr=11:22:33:44:55:66-net \
tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown-drive\
file=/path/to/disk-image,boot=on
执行命令:
# ovs-vsctl add-br br0 //建立一个名为br0的open vswitch网桥
# ovs-vsctl add-port br0 eth0 //把eth0挂接到br0中
# kvm -m 512 -net nic,macaddr=00:11:22:33:44:55-net \
tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown-drive\
file=/path/to/disk-image,boot=on //ovs-ifup和ovs-ifdown和上一节中相同
以上操作都是将多个主机(物理机或虚拟机)连接到同一个网桥上,实现它们之间的通信,但是要构建复杂的网络,就需要多个网桥,在装有open vswitch的主机上建立两个网桥,实现它们之间的连接,构建结果如下:
执行命令:
ovs-vsctl add-br br 添加一个名为br0的网桥
ovs-vsctl add-br br1 //添加一个名为br0的网桥
ovs-vsctl add-port br0 patch-to-br1 //为br0添加一个虚拟端口
ovs-vsctl set interface patch-to-br1type=patch //把patch-to-br1的类型设置为patch
ovs-vsctl set interface patch-to-br1 options:peer=patch-to-br0 把对端网桥和此网桥连接的端口名称设置为patch-to-br0
ovs-vsctl add-port br1 patch-to-br0 //为br0添加一个虚拟端口
ovs-vsctl set interface patch-to-br0type=patch //把patch-to-br0的类型设置为patch
ovs-vsctl set interface patch-to-br0options:peer=patch-to-br1 //把对端网桥和此网桥连接的端口名称设置为patch-to-br1
ovs-vsctl set interface patch-to-br0type=patch 和ovs-vsctl set interface patch-to-br0 options:peer=patch-to-br1是对ovs-database的操作,有有兴趣的同学可以参考ovs-vswitchd.conf.db.5
在两台机器上分别安装上open vswitch并创建网桥,分别为两个网桥添加物理网卡,然后通过网线连接两个网桥,实现两个网桥之间的互通。构建结果图如下:
执行命令:
host1
#ovs-vsctl add-br br0 //添加名为br0的网桥
#ovs-vsctl add-port br0 eth0 //把eth0挂接到br0上
host2
#ovs-vsctl add-br br0 //添加名为br0的网桥
#ovs-vsctl add-port br0 eth0 //把eth0挂接到br0上
然后使用网线把host1的eth0和host2的eth0相连即可。
使用上边五种方法的组合就可以构建出各种复杂的网络,为各种实验提供网络的支持。
参考:
OVS常见问题:https://github.com/openvswitch/ovs/blob/master/FAQ.md
OVS features: http://openvswitch.org/features/
OVS GitHub: https://github.com/openvswitch/ovs
OVS Tutorial:https://github.com/openvswitch/ovs/blob/master/tutorial/Tutorial.md
OVS Install: https://github.com/openvswitch/ovs/blob/master/INSTALL.Debian.md