裝載自http://sdnhub.cn/index.php/openv-switch-full-guide/
1 什么是OpenvSwitch
OpenvSwitch,簡稱OVS是一個虛擬交換軟件,主要用于虛擬機VM環(huán)境,作為一個虛擬交換機,支持Xen/XenServer, KVM, and VirtualBox多種虛擬化技術(shù)。OpenvSwitch還支持多個物理機的分布式環(huán)境。
在這種某一臺物理機器的虛擬化環(huán)境中,一個虛擬交換機(vswitch)主要有如下兩個作用:
傳遞虛擬機VM之間的流量
以及實現(xiàn)VM和外界網(wǎng)絡(luò)的通信。
如下圖所示:
整個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
2 OpenvSwitch的組成
OVS的核心組件包括 ovsdb-server,ovs-vswitchd,ovs kernel module。如下圖所示:
運行原理:
內(nèi)核模塊實現(xiàn)了多個“數(shù)據(jù)路徑(DataPath)”(類似于網(wǎng)橋),每個都可以有多個“vports”(類似于橋內(nèi)的端口)。每個數(shù)據(jù)路徑也通過關(guān)聯(lián)流表(flow table)來設(shè)置操作,而這些流表中的流都是用戶空間在報文頭和元數(shù)據(jù)的基礎(chǔ)上映射的關(guān)鍵信息,一般的操作都是將數(shù)據(jù)包轉(zhuǎn)發(fā)到另一個vport。當一個數(shù)據(jù)包到達一個vport,內(nèi)核模塊所做的處理是提取其流的關(guān)鍵信息并在流表中查找這些關(guān)鍵信息。當有一個匹配的流時它執(zhí)行對應(yīng)的操作。如果沒有匹配,它會將數(shù)據(jù)包送到用戶空間的處理隊列中(作為處理的一部分,用戶空間可能會設(shè)置一個流用于以后遇到相同類型的數(shù)據(jù)包可以在內(nèi)核中執(zhí)行操作)。細節(jié)如下圖所示:
除了核心組件,還包括一些管理工具,詳細介紹如下:
ovs-vswitchd:OVS守護進程是OVS的核心部件,實現(xiàn)交換功能,和Linux內(nèi)核兼容模塊一起,實現(xiàn)基于流的交換(flow-based switching)。它和上層 controller 通信遵從 OPENFLOW 協(xié)議,它與 ovsdb-server 通信使用 OVSDB 協(xié)議,它和內(nèi)核模塊通過netlink通信,它支持多個獨立的 datapath(網(wǎng)橋),它通過更改flow table 實現(xiàn)了綁定和VLAN等功能。
ovsdb-server:OVS輕量級的數(shù)據(jù)庫服務(wù)器,用于整個OVS的配置信息,包括接口,交換內(nèi)容,VLAN 等等。ovs-vswitchd 根據(jù)數(shù)據(jù)庫中的配置信息工作。它于 manager 和 ovs-vswitchd 交換信息使用了OVSDB(JSON-RPC)的方式。
ovs-dpctl:一個工具,用來配置交換機內(nèi)核模塊,可以控制轉(zhuǎn)發(fā)規(guī)則。
ovs-vsctl:主要是獲取或者更改ovs-vswitchd的配置信息,此工具操作的時候會更新ovsdb-server中的數(shù)據(jù)庫。
ovs-appctl:主要是向OVS守護進程發(fā)送命令的,一般用不上。 a utility that sends commands to running Open vSwitch daemons (ovs-vswitchd)
ovsdbmonitor:GUI工具來顯示ovsdb-server中數(shù)據(jù)信息。(Ubuntu下是可以使用apt-get安裝,可以遠程獲取OVS數(shù)據(jù)庫和OpenFlow的流表)
ovs-controller:一個簡單的OpenFlow控制器
ovs-ofctl:用來控制OVS作為OpenFlow交換機工作時候的流表內(nèi)容。
ovs-pki:OpenFlow交換機創(chuàng)建和管理公鑰框架;
ovs-tcpundump:tcpdump的補丁,解析OpenFlow的消息;
brocompat.ko : Linux bridge compatibility module
openvswitch.ko : Open vSwitch switching datapath
一些用用的OVS命令示例:
sudo ovs-vsctl show
sudo ovs-vsctl add-br mybridge
sudo ovs-vsctl del-br mybridge
sudo ovs-vsctl add-port mybridge port-name
sudo ovs-vsctl del-port mybridge port-name
sudo ovs-vsctl list Bridge/Port/Interface/...
sudo ovs-appctl fdb/show mybridge
sudo ovs-ofctl show mybridge
sudo ovs-ofctl dump-flows mybridge
sudo ovs-ofctl add-flow mybridge dl_src=02:a2:a2:a2:a2:a2,dl_dst=02:b2:b2:b2:b2:b2,in_port=2,dl_type=0x0800,nw_src=10.0.0.1,nw_dst=10.0.0.2,actions=output:6
sudo ovs-ofctl del-flows mybridge dl_src=02:a2:a2:a2:a2:a2,dl_dst=02:b2:b2:b2:b2:b2,in_port=2,dl_type=0x0800,nw_src=10.0.0.1,nw_dst=10.0.0.2
sudo ovs-ofctl add-flow dp0 in_port=2,actions=output:6
# This will delete all the flow entries in the flow table
sudo ovs-ofctl del-flows mybridge
3 OpenvSwitch和其他vswitch
這里其他的vswitch,包括VMware vNetwork distributed switch以及思科的Cisco Nexus 1000V。
VMware vNetwork distributed switch以及思科的Cisco Nexus 1000V這種虛擬交換機提供的是一個集中式的控制方式,。而OVS則是一個獨立的vswitch,他運行在每個實現(xiàn)虛擬化的物理機器上,并提供遠程管理。
OVS提供了兩種在虛擬化環(huán)境中遠程管理的協(xié)議:
一個是OpenFlow,通過流表來管理交換機的行為,
一個是OVSDB management protocol,用來暴露sietch的port狀態(tài)。
4 概念及工作流程
4.1 vswitch、Bridge、Datapath
在網(wǎng)絡(luò)中,交換機和橋都是同一個概念,OVS實現(xiàn)了一個虛擬機的以太交換機,換句話說,OVS也就是實現(xiàn)了一個以太橋。那么,在OVS中,給一個交換機,或者說一個橋,用了一個專業(yè)的名詞,叫做DataPath!
要了解OVS如何工作,首先需要知道橋的概念:
網(wǎng)橋也叫做橋接器,連接兩個局域網(wǎng)的設(shè)備,網(wǎng)橋工作在數(shù)據(jù)鏈路層,將兩個LAN連接,根據(jù)MAC地址來轉(zhuǎn)發(fā)幀,可以看成一個“低層的路由器”(路由器工作在網(wǎng)絡(luò)層,根據(jù)IP地質(zhì)進行轉(zhuǎn)發(fā))。
網(wǎng)橋的工作原理
網(wǎng)橋處理包遵循以下幾條規(guī)則:
在一個接口上接收到的包不會再往那個接口上發(fā)送此包。
每個接收到的包都要學(xué)習(xí)其源MAC地址。
如果數(shù)據(jù)包是多播或者廣播包(通過2層MAC地址確定)則要向接收端口以外的所有端口轉(zhuǎn)發(fā),如果上層協(xié)議感興趣,則還會遞交上層處理。
如果數(shù)據(jù)包的地址不能再CAM表中找到,則向接收端口以外的其他端口轉(zhuǎn)發(fā)。
如果CAM表中能找到,則轉(zhuǎn)發(fā)給相應(yīng)端口,如果發(fā)送和接收都是統(tǒng)一端口,則不發(fā)送。
注意,網(wǎng)橋是以混雜模式工作的。關(guān)于網(wǎng)橋更多,請查閱相關(guān)資料。
OVS中的bridge
上面,說到,一個橋就是一個交換機。例如,在OVS中:
root@localhost:~# ovs-vsctl add-br br0
root@localhost:~# ifconfig br0
br0? ? Link encap:Ethernet? HWaddr 1a:09:56:ea:0b:49
inet6 addr: fe80::1809:56ff:feea:b49/64 Scope:Link
UP BROADCAST RUNNING MULTICAST? MTU:1500? Metric:1
RX packets:1584 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:316502 (316.5 KB)? TX bytes:468 (468.0 B)
當我們創(chuàng)建了一個交換機(網(wǎng)橋)以后,此時網(wǎng)絡(luò)功能不受影響,但是會產(chǎn)生一個虛擬網(wǎng)卡,名字就是網(wǎng)橋的名稱(br-int),之所以會產(chǎn)生一個虛擬網(wǎng)卡,是為了實現(xiàn)接下來的網(wǎng)橋(交換機)功能。有了這個交換機以后,還需要為這個交換機增加端口(port),一個端口,就是一個物理網(wǎng)卡,當網(wǎng)卡加入到這個交換機之后,其工作方式就和普通交換機的一個端口的工作方式類似了。
root@localhost:~# ovs-vsctl add-port br0 port
這里要特別注意,網(wǎng)卡加入網(wǎng)橋以后,要按照網(wǎng)橋的工作標準工作,那么加入的一個端口就必須是以混雜模式工作,工作在鏈路層,處理2層的幀,所以這個port就不需要配置IP了。(你沒見過哪個交換的端口有IP的吧)
那么接下來你可能會問,通常的交換機不都是有一個管理接口,可以telnet到交換機上進行配置吧,那么在OVS中創(chuàng)建的虛擬交換機有木有這種呢,有的!上面既然創(chuàng)建交換機brname的時候產(chǎn)生了一個虛擬網(wǎng)口 br-int,那么,你給這個虛擬網(wǎng)卡配置了IP以后,就相當于給交換機的管理接口配置了IP,此時一個正常的虛擬交換機就搞定了。
root@localhost:~# ip address add 192.168.1.1/24 dev br0
最后,我們來看看一個br的具體信息:
root@localhost:~# ovs-vsctl show
bc12c8d2-6900-42dd-9c1c-30e8ecb99a1b
Bridge "br0"
Port "eth0"
Interface "eth0"
Port "br0"
Interface "br0"
type: internal
ovs_version: "1.4.0+build0"
首先,這里顯示了一個名為br0的橋(交換機),這個交換機有兩個接口,一個是eth0,一個是br0,上面說到,創(chuàng)建橋的時候會創(chuàng)建一個和橋名字一樣的接口,并自動作為該橋的一個端口,那么這個虛擬接口的作用,一方面是可以作為交換機的管理端口,另一方面也是基于這個虛擬接口,實現(xiàn)了橋的功能。
#### OpenvSwitch的典型工作流程
這一部分以一個簡單的例子,說明在虛擬化環(huán)境中OpenvSwitch的典型工作流程。
前面已經(jīng)說到,OVS主要是用來在虛擬化環(huán)境中。實現(xiàn)虛擬機之間通信以及一個虛擬機和外網(wǎng)之間通信,如下是一個典型的結(jié)構(gòu)圖:
那么,通常情況下的工作流程如下:
VM實例 instance 產(chǎn)生一個數(shù)據(jù)包并發(fā)送至實例內(nèi)的虛擬網(wǎng)絡(luò)接口 VNIC,圖中就是 instance 中的 eth0.
這個數(shù)據(jù)包會傳送到物理機上的VNIC接口,如圖就是vnet接口。
數(shù)據(jù)包從 vnet NIC 出來,到達橋(虛擬交換機) br100 上.
數(shù)據(jù)包經(jīng)過交換機的處理,從物理節(jié)點上的物理接口發(fā)出,如圖中物理機上的 eth0 .
數(shù)據(jù)包從 eth0 出去的時候,是按照物理節(jié)點上的路由以及默認網(wǎng)關(guān)操作的,這個時候該數(shù)據(jù)包其實已經(jīng)不受你的控制了。
一般 L2 switch 連接 eth0 的這個口是一個 trunk 口, 因為虛擬機對應(yīng)的 VNET 往往會設(shè)置 VLAN TAG, 可以通過對虛擬機對應(yīng)的 vnet 打 VALN TAG 來控制虛擬機的網(wǎng)絡(luò)廣播域. 如果跑多個虛擬機的話, 多個虛擬機對應(yīng)的 vnet 可以設(shè)置不同的 vlan tag, 那么這些虛擬機的數(shù)據(jù)包從 eth0(4)出去的時候, 會帶上TAG標記. 這樣也就必須是 trunk 口才行.
6 OVS簡單應(yīng)用實例
6.1 創(chuàng)建物理機到物理機的網(wǎng)絡(luò)拓撲
root@localhost:~# ovs-vsctl add-br br0
root@localhost:~# ovs-vsctl add-port br0 eth0
root@localhost:~# ovs-vsctl add-port br0 eth1
6.2 創(chuàng)建虛擬機到虛擬機的網(wǎng)絡(luò)拓撲
使用KVM虛擬化。
root@localhost:~# ovs-vsctl add-br br0
root@localhost:~# cat /etc/ovs-ifup
#!/bin/sh
switch='br0'
/sbin/ifconfig? $1 0.0.0.0 up
ovs-vsctl add-port ${switch} $1
root@localhost:~# cat /etc/ovs-ifdown
#!/bin/sh
switch= 'br0'
ovs-vsctl del-port ${sw/sbin/ifconfig? $1 0.0.0.0 down
itch} $1
root@localhost:~# 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
root@localhost:~# 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
7.Misc
7.1 查表
ovs-vsctl list bridge ovs-br
7.2 關(guān)于 Brdige 及 Port
創(chuàng)建 Brdige
ovs-vsctl add-br ovs-br
在 ovs-br 上添加 interface
ovs-vsctl add-port ovs-br eth0
(1) + (2) 的可以合并為:
ovs?vsctl add?br ovs-br -- add?port ovs-br eth0
刪除 Bridge
ovs-vsctl del-br ovs-br #如果不存在, 會有error log
ovs-vsctl --if-exists del-br ovs-br
更改 ofport (openflow port number)為100:
ovs-vsctl add-port ovs-br eth0 -- set Interface eth0 ofport_request=100
設(shè)置 port 為 internal
ovs-vsctl set Interface eth0 type=internal
7.3 關(guān)于Controller
設(shè)置 Controller
ovs-vsctl set-controller ovs-br tcp:1.2.3.4:6633
設(shè)置 multi controller
ovs-vsctl set-controller ovs-br tcp:1.2.3.4:6633 tcp:5.6.7.8:6633
查詢 Controller
ovs-vsctl show
如果有成功連到 controller 則提示 is_connected:true, 反之未連上:
ovs-vsctl get-controller ovs-br
移除 Controller
ovs-vsctl del-controller ovs-br
7.4 關(guān)于 STP (Spanning Tree Protocol)
開啟 STP
ovs-vsctl set bridge ovs-br stp_enable=true
關(guān)閉 STP
ovs-vsctl set bridge ovs-br stp_enable=false
查詢 STP 配置信息
ovs-vsctl get bridge ovs-br stp_enable
設(shè)置 Priority
ovs?vsctl set bridge br0 other_config:stp-priority=0x7800
設(shè)置 Cost
ovs?vsctl set port eth0 other_config:stp-path-cost=10
移除 STP 設(shè)置
ovs?vsctl clear bridge ovs-br other_config
7.5 關(guān)于 Openflow Version
支持 OpenFlow Version 1.3
ovs-vsctl set bridge ovs-br protocols=OpenFlow13
支持 OpenFlow Version 1.3 1.2
ovs-vsctl set bridge ovs-br protocols=OpenFlow12,OpenFlow13
移除 OpenFlow 支持設(shè)置
ovs-vsctl clear bridge ovs-br protocols
7.6 關(guān)于 VLAN
設(shè)置 VLAN tag
ovs-vsctl add-port ovs-br vlan3 tag=3 -- set interface vlan3 type=internal
移除 VLAN
ovs-vsctl del-port ovs-br vlan3
查詢 VLAN
ovs-vsctl show
ifconfig vlan3
設(shè)置 Vlan trunk
ovs-vsctl add-port ovs-br eth0 trunk=3,4,5,6
設(shè)置已 add 的 port 為 access port, vlan id 9
ovs-vsctl set port eth0 tag=9
ovs-ofctl add-flow 設(shè)置 vlan 100
ovs-ofctl add-flow ovs-br in_port=1,dl_vlan=0xffff,actions=mod_vlan_vid:100,output:3
ovs-ofctl add-flow ovs-br in_port=1,dl_vlan=0xffff,actions=push_vlan:0x8100,set_field:100-\>vlan_vid,output:3
ovs-ofctl add-flow 拿掉 vlan tag
ovs-ofctl add-flow ovs1 in_port=3,dl_vlan=100,actions=strip_vlan,output:1
two_vlan example
ovs-ofctl add-flow pop-vlan
ovs-ofctl add-flow ovs-br in_port=3,dl_vlan=0xffff,actions=pop_vlan,output:1
7.7 關(guān)于 GRE Tunnel
設(shè)置 GRE tunnel
ovs?vsctl add?port ovs-br ovs-gre -- set interface ovs-gre type=gre options:remote_ip=1.2.3.4
查詢 GRE Tunnel
ovs-vsctl show
7.8 關(guān)于 Dump flows
Dumps OpenFlow flows 不含 hidden flows (常用)
ovs-ofctl dump-flows ovs-br
Dumps OpenFlow flows 包含 hidden flows
ovs-appctl bridge/dump-flows ovs-br
Dump 特定 bridge 的 datapath flows 不論任何 type
ovs-appctl dpif/dump-flows ovs-br
Dump 在 Linux kernel 裡的 datapath flow table (常用)
ovs-dpctl dump-flows [dp]
Top like behavior for ovs-dpctl dump-flows
ovs-dpctl-top
7.9 XenServer 開啟 OpenvSwitch 方式
檢查是否啟動openvswitch服務(wù):
service openvswitch status
啟動服務(wù)
xe-switch-network-backend openvswitch
關(guān)閉服務(wù)
xe-switch-network-backend bridge
7.10 關(guān)于 Log
查詢 log level list
ovs-appctl vlog/list
設(shè)置 log level (以 stp 設(shè)置 file 為 dbg level 為例)
ovs-appctl vlog/set stp:file:dbg
ovs-appctl vlog/set {module name}:{console, syslog, file}:{off, emer, err, warn, info, dbg}
7.11 關(guān)于 Fallback
Controller connection: false 的時候, 會自動調(diào)成 legacy switch mode
ovs-vsctl set-fail-mode ovs-br standalone
無論 Controller connection status 為何, 都必須通過 OpenFlow 進行網(wǎng)絡(luò)行為 (default)
ovs-vsctl set-fail-mode ovs-br secure
移除
ovs-vsctl del-fail-mode ovs-br
查詢
ovs-vsctl get-fail-mode ovs-br
7.12 關(guān)于 sFlow
查詢
ovs-vsctl list sflow
新增
Set sFlow 缺
刪除
ovs-vsctl -- clear Bridge ovs-br sflow
7.13關(guān)于 NetFlow
查詢
ovs-vsctl list netflow
新增
Set NetFlow 缺
刪除
ovs-vsctl -- clear Bridge ovs-br netflow
7.14 設(shè)置 Out-of-band 和 in-band
查詢
ovs-vsctl get controller ovs-br connection-mode
Out-of-band
ovs-vsctl set controller ovs-br connection-mode=out-of-band
In-band (default)
ovs-vsctl set controller ovs-br connection-mode=in-band
移除 hidden flow
ovs-vsctl set bridge br0 other-config:disable-in-band=true
7.15 關(guān)于 ssl
查詢
ovs-vsctl get-ssl
設(shè)置
ovs-vsctl set-ssl sc-privkey.pem sc-cert.pem cacert.pem
OpenvSwitch Lab 6$ TLS SSL : http://roan.logdown.com/posts/208707-openvswitch-lab-6-ssl
刪除
ovs-vsctl del-ssl
7.16 關(guān)于 SPAN
詳細設(shè)置
ovs-vsctl add-br ovs-br
ovs-vsctl add-port ovs-br eth0
ovs-vsctl add-port ovs-br eth1
ovs-vsctl add-port ovs-br tap0 \
-- --id=@p get port tap0 \
-- --id=@m create mirror name=m0 select-all=true output-port=@p \
-- set bridge ovs-br mirrors=@m
將 ovs-br 上 add-port {eth0,eth1} mirror 至 tap0
刪除
ovs-vsctl clear bridge ovs-br mirrors # 關(guān)於 Table
查 table ovs-ofctl dump-tables ovs-br
7.17 關(guān)于 Group Table
參考hwchiu – Multipath routing with Group table at mininet
建立 Group id 及對應(yīng)的 bucket
ovs-ofctl -O OpenFlow13 add-group ovs-br group_id=5566,type=select,bucket=output:1,bucket=output:2,bucket=output:3
type 共有 All, Select, Indirect, FastFailover, 詳細規(guī)格:http://flowgrammable.org/sdn/openflow/message-layer/groupmod/#GroupMod_1.3
使用 Group Table
ovs-ofctl -O OpenFlow13 add-flow ovs-br in_port=4,actions=group:5566
7.18 關(guān)于 VXLAN
參考rascov – Bridge Remote Mininets using VXLAN
建立 VXLAN Network ID (VNI) 和指定的 OpenFlow port number, eg: VNI=5566, OF_PORT=9
ovs-vsctl set interface vxlan type=vxlan option:remote_ip=x.x.x.x option:key=5566 ofport_request=9
VNI flow by flow
ovs-vsctl set interface vxlan type=vxlan option:remote_ip=140.113.215.200 option:key=flow ofport_request=9
設(shè)置 VXLAN tunnel id
ovs-ofctl add-flow ovs-br in_port=1,actions=set_field:5566->tun_id,output:2
ovs-ofctl add-flow s1 in_port=2,tun_id=5566,actions=output:1
7.19 關(guān)于 OVSDB Manager
參考OVSDB Integration:Mininet OVSDB Tutorial
Active Listener 設(shè)置
ovs-vsctl set-manager tcp:1.2.3.4:6640
Passive Listener 設(shè)置
ovs-vsctl set-manager ptcp:6640
7.20 OpenFlow Trace
Generate pakcet trace
ovs-appctl ofproto/trace ovs-br in_port=1,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02 -generate
7.21 其它
查詢 OpenvSwitch 版本
ovs-ofctl -V
查詢指令歷史記錄
ovsdb-tool show-log [-mmm]
[參考]
http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=openvswitch;a=blob_plain;f=FAQ;hb=HEAD
http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=openvswitch;a=blob_plain;f=README;hb=HEAD
http://openvswitch.org/support/config-cookbooks/vlan-configuration-cookbook/
http://roan.logdown.com/posts/191801-set-openvswitch
http://roan.logdown.com/posts/208707-openvswitch-lab-6-ssl
http://flowgrammable.org/sdn/openflow/message-layer/groupmod/#GroupMod_1.3
http://www.areteix.net/blog/2013/08/network-flow-monitoring-with-open-vswitch/
http://blog.scottlowe.org/2014/11/21/removing-ovs-configuration-settings/