一、前言
介紹前,首先講一下網絡中underlay和overlay的概念。underlay指的是物理網絡層,overlay是指在物理網絡層之上的邏輯網絡或者又稱爲虛擬網絡。overlay是建立在underlay的基礎上,需要物理網絡中的設備兩兩互聯,overlay的出現突破了underlay的物理侷限性,使得網絡的架構更爲靈活。以vlan爲例,在underlay環境下不同網絡的設備需要連接至不同的交換機下,如果要改變設備所屬的網絡,則要調整設備的連線。引入vlan後,調整設備所屬網絡只需要將設備加入目標vlan下,避免了設備的連線調整。
二、雲環境下vlan的痛點
- vlan id數量不足
vlan header由12bit組成,理論上限爲4096個,可用vlan數量爲1~4094個,無法滿足雲環境下的需求。 - vm熱遷移
雲計算場景下,傳統服務器變成一個個運行在宿主機上的vm。vm是運行在宿主機的內存中,所以可以在不中斷的情況下從宿主機A遷移到宿主機B,前提是遷移前後vm的ip和mac地址不能發生變化,這就要求vm處在一個二層網絡。畢竟在三層環境下,不同vlan使用不同的ip段,否則路由器就犯難了。 - mac表項有限
普通的交換機mac表項有4k或8k等,在小規模場景下不會成爲瓶頸,雲計算環境下每臺物理服務器上運行多臺vm,每個vm有可能有多張vnic,mac地址會成倍增長,交換機的表項限制則成爲必須面對的問題。三、針對痛點vxlan的解決方法
- 以多取勝
vxlan header由24bit組成,所以理論上VNI的數量爲16777216個,解決了vid數量不足的問題。
此處需要說明的是:在openstack中,儘管br-tun上的vni數量增多,但br-int上的網絡類型只能是vlan,所有vm都有一個內外vid(vni)轉換的過程,將用戶層的vni轉換爲本地層的vid。
細心的你可能會有這樣的疑問:儘管br-tun上vni的數量爲16777216個,但br-int上vid只有4096個,那引入vxlan是否有意義?答案是肯定的,以目前的物理機計算能力來說,假設每個vm屬於不同的tenant,1臺物理機上也不可能運行4094個vm,所以這麼映射是有意義的。
上圖是2計算節點間vm通信的示意圖,圖中所有的vm屬於同一個tenant,儘管在用戶層同一tenant的vni一致,但在本地層,同一tenant由nova-compute分配的vid可以不一致,同一宿主機上同一tenant的相同subnet之間的vm相互訪問不需要經過內外vid(vni)轉換,不同宿主機上相同tenant的vm之間相互訪問則需要經過vid(vni)轉換。如果所有宿主機上vid和vni對應關係一致,整個雲環境最多只能有4094個tenant,引入vxlan才真的沒有意義。 - 暗渡陳倉
前面說過,vm的熱遷移需要遷移前後ip和mac地址不能發生管改變,所以需要vm處於一個二層網絡中。vxlan是一種overlay的技術,將原有的報文進行再次封裝,利用udp進行傳輸,所以也稱爲mac in udp,表面上傳輸的是封裝後的ip和mac,實際傳播的是封裝前的ip和mac。
- 銷聲匿跡
在雲環境下,接入交換機的表項大小會成爲瓶頸,解決這個問題的方法無外乎兩種:
1.擴大表項 : 更高級的交換機有着更大的表項,使用高級交換機取代原有接入交換機,此舉會增加成本。
2.隱藏mac地址: 在不增加成本的前提下,使用vxlan也能達到同樣的效果。前文得知,vxlan是對原有的報文再次封裝,實現vxlan功能的vetp角色可以位於交換機或者vm所在的宿主機,如果vtep角色位於宿主機上,接入交換機只會學習經過再次封裝後vtep的mac地址,不會學習其上vm的mac地址。
如果vtep角色位於接入交換機上,處理報文的效率更高,但是接入交換機會學習到vm的mac地址,表項的限制依然沒有得到解決,後續對這兩種情況會做詳細說明。
以上就是openstack場景中使用vxlan的原因,下面將會對vxlan的實現原理進行詳細說明。四、vxlan實現機制
- vxlan報文長什麼樣
vxlan報文是在原有報文的基礎上再次進行封裝,已實現三層傳輸二層的目的。
如上圖所示,原有封裝後的報文成爲vxlan的data部分,vxlan header爲vni,ip層header爲源和目的vtep地址,鏈路層header爲源vtep的mac地址和到目的vtep的下一個設備mac地址。
在筆者所從事的公有云架構中,vtep角色通過宿主機上的ovs實現,宿主機上聯至接入交換機的接口類型爲trunk,在物理網絡中爲vtep專門規劃出一個網絡平面
vm在經過vtep時,通過流表規則,去除vid,添加上vni
vtep平面規劃的vid在vxlan的封裝過程中被打上,原因如下圖所示,vxlan的mac header中可以設置vlan tag
- vtep是什麼
vtep全稱vxlan tunnel endpoint,vxlan可以抽象的理解爲在三層網絡中打通了一條條隧道,起點和終點的兩端就是vetp。vtep是實現vxlan功能的重要模型,可以部署在接入交換機或者服務器上,部署在不同的位置除了前文中提到是否學習vm的mac地址外,實現的機制也所有不同,以下內容如無特別說明,默認vtep部署在接入交換機上,vtep部署在服務器上後面會單獨說明。 - vxlan隧道的建立
對於物理交換機而言,vtep是物理交換機上的一個角色,換句話說,vtep只是交換機上的一部分功能,並非所有的報文都需要走vxlan隧道,報文也可能走普通的二三層轉發。那麼哪些報文需要走vxlan隧道?
如上圖所示,vxlan打造了一個大二層的概念,當連接兩個不同vtep的vm需要進行通信時,就需要建立vxlan隧道。每一個大二層域稱爲一個bridge-domain,簡稱bd,類似於vlan的vid,不同的bd用vni表示,bd與vni是1:1的關係。
創建bd和設置bd與vni對應關係的配置如下:# bridge-domain 10 //創建一個編號爲10的bd vxlan vni 5000 //設置bd10對應的vni爲5000 #
vtep會根據以上配置生成bd與vni的映射關係表,該映射表可以通過命令行查看,如下所示:
有了映射表後,進入vtep的報文就可以根據自己所屬的bd來確定報文封裝時該添加哪個vni。問題就剩下報文根據什麼來確定自己屬於哪個bd。
它可以通過二層子接口接入vxlan隧道和vlan接入vxlan隧道來實現。二層子接口主要做兩件事:一是根據配置來檢查哪些報文需要進入vxlan隧道;二是判斷對檢查通過的報文做怎樣的處理。
如上圖所示,基於二層物理接口10GE 1/0/1,分別創建二層子接口10GE 1/0/1.1和10GE 1/0/1.2,且分別配置其流封裝類型爲dot1q和untag。配置如下:# interface 10GE1/0/1.1 mode l2 //創建二層子接口10GE1/0/1.1 encapsulation dot1q vid 10 //只允許攜帶VLAN Tag 10的報文進入VXLAN隧道 bridge-domain 10 //報文進入的是BD 10 # interface 10GE1/0/1.2 mode l2 //創建二層子接口10GE1/0/1.2 encapsulation untag //只允許不攜帶VLAN Tag的報文進入VXLAN隧道 bridge-domain 20 //報文進入的是BD 20 #
基於二層物理接口10GE 1/0/2,創建二層子接口10GE 1/0/2.1,且流封裝類型爲default。配置如下:
# interface 10GE1/0/2.1 mode l2 //創建二層子接口 10GE1/0/2.1 encapsulation default //允許所有報文進入VXLAN隧道 bridge-domain 30 //報文進入的是BD 30 #
至此,所有條件都已具備,就可以通過協議自動建立vxlan隧道隧道,或者手動指定vxlan隧道的源和目的ip地址在本端vtep和對端vtep之間建立靜態vxlan隧道。對於華爲CE系列交換機,以上配置是在nve(network virtualization Edge)接口下完成的。配置過程如下:
# interface Nve1 //創建邏輯接口 NVE 1 source 1.1.1.1 //配置源VTEP的IP地址(推薦使用Loopback接口的IP地址) vni 5000 head-end peer-list 2.2.2.2 vni 5000 head-end peer-list 2.2.2.3 #
其中,vni 5000的對端vtep有兩個,ip地址分別爲2.2.2.2和2.2.2.3,至此,vxlan隧道建立完成。
VXLAN隧道兩端二層子接口的配置並不一定是完全對等的。正因爲這樣,纔可能實現屬於同一網段但是不同VLAN的兩個VM通過VXLAN隧道進行通信。
總結一下,vxlan目前支持三種封裝類型,如下表所示:
這種方法當有衆多個vni的時候,需要爲每一個vni創建一個子接口,會變得非常麻煩。
此時就應該採用vlan接入vxlan隧道的方法。vlan接入vxlan隧道只需要在物理接口下允許攜帶這些vlan的報文通過,然後再將vlan與bd綁定,建立bd與vni對應的bd信息,最後創建vxlan隧道即可。
vlan與bd綁定的配置如下:# bridge-domain 10 //創建一個編號爲10的bd l2 binding vlan 10 //將bd10與vlan10綁定 vxlan vni 5000 //設置bd10對應的vni爲5000 #
- 同子網vxlan通信流程
如上圖所示,假設vtep是通過接入交換機上的子接口實現,VM_A與VM_C進行首次進行通信。由於是,VM_A上沒有VM_C的MAC地址,所以會發送ARP廣播報文請求VM_C的MAC地址。就以ARP請求報文及ARP應答報文的轉發流程,來說明MAC地址是如何進行學習的。
ARP請求報文的轉發流程如下:
1. VM_A發送源MAC爲MAC_A、目的MAC爲全F、源IP爲IP_A、目的IP爲IP_C的ARP廣播報文,請求VM_C的MAC地址。
2. VTEP_1收到這種BUM(Broadcast&Unknown-unicast&Multicast)請求後,會根據頭端複製列表對報文進行復制,並分別進行封裝。根據二層子接口上的配置判斷報文需要進入VXLAN隧道。確定了報文所屬BD後,也就確定了報文所屬的VNI。同時,VTEP_1學習MAC_A、VNI和報文入接口(Port_1,即二層子接口對應的物理接口)的對應關係,並記錄在本地MAC表中。
3. 報文到達VTEP_2和VTEP_3後,VTEP對報文進行解封裝,得到VM_A發送的原始報文。同時,VTEP_2和VTEP_3學習VM_A的MAC地址、VNI和遠端VTEP的IP地址(IP_1)的對應關係,並記錄在本地MAC表中。之後,VTEP_2和VTEP_3根據二層子接口上的配置對報文進行相應的處理並在對應的二層域內廣播。
VM_B和VM_C接收到ARP請求後,比較報文中的目的IP地址是否爲本機的IP地址。VM_B發現目的IP不是本機IP,故將報文丟棄;VM_C發現目的IP是本機IP,則對ARP請求做出應答。
ARP應答報文轉發流程如下圖所示:
4. 由於此時VM_C上已經學習到了VM_A的MAC地址,所以ARP應答報文爲單播報文,單播報文就不再進行頭端複製。報文源MAC爲MAC_C,目的MAC爲MAC_A,源IP爲IP_C、目的IP爲IP_A。
5. VTEP_3接收到VM_C發送的ARP應答報文後,識別報文所屬的VNI(識別過程與步驟2類似)。同時,VTEP_3學習MAC_C、VNI和報文入接口(Port_3)的對應關係,並記錄在本地MAC表中。之後,VTEP_3對報文進行封裝。這裏封裝的外層源IP地址爲本地VTEP(VTEP_3)的IP地址,外層目的IP地址爲對端VTEP(VTEP_1)的IP地址;外層源MAC地址爲本地VTEP的MAC地址,而外層目的MAC地址爲去往目的IP的網絡中下一跳設備的MAC地址。封裝後的報文,根據外層MAC和IP信息,在IP網絡中進行傳輸,直至到達對端VTEP。
6. 報文到達VTEP_1後,VTEP_1對報文進行解封裝,得到VM_C發送的原始報文。同時,VTEP_1學習VM_C的MAC地址、VNI和遠端VTEP的IP地址(IP_3)的對應關係,並記錄在本地MAC表中。之後,VTEP_1將解封裝後的報文發送給VM_A。
至此,VM_A和VM_C均已學習到了對方的MAC地址。之後,VM_A和VM_C將採用單播方式進行通信。 - 不同子網vxlan通信流程
如上圖所示,VM_A和VM_B分別屬於10.1.10.0/24網段和10.1.20.0/24網段,且分別屬於VNI 5000和VNI 6000。VM_A和VM_B對應的三層網關分別是VTEP_3上BDIF 10和BDIF20的IP地址(BDIF接口的功能與VLANIF接口類似,是基於BD創建的三層邏輯接口,用以實現不同子網VM之間或VXLAN網絡與非VXLAN網絡之間的通信。)。VTEP_3上存在到10.1.10.0/24網段和10.1.20.0/24網段的路由。此時,VM_A想與VM_B進行通信。
由於是首次進行通信,且VM_A和VM_B處於不同網段,VM_A需要先發送ARP廣播報文請求網關(BDIF 10)的MAC,獲得網關的MAC後,VM_A先將數據報文發送給網關;之後網關也將發送ARP廣播報文請求VM_B的MAC,獲得VM_B的MAC後,網關再將數據報文發送給VM_B。以上MAC地址學習的過程與同子網互通中MAC地址學習的流程一致,不再贅述。現在假設VM_A和VM_B均已學到網關的MAC、網關也已經學到VM_A和VM_B的MAC,不同子網VM互通報文轉發流程如下圖所示:
1. VM_A先將數據報文發送給網關。報文的源MAC爲MAC_A,目的MAC爲網關BDIF10的MAC_10,源IP地址爲IP_A,目的IP爲IP_B。
2. VTEP_1收到數據報文後,識別此報文所屬的VNI(VNI 5000),並根據MAC表項對報文進行封裝。這裏封裝的外層源IP地址爲本地VTEP的IP地址(IP_1),外層目的IP地址爲對端VTEP的IP地址(IP_3);外層源MAC地址爲本地VTEP的MAC地址(MAC_1),而外層目的MAC地址爲去往目的IP的網絡中下一跳設備的MAC地址。
3. 報文進入VTEP_3,VTEP_3對報文進行解封裝,得到VM_A發送的原始報文。然後,VTEP_3會對報文做如下處理:
(1) VTEP_3發現該報文的目的MAC爲本機BDIF 10接口的MAC,而目的IP地址爲IP_B(10.1.20.1),所以會根據路由表查找到IP_B的下一跳。
(2) 發現下一跳爲10.1.20.10,出接口爲BDIF 20。此時VTEP_3查詢ARP表項,並將原始報文的源MAC修改爲BDIF 20接口的MAC(MAC_20),將目的MAC修改爲VM_B的MAC(MAC_B)。
(3) 報文到BDIF20接口時,識別到需要進入VXLAN隧道(VNI 6000),所以根據MAC表對報文進行封裝。這裏封裝的外層源IP地址爲本地VTEP的IP地址(IP_3),外層目的IP地址爲對端VTEP的IP地址(IP_2);外層源MAC地址爲本地VTEP的MAC地址(MAC_3),而外層目的MAC地址爲去往目的IP的網絡中下一跳設備的MAC地址。
4. 報文到達VTEP_2後,VTEP_2對報文進行解封裝,得到內層的數據報文,並將其發送給VM_B。VM_B迴應VM_A的流程與上述過程類似,不再贅述。
需要說明的是:VXLAN網絡與非VXLAN網絡之間的互通,也需要藉助於三層網關。其實現不同點在於報文在VXLAN網絡側會進行封裝,而在非VXLAN網絡側不需要進行封裝。報文從VXLAN側進入網關並解封裝後,就按照普通的單播報文發送方式進行轉發。五、vtep角色部署在ovs中
- ovs如何創建vxlan隧道
從前文得知,vtep部署在接入交換機上時還是會學習到vm的mac地址,並沒有解決表項限制問題,這也是爲什麼在公有云場景下vtep角色都是部署在宿主機的ovs中。
不同於在接入交換機上通過手動的方式建立vxlan隧道,openstack中負責網絡的neutron-server啓動後,會自己建立隧道,下面來介紹neutron-server如何自動建立隧道。
如上圖所示,每個宿主機上的ovs是由ovs-aget創建,當計算節點1接入網絡中時,他首先會去向neutron-server報告自己的網絡類型和local_ip,neutron-server收到這些資源信息後(neutron中network、port、subnet都稱爲資源)會進行處理,找到相同網絡類型的其他計算節點併爲他們之間創建隧道,同時將這個消息同步給其他計算節點上的ovs-agent。
每當neutron資源發生變化時,或者ovs對流量不知該處和處理時,都會像neutron-server彙報或等待它的通知,再加上之前的流表,是不是感覺很熟悉?沒錯,neutron-server除了接受api請求外,他還是一個sdn控制器。 - 與接入交換機實現vtep的區別
1. 使用ovs實現的vtep接入交換機只會學習經過vtep封裝後的mac地址,學習不到vm的mac地址,這樣解決了mack地址表項的問題。
2. 物理交換機是通過bd和vni綁定的方法建立不同的隧道,ovs實現時每一個vtep內可以有多個vsi(virtual switch instance),每一個vsi對用一個vni。
以上就是vxlan在openstack中通過物理設備或者ovs實現的方式。