學習 Neutron 系列文章:
LAN 表示 Local Area Network,本地區域網路,通常使用 Hub 和 Switch 來連接配接LAN 中的計算機。一般來說,當你将兩台計算機連入同一個 Hub 或者 Switch 時,它們就在同一個 LAN 中。同樣地,你連接配接兩個 Switch 的話,它們也在一個 LAN 中。一個 LAN 表示一個廣播域,它的意思是,LAN 中的所有成員都會收到 LAN 中一個成員發出的廣播包。可見,LAN 的邊界在路由器或者類似的3層裝置。
VLAN 表示 Virutal LAN。一個帶有 VLAN 功能的switch 能夠同時處于多個 LAN 中。最簡單地說,VLAN 是一種将一個交換機分成多個交換機的一種方法。比方說,你有兩組機器,group A 和 B,你想配置成組 A 中的機器可以互相通路,B 中的機器也可以互相通路,但是A組中的機器不能通路B組中的機器。你可以使用兩個交換機,兩個組分别接到一個交換機。如果你隻有一個交換機,你可以使用 VLAN 達到同樣的效果。你在交換機上配置設定配置連接配接組A和B的機器的端口為 VLAN access ports。這個交換機就會隻在同一個 VLAN 的端口之間轉發包。

(圖1)
IEEE 802.1Q 标準定義了 VLAN Header 的格式。它在普通以太網幀結構的 SA (src addr)之後加入了 4bytes 的 VLAN Tag/Header 資料,其中包括 12-bits 的 VLAN ID。VLAN ID 最大值為4096,但是有效值範圍是 1 - 4094。
(圖2)
帶 VLAN 的交換機的端口分為兩類:
Access port:這些端口被打上了 VLAN Tag。離開交換機的 Access port 進入計算機的以太幀中沒有 VLAN Tag,這意味着連接配接到 access ports 的機器不會覺察到 VLAN 的存在。離開計算機進入這些端口的資料幀被打上了 VLAN Tag。
Trunk port: 有多個交換機時,組A中的部分機器連接配接到 switch 1,另一部分機器連接配接到 switch 2。要使得這些機器能夠互相通路,你需要連接配接兩台交換機。 要避免使用一根電纜連接配接每個 VLAN 的兩個端口,我們可以在每個交換機上配置一個 VLAN trunk port。Trunk port 發出和收到的資料包都帶有 VLAN header,該 header 表明了該資料包屬于那個 VLAN。是以,隻需要分别連接配接兩個交換機的一個 trunk port 就可以轉發所有的資料包了。通常來講,隻使用 trunk port 連接配接兩個交換機,而不是用來連接配接機器和交換機,因為機器不想看到它們收到的資料包帶有 VLAN Header。
(圖3)
(1)基于端口的 VLAN (untagged VLAN - 端口屬于一個VLAN,資料幀中沒有VLAN tag)
這種模式中,在交換機上建立若幹個VLAN,在将若幹端口放在每個VLAN 中。每個端口在某一時刻隻能屬于一個VLAN。一個 VLAN 可以包含所有端口,或者部分端口。每個端口有個PVID (port VLAN identifier)。這種模式下,一個端口上收到的 frame 是 untagged frame,是以它不包含任何有關 VLAN 的資訊。VLAN 的關系隻能從端口的 PVID 上看出來。交換機在轉發 frame 時,隻将它轉發到相同 PVID 的端口。
如上圖所示,連接配接兩個交換機的同一個 VLAN 中的兩個計算機需要通信的話,需要在兩個交換機之間連兩根線:
一根從 Switch A 端口4 到 Switch B 端口 4 (VLAN 1)
一根從 Switch A 端口8 到 Switch B 端口 8 (VLAN 2)
(2)Tagged VLANs (資料幀中帶有 VLAN tag)
這種模式下,frame 的VLAN 關系是它自己攜帶的資訊中儲存的,這種資訊叫 a tag or tagged header。當交換機收到一個帶 VLAN tag 的幀,它隻将它轉發給具有同樣 VID 的端口。一個能夠接收或者轉發 tagged frame 的端口被稱為 a tagged port。所有連接配接到這種端口的網絡裝置必須是 802.1Q 協定相容的。這種裝置必須能處理 tagged frame,以及添加 tag 到其轉發的 frame。
上圖中,兩個交換機上的端口8 支援 VLAN 1 和 2, 是以一根線就可以了實作跨交換機的同VLAN 内的計算機互相通信了。
在實際的VLAN 配置中的各種情況:
交換機的所有端口,部分是 tagged port,部分被添加到 VLAN 中。
一個 untagged port,不管它是一個基于端口的VLAN 的一個成員還是一個 tagged VLAN 中的一個成員,一個時刻隻能在一個 VLAN 中。
一個 tagged port,可以是多個 VLAN 的成員。
一個 port,可以同時是一個 VLAN 的 untagged member,以及不同 VLAN 中的 tagged member。
以太網端口有三種鍊路類型:Access、Hybrid和Trunk。
Access類型的端口隻能屬于1個VLAN,一般用于連接配接計算機的端口
這種類型的端口允許接收沒有打标簽的幀,再發出去時将會被打上标簽。
Trunk類型的端口可以屬于多個VLAN,可以接收和發送多個VLAN的封包,一般用于交換機之間連接配接的端口
在配置 trunk 口時,可以指定允許接收的VLAN 的 ID 區間,還可以配置一個 Native VLAN (預設VID,也稱為 PVID)。當設定了 PVID 時,沒有打标簽的進來的幀将被打上PVID 的 tag再被發出去。
Hybrid類型的端口可以屬于多個VLAN,可以接收和發送多個VLAN的封包,可以用于交換機之間連接配接,也可以用于連接配接使用者的計算機。Hybrid端口和Trunk端口的不同之處在于Hybrid端口可以允許多個VLAN的封包發送時不打标簽,而Trunk端口隻允許預設VLAN的封包發送時不打标簽。
各種類型:
Access (接收) Tagged = PVID 不接收 注:部分高端産品可能接收。
Access (接收) Tagged =/ PVID 不接收 注:部分高端産品可能接收。
Access (接收) Untagged 接收 增加tag=PVID 從PC
Access (發送) Tagged = PVID 轉發 删除tag
Access (發送) Tagged =/ PVID 不轉發 不處理
Access (發送) Untagged 無此情況
Trunk (接收) Tagged = PVID 接收 不修改tag
Trunk (接收) Tagged =/ PVID 接收 不修改tag
Trunk (接收) Untagged 接收 增加tag=PVID
Trunk (發送) Tagged = PVID If Passing then 轉發 删除tag
Trunk (發送) Tagged =/ PVID If Passing then 轉發 不修改tag
Trunk (發送) Untagged 無此情況
Hybrid (接收) Tagged = PVID 接收 不修改tag 對端是trunk
Hybrid (接收) Tagged =/ PVID 接收 不修改tag 對端是trunk
Hybrid (接收) Untagged 接收 增加tag=PVID 類Trunk
Hybrid (發送) Tagged = PVID Tag 和 untag 中列出的vlan可以passing 看Tag項和untag項
Hybrid (發送) Tagged =/ PVID Tag 和 untag 中列出的vlan可以passing 看Tag項和untag項
Hybrid (發送) Untagged 無此情況
解釋:
主機隻能處理标準以太幀(沒打标簽的),交換機内部的幀都是打了标簽的。
收封包:Acess端口1 收到一個封包,判斷是否有VLAN資訊:如果沒有則打上端口的PVID,并進行交換轉發,如果有則直接丢棄(預設)
發封包:Acess端口1 将封包的VLAN資訊剝離,直接發送出去
收封包:trunk端口: 1、收到一個封包,判斷是否有VLAN資訊:如果沒有則打上端口的PVID,并進行交換轉發,如果有判斷該trunk端口是否允許該 VLAN的資料進入:如果可以則轉發,否則丢棄
發封包:trunk端口: 1、比較端口的PVID和将要發送封包的VLAN資訊,如果兩者相等則剝離VLAN資訊,再發送,如果不相等則直接發送
收封包: hybrid端口: 1、收到一個封包 2、判斷是否有VLAN資訊:如果沒有則打上端口的PVID,并進行交換轉發,如果有則判斷該hybrid端口是否允許該VLAN的資料進入:如果可以則轉發,否則丢棄
發封包:hybrid端口:1、判斷該VLAN在本端口的屬性(disp interface 即可看到該端口對哪些VLAN是untag, 哪些VLAN是tag)2、如果是untag則剝離VLAN資訊,再發送,如果是tag則直接發送
tagged (進)
untagged(進)
出 (交換機在做交換時,隻會把幀發給包含其 VID 的端口)
Access 端口
丢棄
打上 PVID
剝離 VID,此時的幀為标準以太網幀
Trunk 端口
如果是允許的,則不變;否則丢棄
如果 VID 與 PVID 不同,則透傳;如果 VID 與 PVID 相同,則剝離 VID
VLAN 使用 12-bit 的 VLAN ID,是以 VLAN 的第一個不足之處就是它最多隻支援 4096 個 VLAN 網絡(當然這還要除去幾個預留的),對于大型資料中心的來說,這個數量是遠遠不夠的。
VLAN 是基于 L2 的,是以很難跨越 L2 的邊界,在很大程度上限制了網絡的靈活性。
VLAN 操作需手工介入較多,這對于管理成千上萬台機器的管理者來說是難以接受的。
二層交換機最基本的功能包括:
MAC 位址學習:當交換機從它的某個端口收到資料幀時,它将端口的 ID 和幀的源 MAC 位址儲存到它的内部MAC表中。這樣,當将來它收到一個要轉發到該 MAC 位址的幀時,它就知道直接從該端口轉發出去了。
資料幀轉發:交換機在将從某個端口收到資料幀,再将其從某個端口轉發出去之前,它會做一些邏輯判斷:
如果幀的目的 MAC 位址是廣播或者多點傳播位址的話,将其從交換機的所有端口(除了傳入端口)上轉發。
如果幀的目的MAC位址在它的内部MAC表中能找到對應的輸出端口的話(MAC 位址學習過程中儲存的),将其從該端口上轉發出去。
對其它情況,将其從交換機的所有端口(除了傳入端口)上轉發。
加 VLAN 标簽/去 VLAN 标簽:
幀接收:從 trunk port 上收到的資料幀必須是加了标簽的。從 access port 上收到的資料幀必須是沒有加标簽的,否則該幀将會被抛棄。
幀處理:根據上述轉發流程決定其發出的端口。
幀發出:從 trunk port 發出的幀是加了标簽的。從 access port 上發出的幀必須是沒加标簽的。
預設情況下,交換機的所有端口都處于VLAN 1 中,也就相當于沒有配置 VLAN。該機制說明如下:
(圖4)
PC A 發一個幀到交換機的 1 端口,其目的MAC位址為 PC B 的 MAC。
交換機比較其目的 MAC 位址和它的内部 MAC Table,發現它不存在(此時表為空)。在決定泛洪之前,它把端口 1 和 PC A 的 MAC 位址存進它的 MAC Table。
交換機将幀拷貝多份,分别從2和3端口發出。
PC B 收到該幀以後,發現其目的 MAC 位址和他自己的 MAC 位址相同。它發出一個回複幀進入端口3。
交換機将 PC B 的 MAC位址和端口3 存在它的 MAC 表中。
因為該幀的目的位址為PC A 的 MAC 位址它已經在 MAC 表中,交換機直接将它轉發到端口1,達到PC A。
配置了 VLAN 的交換機的該機制類似,隻不過:
(1)MAC 表格中每一行有不同的 VLAN ID。做比較的時候,拿傳入幀的目的 MAC 位址和 VLAN ID 和此表中的行資料相比較。如果都相同,則選擇其 Ports 作為轉發出口端口。
(圖5)
(2)如果沒有吻合的表項,則将此幀從所有有同樣 VLAN ID 的 Access ports 和 Trunk ports 轉發出去。
二層網絡使用 MAC (media access control address)位址作為硬體的唯一辨別。基于 TCP/IP 協定的軟體使用 ARP 來将 IP 位址轉化為 MAC 位址。
1. 目的 IP 位址在同一網段的話
(圖6)
該示例中,Host A 和 B 在同一個網段中。A 的 IP 位址是 10.0.0.99,B 的 IP 位址是 10.0.0.100。當 A 要和 B 通信時,A 需要知道 B 的 MAC 位址。該過程經過以下步驟:
(1)A 上的 IP 協定棧知道通過B 的 IP 位址可以直接到達 B。A 檢查它的本地 ARP 緩存來看B 的 MAC 位址是否已經存在。
(2)如果A 沒有發現B 的 MAC 位址,它發出一個 ARP 廣播請求,來詢問“10.0.0.100 的 MAC 位址是什麼?”,該資料包:
(3)該網段中所有的電腦都将收到該包,并且會檢查 DST IP 和自己的IP 是否相同。如果不同,則丢棄該包。Host B 發現其IP 位址和 DST IP 相同,它将 A 的 IP/MAP 位址加入到自己的ARP 緩存中。
(4)B 發出一個 ARP 回複消息
(5)交換機直接将該包交給 host A。A 收到後,将 B 的 MAC/IP 位址緩存到 ARP 緩存中。
(6)A 使用 B 的 MAC 作為目的 MAC 位址發出 IP 包。
2. 目的IP 位址不在同一個網段的話
(圖7)
本例子中,A 的位址是 10.0.0.99, B 的位址是 192.168.0.99。Router 的 interface 1 和 A 在同一個網段,其IP 位址為10.0.0.1;interface 2 和 B 在同一個網段,其IP位址為 192.168.0.1。
A 使用下面的步驟來擷取 Router 的 interface 1 的 MAC 位址。
(1)根據其路由表,A 上的 IP 協定知道需要通過它上面配置的 gateway 10.0.0.1 才能到達到 B。經過上面例子中的步驟,A 會得到 10.0.0.1 的 MAC 位址。
(2)當 A 收到 Router interface 1 的 MAC 位址後,A 發出了給B 的資料包:
(3)路由器的 interface1 收到該資料包後,根據其路由表,首先經過同樣的ARP 過程,路由器根據 B 的 IP 位址通過 ARP 獲得其 MAC 位址,然後将包發給它。
Neutron 基于 VLAN 模式的 tenant network 同 provider network 一樣,都必須使用實體的 VLAN 網絡。
本例子中,交換機上劃分了三個 VLAN 區域:
管理網絡,用于 OpenStack 節點之間的通信,假設 VLAN ID 範圍為 50 - 99.
資料網絡,用于虛拟機之間的通訊。由于Vlan模式下,租戶建立的網絡都具有獨立的 Vlan ID,故需要将連接配接虛機的伺服器的交換機端口設定為 Trunk 模式,并且設定所允許的 VLAN ID 範圍,比如 100~300。
外部網絡,用于連接配接外部網絡。加上 VLAN ID 範圍為 1000-1010。
(圖8)
關于網段之間的路由:
如果該實體交換機接到一個實體路由器并做相應的配置,則資料網絡可以使用這個實體路由器,而不需要使用 Neutron 的虛拟路由器。
如果不使用實體的路由器,可以在網絡節點上配置虛拟路由器。
網絡節點上:
計算節點上:
注意:
network_vlan_ranges 中的 VLAN ID 必須和實體交換機上的 VLAN ID 區間一緻。
bridge_mappings 中所指定的 bridge 需要和在個節點上手工建立的 OVS bridge 一緻。
然後重新開機相應的 Neutron 服務。
當 Neutron L2 Agent (OVS Agent 或者 Linux Bridge agent)在計算和網絡節點上啟動時,它會根據各種配置在節點上建立各種 bridge。以 OVS Agent 為例,
(1)建立 intergration brige(預設是 br-int);如果 enable_tunneling = true 的話,建立 tunnel bridge (預設是 br-tun)。
(2)根據 bridge_mappings,配置每一個 VLAN 和 Flat 網絡使用的 physical network interface 對應的預先建立的 OVS bridge。
(3)所有虛機的 VIF 都是連接配接到 integration bridge。同一個虛拟網絡上的 VM VIF 共享一個本地 VLAN (local VLAN)。Local VLAN ID 被映射到虛拟網絡對應的實體網絡的 segmentation_id。
(4)對于 GRE 類型的虛拟網絡,使用 LSI (Logical Switch identifier)來區分隧道(tunnel)内的租戶網絡流量(tenant traffic)。這個隧道的兩端都是每個實體伺服器上的 tunneling bridge。使用 Patch port 來将 br-int 和 br-tun 連接配接起來。
(5)對于每一個 VLAN 或者 Flat 類型的網絡,使用一個 veth 或者一個 patch port 對來連接配接 br-int 和實體網橋,以及增加 flow rules等。
(6)最後,Neutron L2 Agent 啟動後會運作一個RPC循環任務來處理 端口添加、删除和修改。管理者可以通過配置項 polling_interval 指定該 RPC 循環任務的執行間隔,預設為2秒。
做完以上的步驟之後,使用者就可以在 subnet 上 boot 虛機了。
boot 虛機的過程中,Nova 依次會:
(1)調用 Neutron REST API 申請一個或者多個 port。Neutron 會根據資料庫中的配置來進行配置設定。
(2)在計算節點上,Nova 調用 ovs-vsctl 指令将虛機的 VIF 被 plug 到 br-int 上。
(3)啟動虛機。
Neutron L2 Agent 的循環任務每隔兩秒會依次:
(1)調用 ”ovs-vsctl list-ports“ 指令擷取到 br-int 上的 port,再根據上次儲存的曆史資料,生成所有變更端口的清單(包括添加的、更新的、删除的端口)。比如:
{'current': set([u'04646b21-78a0-429e-85be-3167042b77be', u'592740b0-0768-4e57-870d-6495e6c22135']), 'removed': set([]), 'added': set([u'04646b21-78a0-429e-85be-3167042b77be', u'592740b0-0768-4e57-870d-6495e6c22135'])}
(2)為每一個待處理端口,根據其 ID 從 DB 中取得其詳細資訊。比如:
{u'profile': {}, u'admin_state_up': True, u'network_id': u'e2022937-ec2a-467a-8cf1-f642a3f777b6', u'segmentation_id': 4, u'device_owner': u'compute:nova', u'physical_network': phynet1, u'mac_address': u'fa:16:3e:fd:ed:22', u'device': u'592740b0-0768-4e57-870d-6495e6c22135', u'port_id': u'592740b0-0768-4e57-870d-6495e6c22135', u'fixed_ips': [{u'subnet_id': u'13888749-12b3-462e-9afe-c527bd0a297e', u'ip_address': u'91.1.180.4'}], u'network_type': u'vlan'}
(3)針對每一個增加或者變更的 port,設定 local VLAN Tag;調用 ”ovs-ofctl mod-flows “ 指令來設定 br-tun 或者 實體 bridge 的 flow rules;并設定 db 中其狀态為 up。
(4)針對每一個被删除的 port,設定 db 中其狀态為 down。
(1)一個計算節點上的網絡執行個體
它反映的網絡配置如下:
Neutron 使用 Open vSiwtch。
一台實體伺服器,網卡 eth1 接入實體交換機,預先配置了網橋 br-eth1。
建立了兩個 neutron VLAN network,分别使用 VLAN ID 101 和 102。
該伺服器上運作三個虛機,虛機1 和 2 分别有一個網卡接入 network 1;虛機2 和 3 分别有一個網卡接入 network 2.
(圖9)
Neutron 在該計算節點上做的事情:
建立了 OVS Integration bridge br-int。它的四個 Access 端口中,兩個打上了内部 Tag 1,連接配接接入 network 1 的兩個網卡;另兩個端口的 VLAN Tag 為 2。
建立了一對 patch port,連接配接 br-int 和 br-eth1。
設定 br-int 中的 flow rules。對從 access ports 進入的資料幀,加上相應的 VLAN Tag,轉發到 patch port;從 patch port 進入的資料幀,将 VLAN ID 101 修改為 1, 102 修改為 2,再轉發到相應的 Access ports。
設定 br-eth1 中的 flow rules。從 patch port 進入的資料幀,将内部 VLAN ID 1 修改為 101,内部 VLAN ID 2 修改為 102,再從 eth1 端口發出。對從 eth1 進入的資料幀做相反的處理。
(2)再加上另一個連接配接到同一個實體交換機的伺服器(加上 neutron 網絡使用的 VLAN ID 為 100,實體 brige 為 br-eth0):
(圖10)
Neutron 實作了基于實體 VLAN 交換機的跨實體伺服器二層虛拟網絡。
(3)連接配接到同一實體交換機的網絡節點的情況
(圖11)
(4)網絡流向
不同實體伺服器上的虛機,如果 VM1 和 VM2 屬于同一個 tenant network 的同一個subnet,那麼兩者的通信直接經過 實體交換機 進行,不需要做到網絡節點。如圖10 所示。
相同實體伺服器上的虛機,如果 VM1 和 VM2 屬于同一個 tenant network 的同一個subnet,那麼兩者的通信直接經過 br-int 進行。
對其他虛機之間資料交換情形,都算作跨子網的資料流向,都需要經過網絡節點中的 Router 進行 IP 包的路由。(也可以直接使用連接配接實體交換機的實體路由器)。
更詳細的網絡流向分析可以參考我另外的幾篇文章:
<a href="http://www.cnblogs.com/sammyliu/p/4204190.html">探索 OpenStack 之(8):Neutron 深入探索之 OVS + GRE 之 完整網絡流程 篇</a>
<a href="http://www.cnblogs.com/sammyliu/p/4201721.html">探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron節點篇</a>
<a href="http://www.cnblogs.com/sammyliu/p/4201143.html">學習OpenStack之(6):Neutron 深入學習之 OVS + GRE 之 Compute node 篇</a>
本文轉自SammyLiu部落格園部落格,原文連結:http://www.cnblogs.com/sammyliu/p/4626419.html,如需轉載請自行聯系原作者