云計(jì)算環(huán)境的一個(gè)典型屬性是多租戶共享物理資源。其中每個(gè)租戶可以構(gòu)建自己專屬的虛擬邏輯網(wǎng)絡(luò),而每個(gè)邏輯網(wǎng)絡(luò)都需要由唯一的標(biāo)識(shí)符來(lái)標(biāo)識(shí)。不同的邏輯網(wǎng)絡(luò)默認(rèn)情況下相互隔離。傳統(tǒng)上,網(wǎng)絡(luò)工程師一般使用VLAN來(lái)隔離不同二層網(wǎng)絡(luò),但VLAN的標(biāo)識(shí)符命名空間只有12位,只能提供4096個(gè)標(biāo)識(shí)符,這無(wú)法滿足大型云計(jì)算環(huán)境的需求。
另外,使用VLAN隔離虛擬邏輯網(wǎng)絡(luò),往往需要對(duì)底層物理網(wǎng)絡(luò)設(shè)備進(jìn)行手動(dòng)配置,這無(wú)法滿足云計(jì)算環(huán)境的自動(dòng)化需求。為了解決VLAN在網(wǎng)絡(luò)虛擬化環(huán)境中應(yīng)用存在的種種問(wèn)題,Cisco,VMware等廠商提出了新的網(wǎng)絡(luò)協(xié)議VXLAN來(lái)隔離虛擬邏輯網(wǎng)絡(luò)。
VxLAN基本原理
VXLAN的全稱為Virtual eXtensible LAN,從名稱看,它的目標(biāo)就是擴(kuò)展VLAN協(xié)議。802.1Q的VLAN TAG只占12位,只能提供4096個(gè)網(wǎng)絡(luò)標(biāo)識(shí)符。而在VXLAN中,標(biāo)識(shí)符擴(kuò)展到24位,能提供16777216個(gè)邏輯網(wǎng)絡(luò)標(biāo)識(shí)符,VXLAN的標(biāo)識(shí)符稱為VNI(VXLAN Network Identifier)。另外,VLAN只能應(yīng)用在一個(gè)二層網(wǎng)絡(luò)中,而VXLAN通過(guò)將原始二層以太網(wǎng)幀封裝在IP協(xié)議包中,在IP基礎(chǔ)網(wǎng)絡(luò)之上構(gòu)建overlay的邏輯大二層網(wǎng)絡(luò)。
我們來(lái)看具體協(xié)議包結(jié)構(gòu)。VXLAN將二層數(shù)據(jù)幀封裝在UDP數(shù)據(jù)包中,構(gòu)建隧道在不同節(jié)點(diǎn)間通信。包結(jié)構(gòu)如圖:
從包結(jié)構(gòu)上可以看到,VXLAN會(huì)額外消耗50字節(jié)的空間。為了防止因數(shù)據(jù)包大小超過(guò)網(wǎng)絡(luò)設(shè)備的MTU值而被丟棄,需要將VM的MTU減少50甚至更多,或者調(diào)整中間網(wǎng)絡(luò)設(shè)備的MTU。
VXLAN協(xié)議中將對(duì)原始數(shù)據(jù)包進(jìn)行封裝和解封裝的設(shè)備稱為VTEP(VXLAN Tunnel End Point),它可以由硬件設(shè)備實(shí)現(xiàn),也可以由軟件實(shí)現(xiàn)。
VXLAN的整體應(yīng)用示意拓樸結(jié)構(gòu)如圖:
我們來(lái)看VXLAN的通信過(guò)程。在上圖的虛擬機(jī)VM1和VM2處于邏輯二層網(wǎng)絡(luò)中。VM1發(fā)出的二層以太網(wǎng)幀由VTEP封裝進(jìn)IP數(shù)據(jù)包,之后發(fā)送到VM2所在主機(jī)。VM2所在主機(jī)接收到IP報(bào)文后,解封裝出原始的以太網(wǎng)幀再轉(zhuǎn)發(fā)給VM2。
然而,VM1所在主機(jī)的VTEP做完數(shù)據(jù)封裝后,如何知道要將封裝后的數(shù)據(jù)包發(fā)到哪個(gè)VTEP呢?實(shí)際上,VTEP通過(guò)查詢轉(zhuǎn)發(fā)表來(lái)確定目標(biāo)VTEP地址,而轉(zhuǎn)發(fā)表通過(guò)泛洪和學(xué)習(xí)機(jī)制來(lái)構(gòu)建。目標(biāo)MAC地址在轉(zhuǎn)發(fā)表中不存在的流量稱為未知單播(Unknown unicast)。廣播(broadcast)、未知單播(unknown unicast)和組播(multicast)一般統(tǒng)稱為BUM流量。VXLAN規(guī)范要求BUM流量使用IP組播進(jìn)行洪泛,將數(shù)據(jù)包發(fā)送到除源VTEP外的所有VTEP。目標(biāo)VTEP發(fā)送回響應(yīng)數(shù)據(jù)包時(shí),源VTEP從中學(xué)習(xí)MAC地址、VNI和VTEP的映射關(guān)系,并添加到轉(zhuǎn)發(fā)表中。后續(xù)VTEP再次發(fā)送數(shù)據(jù)包給該MAC地址時(shí),VTEP會(huì)從轉(zhuǎn)發(fā)表中直接確定目標(biāo)VTEP,從而只發(fā)送單播數(shù)據(jù)到目標(biāo)VTEP。
OpenvSwitch沒(méi)有實(shí)現(xiàn)IP組播,而是使用多個(gè)單播來(lái)實(shí)現(xiàn)洪泛。洪泛流量本身對(duì)性能有一定影響,可以通過(guò)由controller收集相應(yīng)信息來(lái)填充轉(zhuǎn)發(fā)表而避免洪泛。
Linux環(huán)境中常用的VXLAN實(shí)現(xiàn)有兩種:
Linux內(nèi)核實(shí)現(xiàn)
OpenvSwitch實(shí)現(xiàn)接下來(lái)分別以實(shí)例來(lái)說(shuō)明。
Linux 的實(shí)現(xiàn)
首先看Linux內(nèi)核實(shí)現(xiàn)實(shí)例。我們的測(cè)試環(huán)境有三臺(tái)主機(jī),物理網(wǎng)卡IP分別為192.168.33.12/24, 192.168.33.13/24和192.168.33.14/24。我們?cè)诿颗_(tái)機(jī)器上創(chuàng)建一個(gè)Linux Bridge, 三臺(tái)主機(jī)上的Linux Bridge默認(rèn)接口的IP分別設(shè)置為10.1.1.2/24, 10.1.1.3/24和10.1.1.4/24。此時(shí)三臺(tái)主機(jī)的Linux網(wǎng)橋處于同一虛擬二層網(wǎng)絡(luò),但由于沒(méi)有相互連接,所以無(wú)法互相訪問(wèn)。我們通過(guò)建立VXLAN隧道使其可互相訪問(wèn)實(shí)現(xiàn)虛擬二層網(wǎng)絡(luò)10.1.1.0/24。網(wǎng)絡(luò)結(jié)構(gòu)如圖:
首先在主機(jī)1上創(chuàng)建Linux網(wǎng)橋:
brctl?addbr?br0
給網(wǎng)橋接口設(shè)置IP并啟動(dòng):
ip?addr?add?10.1.1.2/24?dev?br0 ip?link?set?up?br0
我們從主機(jī)1訪問(wèn)主機(jī)2上的虛擬二層網(wǎng)絡(luò)IP, 訪問(wèn)失敗:
[root@localhost?vagrant]#?ping?10.1.1.3 PING?10.1.1.3?(10.1.1.3):?56?data?bytes ^C ---?10.1.1.3?ping?statistics?--- 1?packets?transmitted,?0?packets?received,?100.0%?packet?loss
接下來(lái),我們添加VTEP虛擬接口vxlan0, 并加入組播IP:239.1.1.1, 后續(xù)發(fā)送到該組播IP的數(shù)據(jù)包,該VTEP都可以接收到:
ip?link?add?vxlan0?type?vxlan?id?1?group?239.1.1.1?dev?eth1?dstport?4789
將虛擬接口vxlan0連接到網(wǎng)橋:
brctl?addif?br0?vxlan0
在另外兩臺(tái)主機(jī)上也完成相似配置后,我們開(kāi)始測(cè)試。
首先在主機(jī)1查看VTEP的轉(zhuǎn)發(fā)表,可以看到此時(shí)只有一條組播條目,所有發(fā)出流量都將發(fā)送給該組播IP:
[root@localhost?vagrant]#?bridge?fdb?show?dev?vxlan0 000000:00?dst?239.1.1.1?via?eth1?self?permanent
我們?cè)俅螐闹鳈C(jī)1上訪問(wèn)主機(jī)2上的網(wǎng)橋IP, 此時(shí)訪問(wèn)成功:
[root@localhost?vagrant]#?ping?10.1.1.3 PING?10.1.1.3?(10.1.1.3)?56(84)?bytes?of?data. 64?bytes?from?10.1.1.3:?icmp_seq=1?ttl=64?time=1.58?ms 64?bytes?from?10.1.1.3:?icmp_seq=2?ttl=64?time=0.610?ms ^C ---?10.1.1.3?ping?statistics?--- 2?packets?transmitted,?2?received,?0%?packet?loss,?time?1001ms rtt?min/avg/max/mdev?=?0.610/1.096/1.582/0.486?ms
此時(shí)再次在主機(jī)1上查看VTEP轉(zhuǎn)發(fā)表,可以看到轉(zhuǎn)發(fā)表中已經(jīng)學(xué)習(xí)到10.1.1.3所在主機(jī)的VTEP地址:192.168.33.13,下次再發(fā)送數(shù)據(jù)給10.1.13所對(duì)應(yīng)的MAC該直接發(fā)送到192.168.33.13:
[root@localhost?vagrant]#?bridge?fdb?show?dev?vxlan0 000000:00?dst?239.1.1.1?via?eth1?self?permanent 2ea27b:31?dst?192.168.33.13?self
我們根據(jù)主機(jī)2上tcpdump的抓包結(jié)果來(lái)分析具體過(guò)程:
1454.330846?IP?192.168.33.12.38538?>?239.1.1.1.4789:?VXLAN,?flags?[I]?(0x08),?vni?1 ARP,?Request?who-has?10.1.1.3?tell?10.1.1.2,?length?28
10.1.1.2所在主機(jī)不知道10.1.1.3對(duì)應(yīng)的MAC地址,因而發(fā)送ARP廣播,ARP數(shù)據(jù)包發(fā)送至VTEP,VTEP進(jìn)行封裝并洪泛給組播IP:239.1.1.1。
1454.330975?IP?192.168.33.13.58823?>?192.168.33.12.4789:?VXLAN,?flags?[I]?(0x08),?vni?1 ARP,?Reply?10.1.1.3?is-at?2ea27b:31,?length?28
主機(jī)2收到數(shù)據(jù)包之后解封裝,VTEP會(huì)學(xué)習(xí)數(shù)據(jù)包的MAC及VTEP地址,將其添加到轉(zhuǎn)發(fā)表,并將解封后的數(shù)據(jù)幀發(fā)送到網(wǎng)橋接口10.1.1.3。10.1.1.3的接口發(fā)送ARP響應(yīng)。
1454.332055?IP?192.168.33.12.48980?>?192.168.33.13.4789:?VXLAN,?flags?[I]?(0x08),?vni?1 IP?10.1.1.2?>?10.1.1.3:?ICMP?echo?request,?id?4478,?seq?1,?length?64
主機(jī)1之后開(kāi)始發(fā)送ICMP數(shù)據(jù)包,從這里可以看出外層IP地址不再為組播IP,而是學(xué)習(xí)到的192.168.33.13。
1454.332225?IP?192.168.33.13.55921?>?192.168.33.12.4789:?VXLAN,?flags?[I]?(0x08),?vni?1 IP?10.1.1.3?>?10.1.1.2:?ICMP?echo?reply,?id?4478,?seq?1,?length?64
接著,10.1.1.3發(fā)送回ICMP響應(yīng)包。
OvS 的實(shí)現(xiàn)
下面再來(lái)說(shuō)明OpenvSwitch實(shí)現(xiàn)實(shí)例。
OVS不支持組播,需要為任意兩個(gè)主機(jī)之間建立VXLAN單播隧道。與上邊示例的拓樸結(jié)構(gòu)相比,我們使用了兩個(gè)OVS網(wǎng)橋,將虛擬邏輯網(wǎng)絡(luò)的接口接入網(wǎng)橋br-int,將所有VXLAN接口接入br-tun。兩個(gè)網(wǎng)橋使用PATCH類型接口進(jìn)行連接。由于網(wǎng)橋br-tun上有多個(gè)VTEP,當(dāng)BUM數(shù)據(jù)包從其中某個(gè)VTEP流入時(shí),數(shù)據(jù)包會(huì)從其他VTEP接口再流出,這會(huì)導(dǎo)致數(shù)據(jù)包在主機(jī)之間無(wú)限循環(huán)。因而我們需要添加流表使VTEP流入的數(shù)據(jù)包不再轉(zhuǎn)發(fā)至其他VTEP。若邏輯網(wǎng)絡(luò)接口與VTEP連接同一網(wǎng)橋,配置流表將比較繁瑣。單獨(dú)將邏輯網(wǎng)絡(luò)接口放到獨(dú)立的網(wǎng)橋上,可以使流表配置非常簡(jiǎn)單,只需要設(shè)置VTEP流入的數(shù)據(jù)包從PATCH接口流出。
拓樸結(jié)構(gòu)如圖:
首先在主機(jī)1上創(chuàng)建網(wǎng)橋br-int和br-tun:
ovs-vsctl?add-br?br-int ovs-vsctl?add-br?br-tun
創(chuàng)建PATCH接口連接br-int和br-tun:
ovs-vsctl?add-port?br-int?patch-int?--?set?interface?patch-int?type=patch?options:peer=patch-tun ovs-vsctl?add-port?br-tun?patch-tun?--?set?interface?patch-tun?type=patch?options:peer=patch-int
創(chuàng)建單播VTEP連接主機(jī)2:
ovs-vsctl?add-port?br-tun?vxlan0?--?set?interface?vxlan0?type=vxlan?options:remote_ip=192.168.33.13
創(chuàng)建單播VTEP連接主機(jī)3:
ovs-vsctl?add-port?br-tun?vxlan1?--?set?interface?vxlan1?type=vxlan?options:remote_ip=192.168.33.14
接下來(lái),我們給br-tun添加流表來(lái)處理流量。
首先查看br-tun上各接口的PORT ID,從結(jié)果看到Patch Port為1,VTEP分別為5和6:
[root@localhost?vagrant]#?ovs-ofctl?show?br-tun OFPT_FEATURES_REPLY?(xid=0x2):?dpid:00006e12f4fd6949 n_tables:254,?n_buffers:256 capabilities:?FLOW_STATS?TABLE_STATS?PORT_STATS?QUEUE_STATS?ARP_MATCH_IP actions:?output?enqueue?set_vlan_vid?set_vlan_pcp?strip_vlan?mod_dl_src?mod_dl_dst?mod_nw_src?mod_nw_dst?mod_nw_tos?mod_tp_src?mod_tp_dst 1(patch-tun):?addrfafbbf ?????config:?????0 ?????state:??????0 ?????speed:?0?Mbps?now,?0?Mbps?max 5(vxlan0):?addr6585ea ?????config:?????0 ?????state:??????0 ?????speed:?0?Mbps?now,?0?Mbps?max 6(vxlan1):?addr38fa98 ?????config:?????0 ?????state:??????0 ?????speed:?0?Mbps?now,?0?Mbps?max LOCAL(br-tun):?addr12fd49 ?????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
清空br-tun流表:
ovs-ofctl?del-flows?br-tun
數(shù)據(jù)包進(jìn)入br-tun后開(kāi)始匹配table 0的流。我們使用table 0區(qū)分流量來(lái)源。來(lái)源于br-int的數(shù)據(jù)包由table 1處理,VTEP流入的數(shù)據(jù)交由table 2處理, 并丟棄其他PORT進(jìn)入的數(shù)據(jù)包:
ovs-ofctl?add-flow?br-tun?"table=0,priority=1,in_port=1?actions=resubmit(,1)” ovs-ofctl?add-flow?br-tun?"table=0,priority=1,in_port=5?actions=resubmit(,2)"? ovs-ofctl?add-flow?br-tun?"table=0,priority=1,in_port=6?actions=resubmit(,2)” ovs-ofctl?add-flow?br-tun?"table=0,priority=0,actions=drop”
接著添加table 1的流, table 1用于處理來(lái)自br-int的流量,單播數(shù)據(jù)包交由table 20處理,多播或廣播數(shù)據(jù)包交由table 21處理:
ovs-ofctl?add-flow?br-tun?"table=1,priority=0,dl_dst=000000:00/010000:00,actions=resubmit(,20)” ovs-ofctl?add-flow?br-tun?"table=1,priority=0,dl_dst=010000:00/010000:00,actions=resubmit(,21)”
table 21處理廣播流量,將數(shù)據(jù)包從所有VTEP的PORT口發(fā)出:
ovs-ofctl?add-flow?br-tun?"table=21,priority=0,actions=output:5,output:6”
table 2處理VTEP流入的數(shù)據(jù)包,在這里我們實(shí)現(xiàn)學(xué)習(xí)機(jī)制。來(lái)自VTEP的數(shù)據(jù)包到達(dá)后,table 2從中學(xué)習(xí)MAC地址,VNI、PORT信息,并將學(xué)習(xí)到的流寫(xiě)入table 20中,并將流量由PATCH口發(fā)送到br-int上, 并將學(xué)習(xí)到的流優(yōu)先級(jí)設(shè)為1:
ovs-ofctl?add-flow?br-tun?"table=2,priority=0,actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),?output:1”
table 20處理單播流量,我們將默認(rèn)流優(yōu)先級(jí)設(shè)置為0。因?yàn)閷W(xué)習(xí)到的流優(yōu)先級(jí)設(shè)置為1,因而只有匹配不到目標(biāo)MAC的未知單播交由table 21處理,table 21將流量廣播到所有VTEP:
ovs-ofctl?add-flow?br-tun?"table=20,priority=0,actions=resubmit(,21)"
整體處理邏輯如圖:
我們查看流表, 發(fā)現(xiàn)table 20中只有一條默認(rèn)添加的流:
[root@localhost?vagrant]#?ovs-ofctl?dump-flows?br-tun?table=20 NXST_FLOW?reply?(xid=0x4): cookie=0x0,?duration=1.832s,?table=20,?n_packets=0,?n_bytes=0,?idle_age=1,?priority=0?actions=resubmit(,21)
我們從主機(jī)1訪問(wèn)主機(jī)3上的虛擬網(wǎng)絡(luò)IP,訪問(wèn)成功:
[root@localhost?vagrant]#?ping?10.1.1.4?-c?2 PING?10.1.1.4?(10.1.1.4)?56(84)?bytes?of?data. 64?bytes?from?10.1.1.4:?icmp_seq=1?ttl=64?time=1.45?ms 64?bytes?from?10.1.1.4:?icmp_seq=2?ttl=64?time=0.538?ms ---?10.1.1.4?ping?statistics?--- 2?packets?transmitted,?2?received,?0%?packet?loss,?time?1002ms rtt?min/avg/max/mdev?=?0.538/0.994/1.451/0.457?ms
我們?cè)俅尾榭戳鞅? 發(fā)現(xiàn)table 20中已經(jīng)多了一條學(xué)習(xí)到的流,下次再向該MAC發(fā)送數(shù)據(jù)包,數(shù)據(jù)將直接從PORT 6中發(fā)出:
[root@localhost?vagrant]#?ovs-ofctl?dump-flows?br-tun?table=20 NXST_FLOW?reply?(xid=0x4): cookie=0x0,?duration=164.902s,?table=20,?n_packets=36,?n_bytes=3360,?hard_timeout=300,?idle_age=19,?hard_age=19,?priority=1,dl_dst=ee090e:46?actions=load:0->NXM_NX_TUN_ID[],output:6 cookie=0x0,?duration=223.811s,?table=20,?n_packets=1,?n_bytes=98,?idle_age=164,?priority=0?actions=resubmit(,21)
本文簡(jiǎn)要介紹了VXLAN的原理和實(shí)例。
編輯:黃飛
評(píng)論
查看更多