OpenStack Neutron Dynamic Routing
如果你還不了解BGP,建議先看這篇BGP漫談。
作為航空母艦的OpenStack怎麼能沒有BGP這個功能呢?這次來看看OpenStack里的BGP項目:neutron-dynamic-routing。
Neutron dynamic routing是由HPE工程師發起的項目,其實代碼最開始在neutron裡面,後來才獨立出去的。Neutron號稱只處理2-3層的業務,BGP作為7層的協議,獨立出去也符合Neutron的發展方向。
以上一篇BGP漫談裡面講的小明的雲4.0版本為案例來說明,小明有了自己的公網IP池,但這個也不是無限的,不可能給每個虛機都分配一個公網IP,這樣太奢侈了。現實的數據中心中,通常只能有部分虛機有公網IP,大部分虛機都還是私網IP。例如在一個3層應用架構裡面,之需要給web server分配公網IP,applicationserver和DB server用私網IP就可以了,也更安全。
那問題又來了:
1. 小明的雲中路由器如何區分公網IP和私網IP。具體來說,公網IP需要直接路由出去,而私網IP需要走NAT訪問外網。
2. 小明的BGP服務怎麼知道哪些IP可以廣播出去,而哪些就算廣播出去也沒用(私網IP地址)。
為了解決這個問題,我們需要看一下Neutron的address scope。Neutron address scope是我在Neutron Mitaka版本參與完成的功能,我之前和HPE的工程師Carl Baldwin在Austin峰會講過address scope。
因為Neutron address scope是基於Neutron subnetpool,所以先看看subnetpool。
Subnetpool
Subnetpool是一個邏輯的概念,在Subnetpool之前,Neutron中的subnet是由用戶自己申請CIDR,對於CIDR沒有一個統一的管理。這就導致,不同的租戶申請的CIDR可能是重疊的,一旦重疊,那麼租戶的網路就不可能通過L3連接在一起。另外在其他的應用場合裡面,也要求私網地址不能重疊,例如kuryr。所以kuryr也是基於Neutron subnetpool,這我在之前的文章裡面也提過。
Subnetpool就是為了解決這個問題而誕生的,subnetpool預先分配好CIDR池,用戶在創建subnet的時候,可以不用自己指定CIDR,而是指定subnetpool,然後subnetpool會給subnet 分配CIDR。通過subnetpool的統一分配,可以保證,一個subnetpool下的所有subnet,CIDR是唯一且不重疊的。對應的也就有,一個subnetpool下面的所有網路埠,IP也是唯一的。
相應的,在Neutron subnet中也新增了一個屬性,subnetpool_id,用來表示當前subnet屬於哪個subnetpool。Subnetpool與subnet是一對多的關係,並且一個Neutron network下的所有同一類subnet只可能屬於一個subnetpool。這裡說的同一類是指IPv4或者IPv6。
Address Scope
先看address scope跟subnetpool的關係。
Addressscope與subnetpool的對應關係也是一對多。這說明subnetpool只能屬於一個address scope,對應的在subnetpool中也新增了一個屬性:address_scope_id。相應的Neutron network也新增了兩個屬性,ipv4_address_scope和ipv6_address_scope。與subnetpool相似,一個address scope內的subnetpool不允許CIDR地址重疊。也就是說,如果兩個IP地址都來自一個address scope,那麼它們肯定不相同。
不同於subnetpool的是,address scope不僅是一個邏輯功能,還是一個附加在L3上的實際的網路功能。具體的功能有:
這是一個隔離的功能,也就說如果兩個網路不在一個address scope中,那麼就算用router將它們連接在一起,它們之間還是不能互通。為什麼要這麼做?當你的address scope1裡面的IP地址是公網IP,而address scope2的地址是私網IP,你肯定不想讓私網IP通過路由器就能轉發到公網IP。另一方面,你也不想讓你的私網地址能都直接被公網地址訪問。私網和公網之間應該是隔離的。
如果與routergateway在一個address scope內,那麼租戶網路地址在經過Neutron router時,不會做NAT,而是直接路由出去。相反,如果不在同一個address scope,那麼租戶網路還是通過NAT訪問外網。這是不是就解決了前面提出的第一個問題,在路由器上區分公網IP和私網IP。只需要給公網IP和私網IP指定相應的address scope,那麼Neutron router就能區分它們,並且分別執行相應的動作。
為了不影響使用和向前兼容,我們在實現的時候,對於所有未指定address scope的network和subnetpool,都認為屬於no scope。在no scope下,CIDR是可以重疊的,且在L3也沒有特殊功能(東西向都互通,南北向都走NAT)。也就是說不使用address scope,是感覺不到它的存在的。
Neutron dynamic routing
前面解決了一個問題,那再來看第二個問題,Neutron的BGP服務怎麼知道哪些地址是可以通過BGP廣播出去的?其實也很明顯了。只有跟外網在一個address scope的地址,且這些網路連接到了路由器,才會被廣播出去。
為什麼需要跟外網在一個address scope,因為address scope確保了IP地址不重疊,這些CIDR是可以安全的廣播出來,另一個方面不同的address scope之間做了隔離,這些CIDR廣播出來也不會造成安全問題。
為什麼需要連接到路由器的網路地址才會被廣播?因為只有連接到路由器的地址才有可能被訪問到啊。否則就是在一個二層網路裡面了。
上圖中,也就是與provider network在同一個address scope內的三個淺藍色的self-service network會被Neutron BGP廣播出去。而淺綠色的那個網路還是通過NAT,藉助router gateway訪問外網。
具體使用
有了前面的介紹,再來介紹Neutron dynamic routing的使用,就簡單多了。接下來都是基於neutron的官方文檔來描述。
先是創建address scope和subnetpool,把self-service network 和provider network都創建在address scope下。這裡不再說私網,公網了,而是說self-servicenetwork 和provider network。self-servicenetwork就是給雲上的虛擬機使用的網路,可以是私網地址,也可以是外網地址,provider network映射物理網路,在BGP的環境下,必須是外網地址。當self-service network創建在與provider network在同一個address scope下時,可以認為self-service里的也是外網地址。
然後將self-service network 和provider network都加到Neutron router上。self-service network作為router interface接入,provider network作為router gateway接入。
之後創建BGP speaker,這裡的BGPspeaker可以看成是前一篇BGP漫談裡面的BGP router。
$ neutron bgp-speaker-create --ip-version 4 --local-as LOCAL_AS bgpspeaker
這裡指定的local-as就是BGProuter所在的AS分配到的編號。
BGP router該廣播哪些本地路由,這個是需要指定的。Quagga可以通過靜態配置文件來指定需要廣播的路由,而對於OpenStack來說,是通過將BGP speaker與provider network關聯來指定需要廣播的路由。這之間是什麼關係?
一旦BGP speaker與providernetwork關聯了,Neutron會查找所有連接到providernetwork的router,進而查找連接到這些router上的,且與provider network在同一個address scope下的self-service network,這些self-service network就是需要被廣播的對象。這比靜態指定方便多了。可以通過以下命令查看當前BGP speaker具體會廣播哪些路由。
$ neutron bgp-speaker-advertiseroute-list bgpspeaker
再之後,創建一個BGP peer。這裡的BGP peer是對端BGP router的信息。指定peer-ip,以供BGP連接使用,而remote-as是對端的AS編號。創建完之後,將BGP peer與BGP speaker關聯。注意,一個BGP speaker可以關聯多個BGP peer。
$ neutron bgp-peer-create --peer-ip 192.0.2.1 --remote-as REMOTE_AS bgppeer
到此為止,BGP還只是Neutron的一個邏輯概念,不能工作。需要將BGP speaker指定到BGP agent。制定完成之後,由BGP agent管理實際的BGP進程。而此時,BGP speaker已經可以向對端發送路由信息了。具體的過程在上一篇也簡單說過。
總的來看,一個OpenStack網路的路由信息是以這樣的結構廣播出去的。
實際中,對DVR在廣播floatingip時會有些不同。不過整體思路沒有變。
Neutron dynamic routing目前只支持向外廣播路由信息,不支持接收外部路由信息並應用到本地或者再轉發出去。也就是說BGP功能支持的不是很完善。底層BGP協議的實現,目前也只有基於RYU一種實現。不過因為是個開源項目,任何人都可以去完善這些功能。
推薦閱讀:
※linkedin在中國會贏得大量用戶嗎?
※如何理解計算機網路性能指標之速率與帶寬的區別?
※在電腦前,不知道做什麼,卻又不想關掉它。這是為什麼?怎麼克服?
※SDN(軟體定義網路)初體驗----Mininet
※他給多個科學領域當爹,離世30年才拿第一個獎