VxLAN原理


VxLAN
 背景介紹:
  從上個世紀虛擬化技術就被提出,但由於硬件技術達不到,而沒能被重視,自本世紀初硬件制造技術越來越來強,導致很多單台物理機只跑一個應用或幾個應用根本無法完全使用硬件的全部性能,導致大量資源浪費,虛擬化也在這個時候被推到了風口浪尖上,最先使用虛擬化技術的當屬數據中心,但馬上人們就發現了問題:
  1. VLAN數量和困境
    VLAN數量嚴重不足,導致超過4096個租戶后,就無法再划分VLAN了,那該如何隔離每個租戶的虛擬機那?
   事實上傳統通過VLAN隔離的網絡,存在諸多不便,比如無法動態調整,網絡擴容困難,更要命的是當物理機出現
   故障或負載過重時對VM做遷移十分不便,這要如何解決?

  2. 二層網絡邊界限制
    在虛擬化之下為了讓VM遷移方便二層網絡不斷擴展,這帶來了二層接入設備越來越多,STP問題越來越突出,
   最直接的就是大量端口因為防環被阻塞,出現了接入到匯聚間帶寬下降了1/4,匯聚到核心間帶寬下降了1/8,
      越接近樹根的交換機,端口阻塞越嚴重,導致整體帶寬資源浪費嚴重,效率低下且成本增加,這還是問題中
   的一部分!【STP(生成樹協議)主要在二層交換網絡中避免交換機出現環路導致"網絡風暴";】
      緊接着二層交換機的MAC地址緩存表告急,但物理機上的VM還在不斷增加,新MAC由於無法緩存,導致
      交換機只能在所有接口上泛洪廣播,導致全網被大量廣播充斥,嚴重影響業務流量,該怎么辦?

  3. 管理困境
   大二層之下如何有效管理物理,提高網絡的利用率,同時又能兼顧上層虛擬化應用?

  在這樣的背景之下,VMware和思科就提出VxLAN(Virtual eXtensible LAN)技術,隨后HP和微軟也提出了NVGRE(Network Virtual GRE),這兩種技術的主要特點是隧道的起點和終點主要在vSwitch上,而非物理交換機上,隧道的封裝在服務器內部的vSwitch上就已經打好,所以進入物理網絡時, 數據包的外層IP都是物理接口上的IP,這就將原本二層幀變成了三層IP報文,直接進行路由轉發即可,這樣就實現了大二層透傳,甚至可跨DC(數據中心)。這兩種技術都各有優劣,VxLAN由於使用了很成熟了四層UDP來承載VxLAN數據體,使得數據包頭變的更大了,而相應的數據區就只能繼續減小,而NVGRE則是對GRE(Generic Routing Encapsulation,通用路由協議封裝)做了升級版,將原GRE協議中低24位用作租戶網絡標識符(TNI),來擴展VLAN,它和VxLAN的VNI一樣,都將VLAN擴展到2的24次方個,但NVGRE最大缺點就是不能支持傳統的復制均衡,因為四層負載均衡需要基於IP和端口來調動,而GRE頭部在四層之前這導致四層負載均衡無法解析GRE頭,也就無法獲取四層端口信息,導致無法對其做負載均衡。這就是"Overlay"網絡誕生的原因,Overlay可翻譯為疊加,即疊加網絡。注: Overlay網絡,不止這些,還有VMware私有的STT,GRE等。


傳統VxLAN
  VxLAN本質上是一種隧道協議的實現,它不依賴於雲,當兩個物理上只能通過三層互通的網絡,若想實現二層互聯時,VxLAN就是一種可選的解決方案,它就類似於VPN(虛擬專用網),只是VPN是為了數據安全而做了安全加密,VxLAN不需要這些,它僅是通過VxLAN協議驅動將原本的以太網幀封裝到VxLAN中,然后在從四層(UDP)開始重新封裝,發送到網絡中后,外面看這個包就是一個普通的IP包,可直接進行直連或路由轉發,所謂直連,就是目標是LAN中的主機,而路由則是需要路由器轉發到報文。

VTEP(VXLAN Tunnel End Point):
  網上經常將其解釋為VxLAN的封裝和解封裝的組件,但我覺得這樣說明容易混淆協議驅動和用戶看到的VxLAN接口,所以在此說明,VTEP可理解為一個虛擬VxLAN隧道接口,當我們想讓自己的應用數據包走VxLAN隧道時,便於我們操作和控制VxLAN隧道的對端是誰。而真正將應用數據封裝到VxLAN是操作系統調用VxLAN協議驅動實現的。

  

     在這個圖中,vxlan0接口就可認為是一個VTEP,當vm1要訪問vm2它倆是要通信,就必須依靠VxLAN-Tunnel來實現。那vm1和vm2如何配置使用vxlan0那?
  事實上這是不需要考慮到,因為p0和vxlan0都是Ovs-vSwitch上的虛擬二層接口,可理解為它們就是普通的交換機接口,交換機接口是二層的,當交換機要將一個數據包發送到網絡上時,它要廣播獲取對方的MAC,然后直接二層轉發即可,vm1要訪問vm2,當vm1發起訪問時,數據包到達vSwitch時,vSwitch查詢MAC地址表,沒有10.0.0.2的MAC,於是在所有端口上泛洪ARP廣播,vxlan0就收到了這個ARP廣播報文,vxlan0接口會將收到的數據發送給VxLAN驅動,VxLAN驅動根據vxlan0即可的配置信息,指定vxlan隧道的對端是192.168.10.23,於是VxLAN驅動開始對整個ARP二層幀作為其傳輸的數據封裝到VxLAN報文中,然后調用TCP/IP協議棧,將VxLAN報文封裝到UDP中,接着繼續封裝IP,鏈路層完成后,報文被寫入發送緩沖區中,內核最終通過DMA芯片將發生緩沖區中的數據發送到網卡,接着數據包就進入物理網絡,在物理網絡中的數據包就是這個樣子的:

  

  可以看到,物理網絡中看到的數據包的源IP:192.168.10.15,目標IP:192.168.10.23,這就是二層直接轉發,或叫大二層的擴展,這種方式也被稱為三層網關方式,當vm1訪問vm2時, 對於vm2來說,它的VxLAN網關就是Server1上vxlan0 。那我們在來看看,VxLAN對VLAN的擴展,這也被稱為二層VxLAN網關,實際和三層一樣,都是相對的。

  

  我們很清楚,VLAN之間是互相隔離的,p0被分到VLAN101了,vxlan0接口在默認VLAN0中,它倆如何通信,但是事實上vxlan0接口會被自動配置為tunck口,所以vxlan0接口依然可以收到vm1發的二層廣播報文,下圖就是VxLAN承載二層VLAN的包結構,也就是所謂的VLAN擴展。

  

   以上拓撲結構若你想測試,可參考下面的OpenVSwitch的配置,這是VMware環境下測試:

  1. 安裝OpenVSwitch
    yum install openvswitch

  2. 啟動OpenVSwitch服務
    systemctl start openvswitch

  3. 創建vSwtich
    ovs-vsctl add-br br-vxlan #br-vxlan就是vSwitch的名字.此名可任意.

  4. 創建VxLAN虛擬網口vxlan0
    #在Server0上配置vxlan0時這樣寫:
      ovs-vsctl add-port br-vxlan tun0 -- set interface tun0 type=vxlan options:remote_ip=192.168.10.23
    #創建了一個VxLAN類型的接口tun0
    #set interface實際上修改了vSwitch配置數據庫中的interface表.
    #OpenVSwitch2.0.0時只能這樣看:
      ovsdb-client dump Open_vSwitch #將默認Open_vSwitch數據庫中的所有數據都dump出來看.

    #OpenVSwitch2.5.x后可這樣單獨看Interface表
      ovsdb-client dump Open_vSwitch Interface

    #在Server1上配置vxlan0是這樣寫:
      ovs-vsctl add-port br-vxlan tun0 -- set interface tun0 type=vxlan options:remote_ip=192.168.10.15

    #若想測試gre,可修改type=gre,或使用下ip link來創建gre隧道.


  查看配置信息:
    ovs-vsctl show

  5. 創建虛擬網口p0
    ovs-vsctl add-port br-vxlan p0 -- set interface p0 type=internal

  6. 創建一個網絡名稱空間,來充當一個簡單的虛擬機
    ip netns add vm1

  #接着將拉一根虛擬網線將vm1與vSwitch br-vxlan的p0口連接起來.
  #但要注意: p0實際上是被關聯到vm1中了,vm1內部默認只有一個lo0接口,
  # 我們需要將一個宿主機上可見的網口摘掉,安裝到vm1中。
  # 關於網絡名稱空間,可參考: 容器原理
    ip link set p0 netns vm1

  #接着對安裝到vm1中的p0網口,配置IP地址
    ip netns exec vm1 ifconfig p0 10.0.0.1/24 up

  #查看配置信息:
    ip netns exec vm1 ifconfig

  7. 接着就可以在VMware Network Adapter VMnet1上抓包來看了。
   #這時在Server0上的vm1中:
    ip netns exec vm1 ping 10.0.0.2

   #在VMnet1上抓包,此時就可以查看VxLAN三層網關的效果了。

  8. 接着來看看二層網關的效果:
    ovs-ofctl show br-vxlan

    

    #在流表中創建一個Action Set(動作集):【注意: 可先在Server0或Server1上配置,然后ping,在抓包看】
    ovs-ofctl add-flow br-vxlan "priority=10,in_port=2,dl_vlan=0xffff,actions=mod_vlan_vid:101,normal"
  #簡單說明:
  # priority:指定規則優先級,數字越大越優先,默認為32768,范圍:0~65535, 建議設置,避免出現違背我們意願的行為發生。
     in_port: 指定對從那個接口進入vSwitch上的流量做匹配.
     vlan: 0xffff 表示匹配所有vlan號,若需精確匹配vlan號,只需指定具有的VLAN號即可,如: vlan=101
     actions: 指定匹配前面兩個條件后,執行的動作集合。
   mod_vlan_vid:101 這是修改VLANID為101
     normal 使數據包服從設備正常的L2/L3處理。(並非所有OpenFlow開關都實現此操作。)

  ovs-ofctl add-flow br-vxlan "priority=8,in_port=3,dl_vlan=101,actions=strip_vlan,output:3"
    #dl_vlan: 指定匹配所有數據包的VLAN ID
    #strip_vlan: 去掉VLAN層
    #output:3 將匹配的流量從編號為2的接口上送出。

 以上兩條流規則就實現對vm1或vm2上出來的流量添加VLAN ID101,並且當收到對方回應時,將VLAN ID 101的VLAN層去掉,還原為正常IP包,發給vm1或vm2.

  下圖就是VxLAN所監聽的端口:

    

   #另外,若你想看看,vxlan0上的數據包是什么樣的,可這樣做:
  OpenVSwitch2.0.0以后這樣配置:
  [root@s23 ~]# ovs-vsctl -- set Bridge br-vxlan mirrors=@my1 \
            -- --id=@m1 get port tun0 -- --id=@a1 get port p1 \
            -- --id=@my1 create mirror name=t1 select-dst-port=@m1 select-src-port=@m1 output-port=@a1
    #說明:
    # 上面實際是配置了一個端口SPAN.
    # SPAN:Switched Port Analyzer(交換端口分析器),這是一種交換機端口鏡像技術,
        目的是將某些端口進入和出去的流量都,復制一份到指定端口 做協議分析.
        注:端口監控分為兩種:本地SPAN 和 遠程SPAN(RSPAN),
       RSPAN:通常采用VLAN來實現將跨交換機的復制端口流量.
    #上面配置的是本地SPAN.
    # OVS2.0.0以后,修改了配置方式
    # 1. 先在指定vSwitch上創建一個鏡像ID
        2. 將想監控 或 監控口的流量復制到那個接口 都定義一個引用ID
        3. 創建鏡像,需要使用name定義鏡像名, select-dst-port和select-src-port
        設置要監控那些接口,需要指定引用ID,可指定多個,用逗號分隔。
        若只需要進入此接口的流量就指定dst,若只需要出去的流量就指定src
        4. output-port設置將監控口的流量復制到那個接口上.
      【注意: p1是又添加到端口,可自行參考前面創建】

  [root@s23 ~]# ovs-vsctl list mirror
    _uuid : 85df4437-c903-4110-9061-1d54d36c0427
    external_ids : {}
    name : "t1"
    output_port : 206ace18-b3e6-4423-9216-5088a60b82c1
    output_vlan : []
    select_all : false
    select_dst_port : [8e1dd937-dd97-4446-89c8-af304ff960a5]
    select_src_port : [8e1dd937-dd97-4446-89c8-af304ff960a5]
    select_vlan : []
    statistics : {tx_bytes=0, tx_packets=0}


下圖是網上找到,畫的非常好的VxLAN通信流程:
  需要注意:
  第二步:當配置了多條VxLAN隧道時,因為初始化時,沒有對方的MAC, VNI,和IP的對應表。因此VxLAN會使用默認的239.1.1.1這個組播地址,對所有VxLAN 隧道接口發送這個報文。
  第三步:VxLAN收到組播包后,VTEP-3 和 VTEP-2都會收到,它們都會先學習一個MAC,VNI,IP到對應條目。接着它倆將VxLAN頭部去掉,還原為原始ARP廣播報文后,轉發到自己所在的LAN中.

  

最后來說說雲之下的VxLAN
  VxLAN本身僅是一個隧道協議,只是因為它能夠解決疊加網絡的問題,所以就將其引入到網絡虛擬化中,成為SDN(軟件定義網絡)中的一種功能實現。SDN是一種網絡虛擬化的整體概念框架,它不是具體的技術,它是一種理念,一種指定如何使用軟件來完成對物理網絡的虛擬化的理論。
  在SDN這種理念下,目前比較知名的API實現是OpenFlow,我在OpenFlow和SDN原理中有較為詳細的說明,由於本人能力有限也無法深入刨析,只能盡可能讓每位認真學習的道友能明白其中大概的原理。由於SDN理念之巨大,OpenFlow也並非是完整的將整個TCP/IP協議棧都抽象化成API的,這點需要知道。在OpenFlow的流行之下,目前已經有很多基於OpenFlow協議實現的軟件:OpenVSwitch就是其中之一。
  下面兩種圖是摘自: https://www.cnblogs.com/sammyliu/p/4627230.html
  它就描述了SDN的理念,下面我簡單做一些說明:
    首先SDN理念是將物理網絡抽象化,將其分為控制平面和數據平面
    OpenFlow將其更具體化了,它將物理網絡轉為了一台PC的架構,即分為硬件層,內核空間 和 用戶空間
    其中對於用戶空間來說,它就是控制平面,內核空間就是數據平面(數據的提供者)
    而從內核空間來看,硬件層是數據平面(實際存儲策略數據,並執行動作者),而內核空間是控制平面(控制策略下發者)

  有了以上概念,就可以繼續說明下圖了
  對於Service Node來說它是實際轉發策略的制定者,也就說它是控制平面,而具體的vxlan驅動是實際運行在硬件中的執行者,可將其理解為一個僅有vxlan功能的物理設備,即數據平面。當VM1發送數據到vxlan101接口上時,vxlan驅動收到了用戶的數據流,但它發現自己不知道如何轉發流量,因為初始化時,VNI,VTEP,MAC對應關系表沒有,因此它就會將該數據包完整轉發給控制器(控制平面),然后控制器負責做出轉發決策,若此時控制器查詢數據庫發現自己也沒有VNI,VTEP,MAC對應關系表的相關條目,於是下發策略讓vxlan101(VTEP)將請求通過組播239.1.1.1組播出去,這樣隧道接口上的加入相同組播組的接口都會收到,並作出相應動作,假如這個VxLAN包中的實際數據是ARP查詢,當目標收到后,它會回應ARP響應后,當vxlan101(3.3.3.3)收到響應后,它會將其轉發給控制平面,控制器將會根據響應學習一條VNI,VTEP,MAC對應關系的條目,並再次告訴數據平面要如何轉發,這樣一個來回后,對於vxlan101(3.3.3.3)這個實際執行者來說,它就緩存了一條轉發策略,下次vm1在發來數據流,它就可以直接執行轉發,而無需將數據包轉發給控制器了。
  下圖僅做參考.

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM