GRE與Vxlan網絡詳解


1. GRE

1.1 概念

GRE全稱是Generic Routing Encapsulation,是一種協議封裝的格式,具體格式內容見:https://tools.ietf.org/html/rfc2784

協議封裝指的是用一種格式的協議封裝另一種格式的協議。我們熟悉的TCP/IP協議可以看成是一種封裝:TCP傳輸層協議被網絡層的IP協議封裝,通過IP協議來進行傳輸。還有比如很有用的IP SAN,就是通過IP協議封裝scsi協議,使得我們可以直接通過IP網絡來進行磁盤數據的傳輸。對於這兩個例子來說,前一種封裝的目的是通過分層來嚴格的區分協議的設計,使得具體的協議設計的時候可以更加的清晰,而后者則是為了使用現有的設施,方便廠商推廣自己的產品,同時通過兩種協議的結合產生更多的功能。對於GRE來說,應是偏向后者的一種封裝。

GRE的目的是設計一種通用的封裝格式,所以如果將它與一些為特定目的進行設計的封裝協議比較,那么GRE是沒有太多優勢的。

 A GRE encapsulated packet has the form:

    ---------------------------------
    |                               |
    |       Delivery Header         |
    |                               |
    ---------------------------------
    |                               |
    |       GRE Header              |
    |                               |
    ---------------------------------
    |                               |
    |       Payload packet          |
    |                               |
    ---------------------------------

在GRE中,需要被傳輸和封裝的報文稱之為payload packet,而用於封裝和傳輸的協議則成為delivery protocol。GRE在封裝的時候,除了payload和delivery協議的header外,會生成一個GRE header。GRE header + payload一起被delivery協議封裝用於傳輸,GRE header會包含payload的一些信息,包括checksum、version、payload的協議類型等。可以看到,通過這個GRE header的協議類型字段,我們可以做很多的事情。既然底層的delivery協議是用於傳輸的,那么A和B通信的時候delivery協議可以看成是個郵局送信火車,雖然很重要,但是對於業務理解來說沒有其運送的信重要。當脫取這一層delivery層后,我們怎么知道信的格式呢?通過GRE header中的協議類型我們就能知道協議類型了,既然知道了協議類型,那么就有能力解析了。

由於GRE是一種通用的格式,我們可以使用GRE進行很多不同種類的封裝。比如我們可以使用PPTP協議來進行VPN,可以使用IPv4來包裹IPv6。比較常見的delivery協議一般是IP協議

不過GRE在設計的時候有一個問題,那就是沒有考慮加密。因此現在常見的需要加密的封裝一般是用的IPsec協議。

比如說:A主機是在公司,B主機是在家,A網絡的地址為192.168.1.1,B網絡的地址為192.168.2.1,A如果要和B通信,則需要通過互聯網,所以在A連接的路由器RA上,會配置一個tunnel口,tunnel口的信息是(1.1.1.1 -> 2.2.2.2),在B連接的路由器RB上也會配置一個tunnel口,tunnel口的信息是(2.2.2.2 -> 1.1.1.1)。同時在設置好路由的情況下,A發送一個報文給B,報文會首先到RA,RA發現報文需要走互聯網,於是通過tunnel口封裝,封裝的delivery協議的目的地址寫的是配置的RB的地址2.2.2.2。報文到了RB后delivery協議被脫去,然后RB根據路由信息轉發給B。

http://assafmuller.com/2013/10/10/gre-tunnels/

  

當A(192.168.1.1) ping B(192.168.2.1)時,報文是如下形式的:

    從A到RA

    從RA到RB

1.2 Neutron中的GRE

  (http://assafmuller.com/2013/10/14/gre-tunnels-in-openstack-neutron/

  • br-tun網橋信息:
[root@NextGen1 ~]# ovs-vsctl show
911ff1ca-590a-4efd-a066-568fbac8c6fb
[... Bridge br-int omitted ...]
    Bridge br-tun
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
        Port br-tun
            Interface br-tun
                type: internal
        Port "gre-2"
            Interface "gre-2"
                type: gre
                options: {in_key=flow, local_ip="192.168.1.100", out_key=flow, remote_ip="192.168.1.101"}
        Port "gre-1"
            Interface "gre-1"
                type: gre
                options: {in_key=flow, local_ip="192.168.1.100", out_key=flow, remote_ip="192.168.1.102"}

 

  • VM1(10.0.0.1) pings VM2(10.0.0.2) in different nodes :

  Before VM1 can create an ICMP echo request message, VM1 must send out an ARP request for VM2’s MAC address. A quick reminder about ARP encapsulation – It is encapsulated directly in an Ethernet frame – No IP involved (There exists a base assumption that states that ARP requests never leave a broadcast domain therefor IP packets are not needed). The Ethernet frame leaves VM1’s tap device into the host’s br-int. br-int, acting as a normal switch, sees that the destination MAC address in the Ethernet frame is FF:FF:FF:FF:FF:FF – The broadcast address. Because of that it floods it out all ports, including the patch cable linked to br-tun. br-tun receives the frame from the patch cable port and sees that the destination MAC address is the broadcast address. Because of that it will send the message out all GRE tunnels (Essentially flooding the message). But before that, it will encapsulate the message in a GRE header and an IP packet. In fact, two new packets are created: One from 192.168.1.100 to 192.168.1.101, and the other from 192.168.1.100 to 192.168.1.102. The encapsulation over the GRE tunnels looks like this:

  

  To summarize, we can conclude that the flow logic on br-tun implements a learning switch but with a GRE twist. If the message is to a multicast, broadcast, or unknown unicast address it is forwarded out all GRE tunnels. Otherwise if it learned the destination MAC address via earlier messages (By observing the source MAC address, tunnel ID and incoming GRE port) then it forwards it to the correct GRE tunnel.

  • br-tun流表:
[root@NextGen1 ~]# ovs-ofctl dump-flows br-tun
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=182369.287s, table=0, n_packets=5996, n_bytes=1481720, idle_age=52, hard_age=65534, priority=1,in_port=3 actions=resubmit(,2)
 cookie=0x0, duration=182374.574s, table=0, n_packets=14172, n_bytes=3908726, idle_age=5, hard_age=65534, priority=1,in_port=1 actions=resubmit(,1)
 cookie=0x0, duration=182370.094s, table=0, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=1,in_port=2 actions=resubmit(,2)
 cookie=0x0, duration=182374.078s, table=0, n_packets=3, n_bytes=230, idle_age=65534, hard_age=65534, priority=0 actions=drop
 cookie=0x0, duration=182373.435s, table=1, n_packets=3917, n_bytes=797884, idle_age=52, hard_age=65534, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
 cookie=0x0, duration=182372.888s, table=1, n_packets=10255, n_bytes=3110842, idle_age=5, hard_age=65534, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21)
 cookie=0x0, duration=182103.664s, table=2, n_packets=5982, n_bytes=1479916, idle_age=52, hard_age=65534, priority=1,tun_id=0x1388 actions=mod_vlan_vid:1,resubmit(,10)
 cookie=0x0, duration=182372.476s, table=2, n_packets=14, n_bytes=1804, idle_age=65534, hard_age=65534, priority=0 actions=drop
 cookie=0x0, duration=182372.099s, table=3, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=drop
 cookie=0x0, duration=182371.777s, table=10, n_packets=5982, n_bytes=1479916, idle_age=52, hard_age=65534, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1
 cookie=0x0, duration=116255.067s, table=20, n_packets=3917, n_bytes=797884, hard_timeout=300, idle_age=52, hard_age=52, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:1f:19:55 actions=load:0->NXM_OF_VLAN_TCI[],load:0x1388->NXM_NX_TUN_ID[],output:3
 cookie=0x0, duration=182371.623s, table=20, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=resubmit(,21)
 cookie=0x0, duration=182103.777s, table=21, n_packets=10235, n_bytes=3109310, idle_age=5, hard_age=65534, priority=1,dl_vlan=1 actions=strip_vlan,set_tunnel:0x1388,output:3,output:2
 cookie=0x0, duration=182371.507s, table=21, n_packets=20, n_bytes=1532, idle_age=65534, hard_age=65534, priority=0 actions=drop

 

  •  table表流程

  

  •  在openstack中主要是通過ovs,ovs支持GRE。通過GRE,VM之間的ARP、IP報文都能在GRE的封裝下通過IP網絡進行傳遞。不同的網絡通過GRE header中的tunnel id號區別。由於ovs支持openflow協議,為了效率和性能,mac和GRE的路由關系會存放在ovs的流表中。從鏈接中的文章可以看出,GRE有一個缺點,那就是每新增一個計算節點,都需要其和所有其他計算節點以及network控制器建立GRE鏈接。在計算節點很多的時候會有性能問題。

2. vxlan 

2.1 概念

  相比於GRE的通用性,VXLAN主要用於封裝、轉發2層報文。VXLAN全稱Virtual eXtensible Local Area Network,簡單的說就是擴充了的VLAN,其使得多個通過三層連接的網絡可以表現的和直接通過一台一台物理交換機連接配置而成的網絡一樣處在一個LAN中。其將二層報文加上個vxlan header,封裝在一個UDP包中進行傳輸。vxlan header會包括一個24位的ID(稱為VNI),含義類似於VLAN id或者上面提到的GRE的tunnel id。在上面GRE的例子中,是通過路由器來進行GRE協議的封裝和解封的,在VXLAN中這類封裝和解封的組件有個專有的名字叫做VTEP。相比起VLAN來說,好處在於其突破了VLAN只有4094子網的限制,同時架設在UDP協議上后其擴展性提高了不少(因為UDP是高層協議,屏蔽了底層的差異,換句話說屏蔽了二層的差異)。

  表面上看VXLAN和GRE區別不大,只是對delivery協議做了限定,使用UDP。但是實際上在協議的交互動作上面還是有區別的。和上面的例子一樣,假如主機A和主機B想通信,那么A的報文會的被VTEP封裝,然后發往連接B的VTEP。在上面的例子中類似於VTEP的角色是由路由器來充當的,而且路由器的兩端的地址是配置好的,所以RA知道RB的地址,直接將報文發給RB即可。但是在VXLAN中,A的VTEP並不知道B的VTEP在哪,所以需要一個發現的過程。如何發現呢?VXLAN要求每個VNI都關聯一個組播地址。所以對於一次ARP請求,A的VTEP會的發送一個組播IGMP報文給所有同在這個網絡組中的其他VTEP。所有的訂閱了這個組播地址的VTEP會的收到這個報文,學習發送端的A的MAC和VTEP地址用於以后使用,同時VTEP會將報文解析后比較VNI,發送給同VNI的主機。當某個主機B的IP和ARP中的一樣時,其會的發送ARP應答報文,應答報文通過B的VTEP按照類似的流程發送給A,但是由於B的VTEP已經學習到了A的MAC地址,因此B的VTEP直接就可以發送給A的VTEP,而不需要再走一遍通過IGMP的組播過程了。

  從這個例子可以看出,VXLAN屏蔽了UDP的存在,上層基本上不感知這層封裝。同時VXLAN避免了GRE的點對點必須有連接的缺點。由於需要IGMP,對於物理交換機和路由器需要做一些配置,這點在GRE是不需要的。

  vxlan報文格式:

  (http://www.borgcube.com/blogs/2011/11/vxlan-primer-part-1/

  (http://www.borgcube.com/blogs/2012/03/vxlan-primer-part-2-lets-get-physical/

  

  報文走向:

  

2.2 Neutron中的vxlan

  (http://www.opencloudblog.com/?p=300)

  vxlan的br-tun流表與上面GRE類似。

 

2.3 需要vxlan的原因

  • vlan的數量限制
     4094個vlan遠不能滿足大規模雲計算數據中心的需求
  •  物理網絡基礎設施的限制
     基於IP子網的區域划分限制了需要二層網絡連通性的應用負載的部署。即虛擬機遷移后跨 大二層網絡的需求。
  •  TOR交換機MAC表耗盡
      虛擬化以及東西向流量導致更多的MAC表項。使用隧道技術后,記錄的是Delivery Header里的MAC (即VTEP的MAC)。

2.4 vxlan與GRE的主要區別

  若br-tun之間兩兩點對點的連接,通信封包為GRE格式,那么這樣的網絡環境就是OVS-GRE網絡模式。同理,若br-tun之間跑三層網絡協議,封包方式為VXLAN格式,這樣的網絡環境就是OpenStack-Neutron-OVS-VXLAN網絡模式。對於GRE和VXLAN網絡模式而言,可以抽象地將每個br-tun看成隧道端點,有狀態的隧道點對點連接即為GRE;無狀態的隧道使用UDP協議連接則為VXLAN。

  (http://www.sdnlab.com/11819.html) 兩者的區別還是不太懂?

http://bingotree.cn/?p=654 

 

QA:

  • vxlan網絡指定的segment id 就是vxlan的tunnel id,local vlan號則由neutron代碼按序生成,tunnel id 與 local vlan 由br-tun流表來保證一一對應。

   而由於br-tun的port與trunk0的tunnel-bearing子接口相連,tunnel-bearing子接口也帶vlan id,該vlan id放在Delivery Header的vlan id中,是為了與管理網絡隔離。

  • local vlan 與 外部 vlan 區別

   兩個VM所屬segment id 一樣,位於不同server上時,local vlan id 不一定一樣。local vlan只是作用於當前server上,用於隔離該server上的其他VM。

  • br-tun中有關GRE/Vxlan的port是如何生成的?

   ovs-agent啟動時,會上報自己的tunnel local ip 給neutron server ,然后neutron server 會發rpc消息給其他所有 ovs-agent ,在br-tun上建立相關聯的port。

   


免責聲明!

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



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