OpenStack入門以及一些資料之(二、neutron網路)
L1
L1 是物理層,主要是涉及硬體的一些電氣特性,與偏軟體的 Neutron 虛擬網路從知識脈絡上關係甚少,不展開。
L2
FLAT
L2 資料鏈路層通過交換機裝置進行幀轉發。交換機在接收到幀之後(L2 層叫幀,L3 層叫包)先解析出幀頭中的 MAC 地址,再在轉發表中查詢是否有對應 MAC 地址的埠,有的話就從相應埠轉發出去。沒有,就洪泛(專業術語,即將幀轉發到交換機的所有埠),每個埠上的計算機都檢查幀頭中的 MAC 地址是否與本機網絡卡的 MAC 地址一致,一致的話就接收資料幀,不一致就直接丟棄。而轉發表是通過自學習自動建立的。
這裡引出一個重要概念,混雜模式。預設情況下計算機只接收和本機 MAC 地址一致的資料幀,不一致就丟棄,如果要求計算機接受所有幀的話,就要設定網絡卡為混雜模式(ifconfig eth0 0.0.0.0 promisc up)。所以在虛擬網橋中,如果希望虛機和外部通訊,必須開啟橋接到虛擬網橋中物理網絡卡的混雜模式特性。
VLAN
FLAT 中的洪泛,經常會在一個區域網內產生大量的廣播,這也就是所謂的“廣播風暴”。為了隔離廣播風暴,引入了 VLAN 的概念。即為交換機的每一個埠設定一個 1-4094 的數字,交換機根據 MAC 地址進行轉發的同時也要結合 VLAN 號這個數字,不同的話也要丟棄。這樣就實現了 L2 層資料幀的物理隔離,避免了廣播風暴。
在 Neutron 中,我們知道,截止到筆者寫這篇文章之時已經實現了 FLAT、VLAN、GRE、VXLAN 四種網路拓撲。那麼如何區分 FLAT 和 VLAN 呢?很簡單,結合 VLAN 號和 MAC 地址進行轉發的是 VLAN 模式,只根據 MAC 地址進行轉發的是 FLAT 模式。
VLAN 的缺點與大 L2 層技術
實際上,遂道技術並不能完全歸類於 L2 層。因為有基於 L2 層的遂道協議,例如 PPTP 和 L2TP 等;也有基於 L3 層的遂道,如 GRE、VXLAN、NVGRE 等;但是這些遂道從技術原理上講差不多,所以筆者將這些技術作為“大 L2 層”放在一塊來描述,但希望讀者不要誤解。
本文只將著重講 Neutron 中用到的 GRE 和 VXLAN 技術。
L3 層的 GRE 遂道
VLAN 技術能有效隔離廣播域,但同時有很多缺點:
- 要求穿越的所有物理交換機都配置允許帶有某個 VLAN 號的資料幀通過,因為物理交換機通常只提供 CLI 命令,不提供遠端介面可程式設計呼叫,所以都需要手工配置它,容易出錯且工作量巨大,純粹的體力勞動,影響了大規模部署。
- VLAN 號只能是 1-4094 中的一個數字,對於小規模的私有云可能不是個問題,但對於租戶眾多的公有云,可選擇的 VLAN 號的範圍是不是少了點呢?
為了克服上面的缺點,Neutron 開發了對 GRE 模式的支援。GRE 是 L3 層的遂道技術,本質是在遂道的兩端的 L4 層建立 UDP 連線傳輸重新包裝的 L3 層包頭,在目的地再取出包裝後的包頭進行解析。因為直接在遂道兩端建立 UDP 連線,所以不需要在遂道兩端路徑的物理交換機上配置 TRUNK 的操作。
說說 GRE 的缺點吧:
- GRE 將 L2 層的操作上移到 L3 層來做,效能肯定是會下降的。同時,由於遂道只能是點對點的,所以可以想象,如果有 N 個節點,就會有 N*(N-1)條 GRE 遂道,對於寶貴的 L4 層的埠資源也是一個浪費哦。那也是為什麼 GRE 遂道使用 UDP 而不使用 TCP 的原因了,因為 UDP 用完後就可以釋放,不用老佔著埠又不用。
- 在 Neutron 的 GRE 實現中,即使兩臺物理機上的兩臺虛機也不是直接建立 GRE 遂道的。而是通過 L3-agent 網路節點進行中轉,這樣做是基於方便使用 iptables 隔離網路流量的考慮。
利用 L3 層擴充套件 L2 層的遂道技術 VXLAN 與 SDN 的本質
VXLAN 是 VMware 的技術,可以克服 VLAN 號不足的問題;同時也可以克服 GRE 實質上作為點對點遂道擴充套件性太差的問題。
如果說 GRE 的本質是將 L3 層的資料包頭重新定義後再通過 L4 層的 UDP 進行傳輸,那麼 VXLAN 的本質就是對 L2 層的資料幀頭重新定義再通過 L4 層的 UDP 進行傳輸。也就是筆者說的所謂的利用 L3 層擴充套件 L2 層.
既然 L2 層的資料幀頭要重新定義,那就隨便定義啦,是否滿足以下三點是筆者從技術角度將一件產是否視為 SDN 的關鍵因素:
- 可將 L7 層租戶 tenant 的概念做到 L2 層。在筆者的前一篇《漫步雲中網路》姊妹篇中已經介紹了 IaaS 雲的本質就是賣虛機,即將虛機租給多租戶使用後收費。所以位於 L7 應用層的 tenant 的概念是雲用來對計算、儲存、網路資源進行隔離的重要概念。那麼將 tenant 的概念從 L7 層下移到 L2 層中意義重大。
- 也可將類似 VLAN 的概念做到 L2 層,並且由於是軟體定義的(不像物理交換機那樣受硬體限制),那麼很容易突破 VLAN 號在 1-4094 之間的限制。
- 是否提供集中式的控制器對外提供北向 API 供第三方呼叫來動態改變網路拓撲。
清楚了 SDN 的本質,那麼 VXLAN 的本質又是什麼呢?
- VXLAN 是一種 L2 層幀頭的重新封裝的資料格式。
- VXLAN 仍然使用 GRE 遂道通過 UDP 傳輸重新封裝幀頭後的資料幀。
圖 1. VXLAN 幀頭格式
因為 VXLAN 通過重新定義 L2 層幀頭(相當於通過 MAC 地址進行 NAT 的方案)從而讓兩個跨 L3 層的甚至廣域網內的兩個子網從 L2 層上互通。所以 VXLAN 的優點很多,能讓遺留子網不改變 IP 地址的情況下無縫的遷移到雲上來;也可以讓虛機跨資料中心進行遷移(以前頂多只能在同一個 VLAN 裡遷移)。
當然,VXLAN 也不是沒有缺點的,通過上面的學習,大家已經知道 VXLAN 也是通過 GRE 走 UDP 來傳輸重定義的標準化的 VXLAN 封裝格式的幀頭的。由於在遂道的兩端之間直接建立遂道,那麼它是無法與途經的一些物理裝置(如 DHCP 伺服器)通訊的,那麼就需要 VXLAN 閘道器這種物理裝置在遂道的中途截獲 VXLAN 資料包(閘道器閘道器嘛,就是進行資料截獲再轉換的),解析裡面的資料,然後做一些事情(像流量統計,DHCP 資訊等等),最後再將資料重新打成 VXLAN 資料包交給遂道繼續傳輸。可以想象,在所有需要與物理裝置打交道的地方都是需要 VXLAN 閘道器的。覺得麻煩了嗎?
利用 L2 層擴充套件 L3 層的標籤技術 MPLS
VLAN 是一種標籤技術,VLAN 一般用在區域網的交換機上,標籤很容易在 L2 層通過硬體來實現轉發。
MPLS 也是一種標籤技術,原理類似於 VLAN,但一般用在 WAN 上的路由器上,下面我們說道說道。
對於 L3 層的傳統路由轉發來說一般是在路由表裡查詢相應的路由來實現。因為路由嘛,不同的 CIDR 之間可長可短,如 10.0.0.0/8 與 10.0.100.0/24 這兩個子網首先長度不一樣,其次 CIDR 號一個是 8,一個是 24,在路由器中,是通過字串的按最長匹配演算法來匹配路由的,那麼應該選擇 10.0.100.0/24 這個路由。字串的按最長匹配演算法很難通過硬體來實現,通過軟體速度慢啊。那麼廣域網的路由器能不能也引入標籤通過硬體轉發的優點,在路由器作轉發時,不再在 L3 層的通過軟體去查詢路由來實現轉發,而是直接在 L2 層就通過標籤通過硬體轉發了呢?答案就是 MPLS。
例如 A 路由器通過 B 路由器給 C 路由器發包時,傳統的路由器是根據目的地址進行轉發,A 在開始轉發時,並不知道去 C 的完整路由,它只知道轉給 B,B 再決定轉給 C,這種走一步看一步的叫基於目的地址的路由轉發。但是 MPLS 的原理完全不同,A 在給 C 發包時,先發個 HELLO 包從 A 到 C 走一遍,在走的過程中就已經知道了 A 到 C 的路由路徑並且根據 LDP(標籤分發協議)將 A 到 C 的標籤序列就事先確定好了。那樣 A 再給 C 發資料時,A 就提前知道了在 L2 層怎麼根據標籤來轉發,所以它不用再到 L3 層查詢路由資訊了,另外它在 L2 層通過標籤轉發可以很容易通過硬體來實現,這樣速度更快了,最後標籤的確定是通過 LDP 協議動態分配的這也避免了像 VLAN 的那種標籤需要手工去設定的麻煩。
SDN
在 VXLAN 一節中,筆者已經說過了筆者判斷一個產品是否是 SDN 產品的核心判斷因素,即是否將 tenant 租戶的概念做到了 L2 層並且提供了北向 API 供第三方應用呼叫動態調整網路拓撲。做到了,就是 SDN 產品。目前,SDN 產品主要有三類:
- 基於 Overlay 技術的,如 VMware 的 VxLAN,如 Microsoft 的 NVGRE,如 IBM 的 Dove
- 基於 OpenFlow 技術的
- 基於專有技術的,如 Cisco 的 onePK
基於 Overlay 技術的 VxLAN 已經在上面介紹過了,這裡著重介紹一下 OpenFlow 和 Dove。
OpenFlow
OpenFlow 是完全不同於傳統網路技術的新興網路技術。
傳統交換機能通過自主學習建立轉發表,然後根據轉發錶轉發。但對於 OpenFlow 交換機,它是很“笨”的,資料幀來了它並不知道往哪個埠轉發,不知道怎麼辦呢?不懂就問唄,找 OpenFlow 控制器問。控制器通過一定演算法告訴它往哪個埠轉發,然後 OpenFlow 交換機照著做就行了。下圖 2 顯示了 OpenFlow 的結構:
圖 2. OpenFlow 的結構
我並沒有將 OpenFlow 歸於 L2 層,因為從理論上講,它並不嚴格屬於 L2 層,因為它設計了 L2-L4 層的轉發項進行轉發。現在 OpenFlow 的 FIB(轉發資訊表,Forward Info Base)中至少有下列條目:
- L2 層的 MAC、VLAN 等
- L3 層的 source ip, dest ip
- L4 層的 source port, dest port
- 甚至有基於 WAN 的動態路由的轉發項,如 BGP、MPLS 等
OpenFlow 進行轉發的時候和傳統的網路技術不一樣,傳統的是儲存包轉發(資料到了 L2 層就解析出 MAC 地址進行轉發,到了 L3 層後就解析出 IP 地址進行轉發)。而 OpenFlow 則根據所謂的流進行轉發。它將上面的 MAC、VLAN, source ip, dest ip, source port, dest port 等視作平等的平面,直接通過某個高效的字串匹配演算法匹配到了後再做某些動作,如 accept 或者 drop 掉。
再聊聊筆者所理解的 OpenFlow 的缺點。理論上,如果 OpenFlow 通過 L3 層的 IP 進行轉發的話,那它就成了一個路由器了。但實際上,目前,OpenFlow 主要還是用在 L2 層當做一個交換機來使用的。如果真要在 L3 層和路由結合的話,那麼它將以怎麼樣的方式和現存的分散式的動態路由協議(如 RIP、OSPF、BGP、MPLS)協作呢? 並且傳統的 WAN 本來為了可靠就是以分散式來設計的,現在搞成 OpenFlow 式的集中式控制,監控什麼的是方便了,但一旦控制器掛了那麼整個網路也全掛了,並且 OpenFlow 控制器一旦被某方勢力所掌握,那麼整個 OpenFlow 網路也就全被掌握了,畢竟 WAN 是要考慮這些因素的。所以筆者不認為 OpenFlow 這種集中式控制的路由器能在 WAN 上將取代傳統分散式的路由協議,頂多在 LAN 的 L2 層會有一些作為吧。
Dove/OpenDaylight
上面已經說到 SDN 需要對外提供北向 API 供第三方呼叫。
對於控制器與交換機之間的南向 API 的通訊標準就是由 google, facebook 這些使用者主導定製的 OpenFlow 協議。
北向 API 沒有標準,南向 API 也五花八門,將 tenant 和 VLAN 的概念做到 SDN 裡也沒有標準(雖然有 VMware 主導了一個 VXLAN 的資料封裝格式),所以業界存在很多 SDN 的產品,Dove 便是由 IBM 實現的其中一種,OpenDaylight 的外掛結構可以同時和眾多的 SDN 控制器打交道,降低第三方應用同時和眾多 SDN 控制器打交道的複雜性。
L3
L3 層的路由分靜態路由和動態路由兩種:
- 在 Linux 中,通過開啟 ipv4 forward 特性可以讓資料包從一塊網絡卡路由到另外一塊網絡卡上。
- 動態路由,如內部閘道器協議 RIP,OSPF;如外部閘道器協議 BGP。能夠自動地學習建立路由表。
目前 Neutron 只支援靜態路由,要點如下:
- 對於不同 tenant 子網通過 namespace 功能進行隔離,在 Linux 中,一個名稱空間 namespace 您可以簡單理解成 linux 又啟動了一個新的 TCP/IP 棧的程序。多個 tenant 意味著多個 namespace,也意味著多個 TCP/IP 棧。
- 對於同一 tenant 中的不同子網的隔離通過 iptables 來做,也意味著,同一 tenant 中的相同子網的兩個虛機不用走 L3 層,直接走 L2 層能通,沒問題;但如果同一 tenant 中的不同子網的兩個虛機要通訊的話,必須得繞道 L3-agent 網路節點,這是影響效能的。
L4-L7
LBaaS
OpenStack 最初的目標是做 x86 平臺下的開源 IaaS 雲,但它目前也有了類似於 LBaaS (Load Balance as a Service)這樣本屬於 SaaS 的特性。
LbaaS 服務可以為一個 tenant 下的多臺虛機提供負載均衡服務,要點如下:
- 提供負載均衡的虛機之間組成一個服務組
- 虛機之間提供心跳檢查
- 外部通過 VIP 來訪問 LB 服務組提供的服務,動態地將 VIP 根據負載均衡策略繫結到具體提供服務虛機的 fixed ip 上
下圖 3 顯示了 LBaaS 應用的幾種情形:
圖 3. LBaaS 的應用場景
說明如下:
- 有兩個虛機 192.168.0.3 和 192.168.0.1 組成負載均衡池,它們之間做心跳
- 如果這個 LB 服務只用在內網,可以只為虛機提供一個內部的 vip,如 192.168.0.4
- 如果這個 LB 服務也需要從外部訪問,那麼這個 vip 可以做成 floating ip,如 10.1.1.10
所以實現上述 LB 服務的 neutron 命令如下:
清單 1. 實現例子 LB 服務的 neutron 命令
neurton lb-pool-create --lb-method ROUND_ROBIN --name mypool --protocol HTTP --subnet-id <subnet-id> neurton lb-member-create --address 192.168.0.3 --protocol-port 80 mypool neurton lb-member-create --address 192.168.0.1 --protocol-port 80 mypool neurton lb-healthmonitor-create --delay 3 --type HTTP --max-retries 3 --timeout 3 neurton lb-healthmonitor-associate <lb-healthomonitor-id> mypool neurton lb-vip-create --name myvip --protocol-port 80 --protocol HTTP --subnet-id <subnet-id> mypool neurton lb-vip-create --name myvip --protocol-port 80 --protocol HTTP --subnet-id <subnet-id> mypool neurton floatingip-create public neurton floatingip-associate <floating-ip-id> <lb-vip-port-id>
FwaaS
目前,Neutron 已經實現了一個 Security Group 服務,FWaaS 服務正在開發中。 FwaaS 和 Security Group 的原理差不多,只不過程式碼重構將以前 Security Group 的程式碼挪到了現有的 L4/L7 層框架來了;這樣,以前 Security Group 作為 nova-compute 的一個元件只能執行在計算節點上,單純拆出來做為一個獨立程序之後也可以部署在 l3-agent 的那個物理機上提供邊緣防火牆特性。下圖 4 顯示了 Security Group 服務的原理圖:
圖 4. Security Group 原理圖
Security Group 由一系列的 iptables rule 組成
- 這些 iptables rule 執行在計算節點上
- 可以控制從虛機出去的流量
- 可以控制進來虛機的流量
- 可以控制虛機之間的流量
實施 Security Group 的步驟如下,例如,四個虛機,可以從 80 埠訪問 web 虛機,從 web 虛機上可以訪問 database 虛機,ssh 跳轉虛機上可以同時訪問 database 和 web 虛機,可以通過埠 22 訪問 ssh 虛機。
清單2. 實施Security Group 的步驟
neutron security-group-create web neutron security-group-create database neutron security-group-create ssh neutron security-group-rule-create --direction ingress --protocol TCP \ --port-range-min 80 --port-range-max 80 web neutron security-group-rule-create --direction ingress --protocol TCP \ --port-range-min 3306 --port-range-max 3306 --remote-group-id web database neutron security-group-rule-create --direction ingress --protocol TCP \ --port-range-min 22 --port-range-max 22 --remote-group-id ssh database neutron security-group-rule-create --direction ingress --protocol TCP \ --port-range-min 22 --port-range-max 22 --remote-group-id ssh web neutron security-group-rule-create --direction ingress --protocol tcp \ --port-range-min 22 --port-range-max 22 ssh
VPNaaS
我們仍然從技術的本質角度出發來解釋什麼是 VPN。VPN 類似於 GRE,也是一種遂道。但是不同的是 VPN 也要求不同的使用者可以使用相同的子網,所以在每個建立 VPN 的兩個端點所對應的邊緣路由器上都會為每個使用者建立它自己的 VPN 路由例項 VRF,白話一點的話,VRF 就是 Linux 裡上面提到過的 namespace 的概念。
建立 GRE 遂道容易,但是 VPN 強調私密性,一個組織的 VPN 總不希望不經授權的訪問吧。所以一般使用 SSL 或者 IPSec 結合 GRE 來建立 VPN。也可以通過 MPLS 來建立 VPN。Neutron 中這三類 VPN 目前均在開發之中。從下面 MPLS VPN 的 blueprint 中的圖 5 可以看到將來要實現的樣子:
圖 5. MPLS VPN 實現原理圖
目前,l3-agent 沒有使用動態路由,使用的是 namespace + ipv4 forward + iptables 的靜態路由技術。l3-agent 現在充當著 CE 的角色(Custum Edge)。我們設想一下,筆者認為 BGPMpls Driver 將來至少要實現下列幾個方面的內容:
- 呼叫 PE API 在邊緣路由器 PE 上通過 namespace 特性定義並配置 tenant 之間隔離的自己的 VPN 路由例項 VRF
- tenant 定義的 VRF 路由並不需要在每個 WAN 核心路由上都存在,所以可以通過配置輸入和輸出策略實現,即使用 router-target import/export 命令匯入或匯出相應的 VRF 條目
- 配置 PE 到 CE 的鏈路
- 將 CE 的介面關聯到預先定義的 VRF