共計 7652 個字符,預計需要花費 20 分鐘才能閱讀完成。
這篇文章給大家介紹如何理解 vxlan 在 openstack 中的使用場景,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
一、前言
介紹前,首先講一下網絡中 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 實現的方式。
關于如何理解 vxlan 在 openstack 中的使用場景就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。