Open vSwitch(简称OVS)是在开源的Apache2.0许可下的产品级质量的多层虚拟交换标准。它旨在通过编程扩展,使庞大的网络自动化(配置、管理、维护),同时还支持标准的管理接口和协议。总的来说,它被设计为支持分布在多个物理服务器。OVS适用于VM环境中提供虚拟交换的功能。作为一个虚拟交换机,支持Xen/XenServer, KVM,和VirtualBox等多种虚拟化技术。虚拟交换就是利用虚拟平台,通过软件的方式形成交换机部件。跟传统的物理交换机相比,虚拟交换机同样具备众多优点,一是配置更加灵活。一台普通的服务器可以配置出数十台甚至上百台虚拟交换机,且端口数目可以灵活选择。例如,VMware的ESX一台服务器可以仿真出248台虚拟交换机,且每台交换机预设虚拟端口即可达56个;二是成本更加低廉,通过虚拟交换往往可以获得昂贵的普通交换机才能达到的性能,例如微软的Hyper-V平台,虚拟机与虚拟交换机之间的联机速度轻易可达10Gbps。(摘自百度百科) OVS大部分的代码是使用平台独立的C写成,可移植性非常好。OVS支持功能如下: * 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 * Geneve, 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
* ovs-vswitchd:通过使用基于流交换的内核模块来实现switch的守护进程。
* ovsdb-server:轻量级数据服务,提供从ovs-vswithd获取的配置信息。
* ovs-dpctl: 配置switch内核模块工具。
* ovs-vsctl:查询和更新ovs-vswitchd的配置信息。
* ovs-appctl:发送命令来运行相关Open vSwitch守护进程。
Open vSwitch还提供一些工具:
* ovs-ofctl:查询和控制OpenFlow switches和controllers。
* ovs-pki:为OpenFlow swithes创建和管理公钥框架。
* tcpdump的补丁,可以让tcpdump解析OpenFlow的消息。
* ovs-controller:一个简单的OpenFlow控制器。
* openvswitch.ko:Open vSwitch switching datapath
OVSDB是一个轻量级数据库,其实它是一个临时配置缓存,OVSDB通过模式文件vswitch.ovsschema来定制。ovs-vswitchd保存和修改switch配置到数据库,并与ovsdb-server交互(OVSDB协议)来管理ovsdb。 可以通过“man ovs-vswitchd.conf.db”来查看OVSDB详细介绍,Open_vSwitch是主表,且只有单独一列。
相关工具: ovs-vsctl, ovsdb-tool, ovsdb-client, ovs-appctl
Table | Purpose |
Open_vSwitch | Open vSwitch configuration() |
Bridge | Bridge configuration |
Port | Port configuration |
Interface | One physical network device in a Port |
QoS | Quality of Service configuration |
Queue | QoS output queue |
Mirror | Port mirroring |
Controller | OpenFlow controller configuration |
Manager | OVSDB management connection |
NetFlow | NetFlow configuration |
SSL | SSL configuration |
sFlow | sFlow configuration |
Capability | Capability configuration |
# ovsdb-client list-dbs
Open_vSwitch
# ovsdb-client list-tables Open_vSwitch
Table
-------------------------
Port
Manager
Bridge
Interface
SSL
IPFIX
Open_vSwitch
Queue
NetFlow
Mirror
QoS
Controller
Flow_Table
sFlow
Flow_Sample_Collector_Set
# ovs-vsctl配置ovs-vswitched但实际是管理OVSDB的接口。
# ovs-vsctl add-br br-ex
# ovs-vsctl add-port br-ex eth2 #添加桥和端口
ovsdb-tool管理数据库文件的命令行工具。
# ovsdb-tool show-log -m #可以查看相关数据库记录
record 657: 2014-09-13 07:47:29 "ovs-vsctl: ovs-vsctl add-br br-ex" table Port insert row "br-ex" (7a81506f): table Interface insert row "br-ex" (060183fc): table Bridge insert row "br-ex" (801be531): table Open_vSwitch row 30051bb4 (30051bb4): record 658: 2014-09-13 07:47:29 table Interface row "br-ex" (060183fc): record 659: 2014-09-13 07:47:29 table Open_vSwitch row 30051bb4 (30051bb4): record 660: 2014-09-13 07:48:16 "ovs-vsctl: ovs-vsctl add-port br-ex eth2" table Port insert row "eth2" (fc9e79bf): table Bridge row "br-ex" (801be531): table Interface insert row "eth2" (dbfa48c2): table Open_vSwitch row 30051bb4 (30051bb4): record 661: 2014-09-13 07:48:16 table Interface row "eth2" (dbfa48c2): table Open_vSwitch row 30051bb4 (30051bb4):
ovs-vswitchd是核心组件,支持多个独立数据路径(类似网桥)。
OVS内核模块
处理swithing和tunneling,实现tunnel和flow缓存。内核模块对openflow一无所知。OVS内核模块实现多个datapath,每个datapath可以有多个vport。每个数据通路都包含一个flow table。Flow table是什么?首先要理解什么是flow。某种特定的网络流量都可以认为是一个flow, 譬如TCP连接可以认为是一个flow。Flow Table里面的每个flow entry都会与一个指令相关联,来告诉switch来如何处理与这个flow。 Flow table中每个flow entry包含如下主要部分: match fields:匹配数据报文的字段,包含入端口、报文头和元数据值。 counters:更新匹配上的数据包文的数目。 instructions:当有报文匹配时,指令会修改匹配报文的指令集(转发到其他端口或mirror,封装并转发到controller,丢弃),或者修改 Pipeline 的处理流程,来决定报文如何转发。
ovs-vswitchd(slow path):逻辑转发,远程配置。
内核模块(Fast Path):数据表查找,修改和转发;隧道封装和解封。
内核模块处理过程:
当数据包来时,数据包会发送到 internal_dev_xmit(),来依次接收这个数据包。内核模块需要查询flow table来确认是否有缓存来指定如何转发这个数据包。这个由ovs_flow_tbl_lookup()函数完成。这个函数需要关键字,这个关键字是由ovs_flow_extract() 函数从数据包提取的。如果匹配上entry,就通过相应的指令集来处理这个数据包,counters增加。如果没有匹配的entry,ovs内核模块不知道如何处理这个数据包(即一个新flow的first packet),就会将这个数据包就会被发送到用户空间,同时miss counters增加。随后的数据包是在内核datapath中直接处理的。
用户空间处理过程:
从内核接收到数据包后,用户空间中ovs-vswitchd守护进程会根据openflow规范,创建flow entry和指令集(如果失败则丢弃),然后和数据包一起发回到内核模块处理。
# ovs-vsctl add-br mybr0
# ovs-vsctl show
376be544-6c4e-4071-bb47-c3767da4abbb
Bridge "mybr0"
Port "mybr0"
Interface "mybr0"
type: internal
ovs_version: "1.11.0"
# ifconfig mybr0 up
# ifconfig mybr0
mybr0 Link encap:Ethernet HWaddr A6:24:23:A1:0C:4C
inet6 addr: fe80::9436:54ff:feb0:d738/64 Scope:Link
UP BROADCAST RUNNING MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:468 (468.0 b)
当前eth1可以与10.0.1.0网段通信,将eth1添加到mybr0,此时,会发现eth1已经无法与外部通信;
# ovs-vsctl add-port mybr0 eth1
# ovs-vsctl show
376be544-6c4e-4071-bb47-c3767da4abbb
Bridge "mybr0"
Port "eth1"
Interface "eth1"
Port "mybr0"
Interface "mybr0"
type: internal
ovs_version: "1.11.0"
清除eth1配置,将eth1 ip地址配置到mybr0,网络又通了。
# ifconfig eth1 0
# ifconfig mybr0 10.0.1.31 netmask 255.255.255.0
添加一个tap设备
# tunctl -p -t tap0-test
Set 'tap0-test' persistent and owned by uid 0
# ifconfig tap0-test up
# ifconfig tap0-test tap0-test Link encap:Ethernet HWaddr 42:68:44:F6:3D:3B inet6 addr: fe80::4068:44ff:fef6:3d3b/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:4 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
将tap0-test添加到
# ovs-vsctl add-port mybr0 tap0-test # ovs-vsctl show 376be544-6c4e-4071-bb47-c3767da4abbb Bridge "mybr0" Port "tap0-test" Interface "tap0-test" Port "eth1" Interface "eth1" Port "mybr0" Interface "mybr0" type: internal ovs_version: "1.11.0"
创建一个虚拟机:
/usr/libexec/qemu-kvm -name cirros -m 512 -hda /images/cirros-0.3.0-i386-disk.img -boot order=c,menu=on -net nic,model=virtio -net tap,ifname=tap0-test,script=no,downscript=no -nographic -vnc :1
虚拟机创建成功后,由于我没有做dhcp,所以在VM创建完成后手动给VM分配一个IP地址,IP配置成功后,可以测试连通性。 大概效果图下图所示
ovs-ofctl用来和OpenFlow模块通信。
# ovs-ofctl show查看OpenFlow信息 # ovs-ofctl dump-flows 查看所有flow entries,默认flow table只包含一个“NORMAL”处理的entry # ovs-ofctl add-flow # ovs-ofctl del-flows [flow] # ovs-ofctl snoop # ovs-appctl bridge/dump-flows mybr0 查看“隐藏”flow:In-band control (priority >= 180000)、Fail-open (priority = 0xf0f0f0)
ovs-dpctl与内核模块通信。 # ovs-dpctlshow 查看datapath和对应端口
system@ovs-system: lookups: hit:17 missed:35 lost:0 #hit:匹配到已存在entry的packet missed:发送到userspace的Packet lost:直接丢弃的Packet flows: 0 port 0: ovs-system (internal) port 1: br-int (internal)# ovs-dpctl dump-flows 查看datapath中缓存的flows
ovs-appctl对大多ovs守护进程调用运行时控制和查询,具体用法请参考帮助。