局域網游戲代表:紅色警戒
Open vSwitch系列之一 Open vSwitch誕生
Open vSwitch系列之三 ovs-vsctl命令使用
Open vSwitch系列之四 ovs-ofctl命令使用
ovs交換機可以實現vlan的隔離,功能上類似於普通交換的vlan隔離。並且vlan隔離在openstack的各種網絡發揮着十分重要的作用。ovs的隔離通通過tag標簽來實現。下面首先使用mininet仿真軟件創建一個最簡單的拓撲,然后設置端口tag來實現vlan。
Mininet創建簡單拓撲
mininet是SDN學習中用來創建各種拓撲的仿真軟件,能夠使用最小的消耗完成主機,交換機,控制器的模擬。使用mn命令創建兩個主機連接到一個交換機中的拓撲。
查看交換機的端口。兩個主機連接到交換機的兩個端口,分別是s1-eth2,s1-eth2。所有的端口默認其實都是有tag的,tag為0,但不會顯示在這里。
打開h1
mininet 仿真器可以打開任何一個模擬出來的設備,可以將新開的端口看做一個虛擬機。
主機h1這時還不能和主機h2通信,因為ovs交換機中沒有任何流表。
下發正常轉發流表
action=NORMAL的流表意思是該交換機配置成一個正常傳統交換機工作。ovs交換機有兩種工作模式:SDN模式和傳統模式。傳統的ovs交換機是通過mac地址自學習來完成數據幀交換,SDN模式是交換機里的流表匹配數據流然后有相應的轉發動作。這里就是讓交換機實現mac地址自學習功能。
sh ovs-ofctl add-flow s1 action=normal
主機1能夠ping通主機2
查看mac地址自學習表,可以看到這個時候交換機的端口,特別是VALN都是0。
設置tag號。tag是在端口上設置的,使用命令將tag號打在端口上。
ovs-vsctl set Port s1-eth1 tag=100
ovs-vsctl set Port s1-eth2 tag=200
再次讓h1 ping h2 可以發現已經無法通信了。
查看交換機的mac地址自學習表,能夠看到VLAN發生了變化。正是這種LVAN的變化導致數據
ovs-dpctl
:可以統計每條 datapath 上的設備通過的流量,打印流的信息。datapath模塊是最底層交換機機制的實現,功能是接收網包-查表-執行action。下面使用dpctl查看經過datapath數據流是怎么樣
ovs-dpctl dump-dps
可以看到在h1 h2互相ping時的數據流。
recirc_id(0),in_port(1),eth(src=46:5d:b5:ee:45:bf,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=10.0.0.2,tip=10.0.0.1,op=1/0xff), packets:59, bytes:2478, used:0.528s, actions:push_vlan(vid=200,pcp=0),3
recirc_id(0),in_port(2),eth(src=be:1c:a1:b5:c5:9f,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=10.0.0.1,tip=10.0.0.2,op=1/0xff), packets:78, bytes:3276, used:0.799s, actions:push_vlan(vid=100,pcp=0),3
這兩條經過的數據流分別是h2和h1發出的。其中action表明了該條流vlan的產生過程。數據幀進入s1是不帶vlan的,因為ovs是軟件模擬,所以datapath負責對設置了tag的端口在數據幀中加入tag(個人理解)。從h2出來的數據幀進入datapath打上vlan tag200,從h1出來的數據幀進入datapath打上vlan tag100。正是因為數據流的tag導致了匹配之后無法轉發。
注意這里的in_port並不是網橋s1上的port,而是datapath自己的的port,關系可以參考如下:
tag在openstack中使用
openstack有多種網絡插件,其中最重要的就是ovs,即openvswitch-plugin。在使用ovs實現openstack中的各種網絡時,這里各種網絡指:local,flat,vlan,vxlan等,tag標簽的使用可以說是每一種網絡都離不開的。下面說說在各種網絡中tag標簽的使用。由於手頭上沒有openstack環境,這里借用我的雲計算啟蒙教程cloudman先生的每天五分鍾玩轉openstack系列來說明。
local網絡
local網絡是虛擬機的網絡和網橋連接,但是網絡和服務器網卡之間沒有連接。流量限制在網橋內部。在local網絡中,為了實現網絡隔離,不同網絡之間連接到網橋的tag是不一樣的。在同一個tag下的網絡可以互相通信,當然網絡是訪問不到外網的,則是local網絡的最大特征。
flat網絡
flat網絡叫平面網絡即為不帶tag的網絡。不帶也是一種特征。flat網絡模式下,每創建一個網絡,就需要獨占一塊網卡,所以一般也不會使用這種網絡作為租戶網絡。雖然說flat網絡不帶tag,但是其實是所有的port都使用了默認的tag號1,所以能夠看到網橋中port都有tag為1。
vlan網絡
vlan網絡是tag在openstack中的一個重要應用,值得重點講解。
vlan網絡的模型如下:
在vlan網絡中。每一個網絡在br-int上的tag號都是不一樣的,比如使用網絡1創建的虛擬機,其port的tag是1,使用網絡2創建的虛擬機,其port的tag是2。有了不同的tag就能夠實現了vlan隔離。如下圖:
但是只使用tag隔離不同網絡還不算完成vlan網絡。因為如果同一個網絡下的兩個虛擬機調度到不同的節點,那么流量要經過一個節點達到另一個節點肯定要經過物理交換機。前面說過tag號就是vlan id。在br-int上定義的tag號不會考慮物理交換機上的vlan id支持。通俗來說就是ovs是虛擬交換機,tag號自己管理,而物理交換機的vlan id是物理交換機管理。這兩個vlan是不同設備的,所有不能保證可以直接通用。萬一ovs定義的vlan為3000,而物理交換機不能識別呢?所以在br-ethx這個網橋上需要對ovs的vlan和物理交換機的vlan做一個轉換。規則也很簡單:
- 在br-ethx上對來自br-int 的數據,將vlan 1轉化成物理網卡能通過的vlan 100
- 在br-int上對來自br-ethx的數據,將vlan 100轉成ovs交換機能通過的vlan 1。
br-int上流表:
#ovs-ofctl dump-flows br-int cookie=0x0, duration=100.795s, table=0, n_packets=6, n_bytes=468, idle_age=90, priority=2,in_port=3 actions=drop cookie=0x0, duration=97.069s, table=0, n_packets=22, n_bytes=6622, idle_age=31, priority=3,in_port=3,dl_vlan=101 actions=mod_vlan_vid:1,NORMAL cookie=0x0, duration=95.781s, table=0, n_packets=8, n_bytes=1165, idle_age=11, priority=3,in_port=3,dl_vlan=102 actions=mod_vlan_vid:2,NORMAL cookie=0x0, duration=103.626s, table=0, n_packets=47, n_bytes=13400, idle_age=11, priority=1 actions=NORMAL
br-ethx上流表:
#ovs-ofctl dump-flows br-eth0 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=73.461s, table=0, n_packets=51, n_bytes=32403, idle_age=2, hard_age=65534, priority=4,in_port=4,dl_vlan=1 actions=mod_vlan_vid:101,NORMAL cookie=0x0, duration=83.461s, table=0, n_packets=51, n_bytes=32403, idle_age=2, hard_age=65534, priority=4,in_port=4,dl_vlan=2 actions=mod_vlan_vid:102,NORMAL cookie=0x0, duration=651.538s, table=0, n_packets=72, n_bytes=3908, idle_age=2574, hard_age=65534, priority=2,in_port=4 actions=drop cookie=0x0, duration=654.002s, table=0, n_packets=31733, n_bytes=6505880, idle_age=2, hard_age=65534, priority=1 actions=NORMAL
vxlan網絡
vxlan網絡看似比較復雜,其實如果能夠理解vlan網絡的ovs tag和物理vlan id轉換原理就好理解。vxlan數據構造比較特殊,其數據結構如下:
在正常的網絡封裝上還有外層,並且重要的是中間還有一個vxlan頭。重點就在這個vxlan的頭,vxlan頭部中有一個tunnel id。不同的vxlan網絡之間使用tunnel id來隔離。ovs實現的vxlan結構如下:
創建虛擬機之后,在br-int上的port會有tag號。不同的網絡之間tag號是不一樣的。那么分情況討論:
- 如果同一網絡的虛擬機都在一個計算節點,同一個br-int上,它們之間的tag是一樣的,所以直接通過br-int轉發數據。不同網絡之間tag不同,br-int根據tag實現隔離。
- 如果同一網絡的虛擬機分布在不同的計算節點上,這時就需要通過bt-tun這個網橋發送出去。在br-tun上維護了一個vlan和vxlan之間的轉換關系。比如對於計算節點1來說:vlan 4 對應了 vxlan 256。這時bt-tun就會把vlan 為4 的數據經過vxlan封裝,封裝成vxlan 256的數據包,然后發送出。同樣當br-tun接收到數據包時,會將vxlan轉化成vlan,然后發送到br-int,br-int 根據不同的vlan轉發到對應虛擬機。
將vlan轉化成vxlan
cookie=0x9814613d8b13e33b, duration=355743.467s, table=22, n_packets=121, n_bytes=5490, idle_age=65534, hard_age=65534, priority=1,dl_vlan=786 actions=strip_vlan,load:0x25a->NXM_NX_TUN_ID[],output:3,output:2,output:5,output:4 cookie=0x9814613d8b13e33b, duration=335047.168s, table=22, n_packets=114, n_bytes=5460, idle_age=23232, hard_age=65534, priority=1,dl_vlan=788 actions=strip_vlan,load:0x222->NXM_NX_TUN_ID[],output:3,output:2,output:5,output:4
將vxlan 轉化成vlan
cookie=0x9814613d8b13e33b, duration=355644.212s, table=4, n_packets=1025, n_bytes=107512, idle_age=17091, hard_age=65534, priority=1,tun_id=0x25a actions=mod_vlan_vid:786,resubmit(,10) cookie=0x9814613d8b13e33b, duration=334947.915s, table=4, n_packets=8487, n_bytes=710987, idle_age=38, hard_age=65534, priority=1,tun_id=0x222 actions=mod_vlan_vid:788,resubmit(,10)
剛好這兩條處理是相互的,可以清晰看出vlan和vxlan之間的轉換。
最后這里有一個有意思的東西,前面說過vxlan網絡下,使用tunnel id 隔離。在不同的計算節點上發現 相同的tunnel id 0x222 對應的vlan 是不一樣的?為什么會這樣?
root@compute15:~# ovs-ofctl dump-flows br-tun | grep 0x222 cookie=0xa6b0faa0153f7efc, duration=335373.158s, table=4, n_packets=4741, n_bytes=9326933, idle_age=26, hard_age=65534, priority=1,tun_id=0x222 actions=mod_vlan_vid:3678,resubmit(,10) cookie=0xa6b0faa0153f7efc, duration=26.944s, table=20, n_packets=0, n_bytes=0, hard_timeout=300, idle_age=26, priority=1,vlan_tci=0x0e5e/0x0fff,dl_dst=fa:16:3e:22:69:3a actions=load:0->NXM_OF_VLAN_TCI[],load:0x222->NXM_NX_TUN_ID[],output:4 cookie=0xa6b0faa0153f7efc, duration=335373.162s, table=22, n_packets=133, n_bytes=36387, idle_age=23569, hard_age=65534, priority=1,dl_vlan=3678 actions=strip_vlan,load:0x222->NXM_NX_TUN_ID[],output:4,output:3,output:2,output:5
同一個tunnel 在不同節點的對應的tag號不一樣,那不同節點上的虛擬機之間vlan不同能夠正常訪問嗎?毫無疑問是可以的,為啥呢?因為在出服務器時br-tun已經將tag剝離,到了相應的服務器時會加上該tunnel id在該服務器上的對應的tag號。每一個服務器上tunnel id對應的tag都是不一樣的,但是只要tunnel id一致就能走遍天下。
ovs實現的vlan就講這么多,一個小小的tag最后發現能夠成為openstack這種巨大架構中很重要的一部分,充分說明難度再大的技術都是由小知識點組成的,所以面對龐然大物時也不要心生畏懼,將其分解成一個個小知識就能掌握。學習如此,人生亦如是~