下面對Openstack和Neutron的介紹,要從幾個關鍵詞入手。
1. 三代網(wǎng)絡
在網(wǎng)絡這一口,OpenStack經(jīng)歷了由nova-network到Quantum再到Neutron的演進過程。我們直觀地來看看三代網(wǎng)絡的對比分析:
1)Nova-network是隸屬于nova項目的網(wǎng)絡實現(xiàn),它利用了linux-bridge(早期,目前也支持OVS)作為交換機,具備Flat、Flat DHCP、VLAN三種組網(wǎng)模式。優(yōu)點是性能出色,工作穩(wěn)定,支持multi-host部署以實現(xiàn)HA;缺點是網(wǎng)絡模塊不獨立,功能不夠靈活,組網(wǎng)模式也比較受限。
2)Quantum作為獨立的網(wǎng)絡管理項目出現(xiàn)在F版本,除了linux-bridge外還支持OVS,以及以及其他商業(yè)公司的插件,組網(wǎng)模式上增加了對GRE和VxLAN兩個Overlay技術的支持。優(yōu)點是功能靈活,支持大二層組網(wǎng);缺點是集中式的網(wǎng)絡節(jié)點缺乏HA,而且各廠商插件無法同時在底層網(wǎng)絡中運行。
3)Neutron出現(xiàn)在H版本,由來是Quantum和一家公司的名稱沖突而改名。Neutron對Quantum的插件機制進行了優(yōu)化,將各個廠商L2插件中獨立的數(shù)據(jù)庫實現(xiàn)提取出來,作為公共的ML2插件存儲租戶的業(yè)務需求,使得廠商可以專注于L2設備驅動的實現(xiàn),而ML2作為總控可以協(xié)調多廠商L2設備共同運行。Neutron繼承了Quantum對大二層的支持,還支持L2 PoP,DVR,VRRP,HA等關鍵功能,集成了很多L4-L7的網(wǎng)絡服務,一些blueprint也正在積極開發(fā)中,如SFC等。優(yōu)點是開始引入SDN思想,功能上更為豐富,網(wǎng)絡兼容性強;缺點是代碼結構復雜,工作不夠穩(wěn)定,HA機制仍缺乏大規(guī)模商用的檢驗。
從應用場景來看,Nova-network組網(wǎng)模式過于簡單,一些復雜的網(wǎng)絡需求無法實現(xiàn)(比如兩個公司合并,有大量IP重合的VM要遷移到一個平臺,而且要求遷移后都要用原來的IP)。不過由于其簡單穩(wěn)定的特點,仍適合于中小型企業(yè)的生產環(huán)境;Quantum的實際部署目前基本都跟進到了Neutron;Neutron的大二層組網(wǎng),適合于云計算規(guī)模的生產環(huán)境,但是由于分布式和HA機制仍不夠成熟,因此目前多見于私有云和小規(guī)模共有云的部署,大規(guī)模的公有云仍然難以使用Neutron實現(xiàn)。
2. 四種組網(wǎng)模型
說完了基本特征與應用場景,下面開始對上述提到的一些網(wǎng)絡問題進行詳細的描述。我們拋開技術,結合圖例來抽象地看看不同的組網(wǎng)模型。當然,以下模型的實現(xiàn)不僅僅局限于三張圖中的方式。
1)Flat模型最為簡單,所有的虛擬機共用一個私有IP網(wǎng)段,IP地址在虛擬機啟動時完成注入,虛擬機間的通信直接通過HyperVisor中的網(wǎng)橋轉發(fā),公網(wǎng)流量在該網(wǎng)段的網(wǎng)關上進行NAT(Nova-network實現(xiàn)為開啟nova-network主機內核的iptables,Neutron實現(xiàn)為網(wǎng)絡節(jié)點上的l3-agent)。Flat DHCP模型與Flat區(qū)別在于網(wǎng)橋中開啟了DHCP進程,虛擬機通過DHCP消息獲得IP地址(Nova-network實現(xiàn)為nova-network主機中的dnsmaq,Neutron實現(xiàn)為網(wǎng)絡節(jié)點上的dhcp-agent)。
2)VLAN模型引入了多租戶機制,虛擬機可以使用不同的私有IP網(wǎng)段,一個租戶可以擁有多個IP網(wǎng)段。虛擬機IP通過DHCP消息獲取IP地址(Nova-network實現(xiàn)為nova-network主機中的dnsmaq,Neutron實現(xiàn)為網(wǎng)絡節(jié)點上的dhcp-agent)。網(wǎng)段內部虛擬機間的通信直接通過HyperVisor中的網(wǎng)橋轉發(fā),同一租戶跨網(wǎng)段通信通過網(wǎng)關路由,不同租戶通過網(wǎng)關上的ACL進行隔離,公網(wǎng)流量在該網(wǎng)段的網(wǎng)關上進行NAT(Nova-network實現(xiàn)為開啟nova-network主機內核的iptables,Neutron實現(xiàn)為網(wǎng)絡節(jié)點上的l3-agent)。如果不同租戶邏輯上共用一個網(wǎng)關,則無法實現(xiàn)租戶間IP地址的復用。
3)Overlay模型(主要包括GRE和VxlAN隧道技術),相比于VLAN模型有以下改進。1)租戶數(shù)量從4K增加到16million;2)租戶內部通信可以跨越任意IP網(wǎng)絡,支持虛擬機任意遷移;3)一般來說每個租戶邏輯上都有一個網(wǎng)關實例,IP地址可以在租戶間進行復用;4)能夠結合SDN技術對流量進行優(yōu)化。
3. 三類節(jié)點和三類網(wǎng)絡
看過抽象的組網(wǎng)模型,下面我們來介紹組網(wǎng)具體的實現(xiàn)技術。下面的介紹都是針對Neutron的,對nova-network和Quantum將不做討論。
1)3類節(jié)點——管理節(jié)點:實現(xiàn)鏡像、塊存儲、身份認證、前端等服務,運行nova-compute的調度模塊以及nova api-server;計算節(jié)點:實現(xiàn)nova-compute,以及neutron的各種agent(一般不包括l3-agent,DVR除外);網(wǎng)絡節(jié)點,:實現(xiàn)neutron各種agent。注意,由于OpenStack為分布式架構實現(xiàn),因此neutron-server既可以運行在控制節(jié)點,也可以運行在網(wǎng)絡節(jié)點。
2)3種網(wǎng)絡——OpenStack內部模塊之間的交互發(fā)生在管理網(wǎng)絡,虛擬機之間的通信發(fā)生在數(shù)據(jù)網(wǎng)絡,而External Network/API Network網(wǎng)絡是連接外網(wǎng)的,無論是用戶調用Openstack API,還是虛擬機與外網(wǎng)間的互通都需要經(jīng)過這個網(wǎng)絡。
目前OpenStack通常采用out-of-bound方式進行部署,管理網(wǎng)絡與另外兩個網(wǎng)絡是獨立的,管理節(jié)點上一般也不會承載Openstack的業(yè)務流量,下面的分析中網(wǎng)絡只涉及數(shù)據(jù)網(wǎng)絡與External Network/API Network網(wǎng)絡,節(jié)點只涉及計算節(jié)點和網(wǎng)絡節(jié)點。
4. 兩張圖例
有了以上知識作為基礎,就可以來分析Openstack中的網(wǎng)絡通信了。由于OpenStack中容器的通信機制目前尚不成熟,并且有專門的項目Kuryr去實現(xiàn)容器相關網(wǎng)絡技術,以下內容將不涉及OpenStack中的容器通信。
以下將通過兩張圖來分析Neutron中的VLAN組網(wǎng)模型,HyperVisor中的網(wǎng)絡設備以OpenvSwitch為例。這三張圖中每一個信息都是有用的,把這些信息完全弄懂了,Neutron的組網(wǎng)也就能基本掌握了,Overlay模型與VLAN模型的區(qū)別只在于將圖中的br-eth1替換成br-tun即可,具體隧道如何進行封裝,稍后我們再詳細介紹。
第一張圖是計算節(jié)點上的網(wǎng)絡實現(xiàn)。以虛擬機發(fā)出流量方向為例,從虛擬機處開始分析:
1)流量經(jīng)由虛擬機IP內核交給虛擬網(wǎng)卡處理,虛擬網(wǎng)卡由TAP軟件實現(xiàn),TAP允許用戶態(tài)程序向內核協(xié)議棧注入數(shù)據(jù),它可以運行于虛擬機操作系統(tǒng)之上,能夠提供與硬件以太網(wǎng)卡完全相同的功能。
2)TAP設備并不是直接連接到OVS上的,而是通過linux bridge中繼到ovs br-int上,其原因在于ovs無法實現(xiàn)linux bridge中一些帶狀態(tài)的iptables規(guī)則,而這些規(guī)則往往用于以虛擬機為單位的安全組(security group)功能的實現(xiàn)。qbr是quantum bridge的縮寫,Neutron中沿用了Quantum的叫法。
3)linux bridge與ovs br int間的連接通過veth-pair技術實現(xiàn),qvb代表quantum veth bridge,qvo代表quantum veth ovs。veth-pair用于連接兩個虛擬網(wǎng)絡設備,總是成對出現(xiàn)以模擬虛擬設備間的數(shù)據(jù)收發(fā),其原理是反轉通訊數(shù)據(jù)的方向,需要發(fā)送的數(shù)據(jù)會被轉換成需要收到的數(shù)據(jù)重新送入內核網(wǎng)絡層進行處理。veth-pair與tap的區(qū)別可以簡單理解為veth-pair是軟件模擬的網(wǎng)線,而tap是軟件模擬的網(wǎng)卡。
4)ovs br-int是計算節(jié)點本地的虛擬交換設備,根據(jù)neutron-server中OVS Plugin的指導,完成流量在本地的處理:本地虛擬機送入的流量被標記本地VLAN tag,送到本地虛擬機的流量被去掉本地VLAN tag,本地虛擬機間的2層流量直接在本地轉發(fā),本地虛擬機到遠端虛擬機、網(wǎng)關的流量由int-br-eth1送到ovs br-eth1上(在Overlay模型中送到ovs br-tun上)。注意,無論是VLAN模型還是Overlay模型,由于br-int上VLAN數(shù)量的限制,計算節(jié)點本地最多支持4K的租戶。
5)ovs br-int與ovs br-eth1間的連接通過veth-pair技術實現(xiàn)。
6)ovs br-eth1將該計算節(jié)點與其他計算節(jié)點、網(wǎng)絡節(jié)點連接起來,根據(jù)neutron-server中OVS Plugin的指導,完成流量送出、送入本地前的處理:根據(jù)底層物理網(wǎng)絡租戶VLAN與本地租戶VLAN間的映射關系進行VLAN ID的轉換(Overlay模型中此處進行隧道封裝,并進行VNI與本地租戶VLAN ID間的映射)。由于底層物理網(wǎng)絡中VLAN數(shù)量的限制,VLAN模型最多支持4K的租戶,而Overlay模型中,24位的VNI最多支持16million的租戶。
7)ovs br-eth1直接關聯(lián)物理宿主機的硬件網(wǎng)卡eth1,通過eth1將數(shù)據(jù)包送到物理網(wǎng)絡中。Overlay模型中ovs br-tun通過TUN設備對數(shù)據(jù)包進行外層隧道封裝并送到HyperVisor內核中,內核根據(jù)外層IP地址進行選路,從硬件網(wǎng)卡eth1將數(shù)據(jù)包送到物理網(wǎng)絡中。TUN與TAP的實現(xiàn)機制類似,區(qū)別在于TAP工作在二層,而TUN工作在三層。
第二張圖是網(wǎng)絡節(jié)點上的網(wǎng)絡實現(xiàn),以流量流入網(wǎng)絡節(jié)點方向為例,從底層物理網(wǎng)絡流量通過eth1進入ovs br-eth1(Overlay模型中為ovs br-tun)開始分析:
1)ovs br-eth1將網(wǎng)絡節(jié)點與計算節(jié)點連接起來,根據(jù)neutron-server中OVS Plugin的指導,完成流量送入網(wǎng)絡節(jié)點前的處理:根據(jù)底層物理網(wǎng)絡租戶VLAN與本地租戶VLAN間的映射關系進行VLAN ID的轉換(Overlay模型中此處進行解封裝,并進行VNI與本地租戶VLAN ID間的映射)。注意,雖然同一租戶在底層物理網(wǎng)絡上的VLAN ID(Overlay模型中為VNI)唯一,但是在網(wǎng)絡節(jié)點與計算節(jié)點,不同計算節(jié)點中同一租戶對應的本地VLAN ID可能有所不同。另外由于網(wǎng)絡節(jié)點也要在ovs br-int上使用本地VLAN,而租戶跨網(wǎng)段流量與公網(wǎng)流量都要經(jīng)過網(wǎng)絡節(jié)點,因此使用單個網(wǎng)絡節(jié)點時,Neutron最多能支持4K租戶,可采用部署多個網(wǎng)絡節(jié)點的方式來解決這一問題。
2)送入網(wǎng)絡節(jié)點的流量,由ovs br-eth1(ovs br-tun)通過veth-pair送給ovs br-int,ovs br-int連接了本地不同的namespace,包括實現(xiàn)dhcp功能的dhcp-agent——dnsmasq,以及實現(xiàn)路由功能的l3-agent——router。Dnsmasq負責給對應租戶的虛擬機分配IP地址,而router負責處理租戶內跨網(wǎng)段流量以及公網(wǎng)流量。不同的租戶有不同的dnsmasq和router實例,因此不同租戶間可以實現(xiàn)IP地址的復用。
3)Router namesapce通過qr接口(Quantum Router)接收到租戶內跨網(wǎng)段流量以及公網(wǎng)流量,在ns的IP內核中對跨網(wǎng)段流量進行路由,改寫MAC地址并通過相應的qr接口向ovs br-int送出數(shù)據(jù)包。在ns的IP內核中對公網(wǎng)流量進行NAT,并通過qg接口(Quantum Gateway)發(fā)送給ovs br-ex。
4)Ovs br-ex通過關物理聯(lián)宿主機的硬件網(wǎng)卡eth1將流量送至Internet路由器。
5)上述兩幅圖中,ovs br-int與ovs br-ex間有直連,據(jù)說主要是防止l3-agent出現(xiàn)問題時能夠保證流量不中斷,但實際上看來很少出現(xiàn)此問題。
**5. Neutron網(wǎng)絡全家福
**
上圖是在網(wǎng)上看過的更加細致,更為全面的一張圖(http://blog.csdn.net/canxinghen/article/details/46761591#comments),圖中清晰地展示了Neutron對多種L2技術(VLAN、VxLAN、GRE)共同運行的支持。圖中的mellonax是intel等硬件廠商搞出的具備轉發(fā)功能的網(wǎng)卡,能夠避免虛擬交換機帶來的資源消耗,并能夠加快轉發(fā)速率。一塊這樣的網(wǎng)卡能虛擬出63個VF,每個VF就好像一個獨立的物理網(wǎng)卡一樣,通過將VF直接掛到虛擬機上,能夠實現(xiàn)轉發(fā)性能的大幅度提高。
以上介紹了OpenStack中網(wǎng)絡組件的演進,以及Neutron組網(wǎng)的基本原理。下面我們將對Neutron的軟件實現(xiàn)進行簡單的介紹。
二、Nova虛擬機啟動時的網(wǎng)絡處理
設備啟動了,網(wǎng)絡有了,可是現(xiàn)在還沒有虛擬機。下面我們來看看nova虛擬機啟動時的網(wǎng)絡處理過程。
從頭開始講。虛擬機的啟動通常來自于控制節(jié)點命令行的nova boot,該命令被組裝成REST API送到nova-api。Nova-api與neutron-server干的是一樣的活:接收REST請求,調nova-scheduler跑一些調度機制,計算出虛擬機部署的位置,然后通過rpc與相應計算節(jié)點上的agent——nova-compute進行通信,而啟動虛擬機的實際工作由nova-compute完成。
當然,以上過程與網(wǎng)絡并沒有發(fā)生什么關系,這里不做深入分析,大家要是有興趣可參考http://www.linuxqq.net/archives/1277.html。
假定nova-compute已經(jīng)通過rpc收到了開始干活的命令,我們就從這里開始漫長的代碼分析。在此之前,先來看一看OpenStack組件層面的調用流程。這里借用OpenStack大神SammyLiu的一張圖吧,圖中1-6步驟依次做了這么幾件事:
1)Nova-compute向neutron-server請求虛擬機對應的Port資源。
2)Neutron-server根據(jù)neutron-database生成Port資源。
3)Neutron-server通知Dhcp agent虛擬機信息。
4)Dhcp agent將虛擬機信息通知給dhcp server。
5)虛擬機接入并啟動。
6)虛擬機從dhcp server處獲得IP地址。
最后一步就是傳統(tǒng)的dhcp的交互過程,這里就不講了,下面來看1-5的實現(xiàn)。時間有限,代碼不再一步步回溯了,詳見SDNLAB“網(wǎng)絡虛擬化”專題的后續(xù)文章,這里給出代碼的主體思路。
1)Nova-compute向neutron-server發(fā)送create_port的REST API請求,生成新的Port資源。
2)Neutron-server收到該REST請求,通過APIRouter路由到ML2的create_port方法。該方法中,獲得了neutron-database新生成的Port,并通知ML2 Mechanism Driver該Port的生成。
3)Nova-compute向neutron發(fā)送update_port的REST API請求,
4)Neutron-server收到該REST請求,通過APIRouter路由到ML2的update_port方法。該方法中,在neutron-database更新該Port的狀態(tài),并根據(jù)ML2 Mechanism Driver的不同,決定后續(xù)的處理:若Mechanism Driver為hyperv/linuxbridge/ofagent/openvswitch,則需要通過ML2的update_port方法中執(zhí)行rpc遠程調用update_port;對于其余的Mechanism Driver,ML2的update_port方法調用其的update_port_postcommit方法進行處理,這些Mechanism Driver可能使用非rpc方式與自身的agent通信(如REST API、Netconf等)。
5)ML2執(zhí)行完update_port方法后,Port資源在wsgi中對應的Controller實例通過DhcpAgentNotifyAPI實例rpc通知給網(wǎng)絡節(jié)點上的dhcp agent(也可能通過一些調度機制通知給分布在計算節(jié)點上的dhcp agent)。
6)Dhcp agent收到該rpc通知,通過call_driver方法將虛擬機MAC與IP的綁定關系傳遞給本地的DHCP守護進程Dnsmaq。
7)Nova-compute通過libvirt driver的spawn方法將虛擬機接入網(wǎng)絡,然后啟動虛擬機。
到這里,虛擬機啟動過程中的網(wǎng)絡處理就都結束了,虛擬機間就可以開始通信了。下面開始介紹Neutron中OVS的流表邏輯,看看OVS是怎么支持虛擬機間的通信的。
三、Neutron的軟件實現(xiàn)
5. 5類Neutron組件
在架構設計上, Neutron沿用了OpenStack完全分布式的思想,各組件之間通過消息機制進行通信,使得Neutron中各個組件甚至各個進程都可以運行在任意的節(jié)點上,如下圖所示。這種微內核的架構使得開發(fā)者可以集中精力在網(wǎng)絡業(yè)務的實現(xiàn)上。目前Neutron提供了眾多的插件與驅動,基本上可以滿足各種部署的需要,如果這些還難以支撐實際所需的環(huán)境,則可以方便地在Neutron的框架下擴展插件或驅動。
1)Neutron-server可以理解為一個專門用來接收Neutron REST API調用的服務器,然后負責將不同的rest api分發(fā)到不同的neutron-plugin上。
2)Neutron-plugin可以理解為不同網(wǎng)絡功能實現(xiàn)的入口,各個廠商可以開發(fā)自己的plugin。Neutron-plugin接收neutron-server分發(fā)過來的REST API,向neutron database完成一些信息的注冊,然后將具體要執(zhí)行的業(yè)務操作和參數(shù)通知給自身對應的neutron agent。
3)Neutron-agent可以直觀地理解為neutron-plugin在設備上的代理,接收相應的neutron-plugin通知的業(yè)務操作和參數(shù),并轉換為具體的設備級操作,以指導設備的動作。當設備本地發(fā)生問題時,neutron-agent會將情況通知給neutron-plugin。
4)Neutron database,顧名思義就是Neutron的數(shù)據(jù)庫,一些業(yè)務相關的參數(shù)都存在這里。
5)Network provider,即為實際執(zhí)行功能的網(wǎng)絡設備,一般為虛擬交換機(OVS或者Linux Bridge)。
6 兩類Plugin
1)Core-plugin,Neutron中即為ML2(Modular Layer 2),負責管理L2的網(wǎng)絡連接。ML2中主要包括network、subnet、port三類核心資源,對三類資源進行操作的REST API被neutron-server看作Core API,由Neutron原生支持。其中:
2)Service-plugin,即為除core-plugin以外其它的plugin,包括l3 router、firewall、loadbalancer、VPN、metering等等,主要實現(xiàn)L3-L7的網(wǎng)絡服務。這些plugin要操作的資源比較豐富,對這些資源進行操作的REST API被neutron-server看作Extension API,需要廠家自行進行擴展。
最開始曾經(jīng)提到,“Neutron對Quantum的插件機制進行了優(yōu)化,將各個廠商L2插件中獨立的數(shù)據(jù)庫實現(xiàn)提取出來,作為公共的ML2插件存儲租戶的業(yè)務需求,使得廠商可以專注于L2設備驅動的實現(xiàn),而ML2作為總控可以協(xié)調多廠商L2設備共同運行”。在Quantum中,廠家都是開發(fā)各自的Service-plugin,不能兼容而且開發(fā)重復度很高,于是在Neutron中就為設計了ML2機制,使得各廠家的L2插件完全變成了可插拔的,方便了L2中network資源擴展與使用。
ML2作為L2的總控,其實現(xiàn)包括Type和Mechanism兩部分,每部分又分為Manager和Driver。Type指的是L2網(wǎng)絡的類型(如Flat、VLAN、VxLAN等),與廠家實現(xiàn)無關。Mechanism則是各個廠家自己設備機制的實現(xiàn),如下圖所示。當然有ML2,對應的就可以有ML3,不過在Neutron中L3的實現(xiàn)只負責路由的功能,傳統(tǒng)路由器中的其他功能(如Firewalls、LB、VPN)都被獨立出來實現(xiàn)了,因此暫時還沒有看到對ML3的實際需求。
===================== 代碼分析 =========================
一般而言,neutron-server和各neutron-plugin部署在控制節(jié)點或者網(wǎng)絡節(jié)點上,而neutron agent則部署在網(wǎng)絡節(jié)點上和計算節(jié)點上。我們先來簡單地分析控制端neutron-server和neutron-plugin的工作,然后再分析設備端neutron-agent的工作。
具體的代碼這次分享沒有時間講了,只能講個大致的輪廓和思路。有興趣深入研究的同志,可以關注SDNLAB上“網(wǎng)絡虛擬化”專題的后續(xù)更新。
(注意,以前廠商開發(fā)的L2 plugin跟ML2都存在于neutron/plugins目錄下,而可插拔的ML2設備驅動則存在于neutron/plugins/ml2/drivers目錄下)
**1. 控制端的實現(xiàn)
**
從neutron-server的啟動開始說起。neutron-server的啟動入口在neutron.server.__init__中,主函數(shù)中主要就干了兩件事,第一是下圖l 48處啟動wsgi服務器監(jiān)聽Neutron REST API,第二是在l 52啟動rpc服務,用于core plugin與agent間的通信,兩類服務作為綠色線程并發(fā)運行。從SDN的角度來看,wsgi負責Neutron的北向接口,而Neutron的南向通信機制主要依賴于rpc來實現(xiàn)(當然,不同廠家的plugin可能有其它的南向通信機制)。
1)北向方面,Neutron的wsgi通過Paste工具進行模板化部署,它接收Neutron REST API的業(yè)務請求,然后通過APIRouter將其分發(fā)給對應的plugin。
2)Neutron內部,plugin與數(shù)據(jù)庫交互,獲取業(yè)務的全局參數(shù),然后通過rpc機制將操作與參數(shù)傳給設備上的Agent(某些plugin和ML2 Mechanism Driver通過別的方式與Agent通信,比如REST API、NETCONF等)。
3)RPC機制就可以理解為Neutron的南向通信機制,Neutron的RPC實現(xiàn)基于AMPQ模型,plugins和agents之間通常采用“發(fā)布——訂閱”模式傳遞消息,agents收到相應plugins的NotifyApi后,會回調設備本地的CallBack來操作設備,完成業(yè)務的底層部署。
2. 設備端的實現(xiàn)
控制端neutron-server通過wsgi接收北向REST API請求,neutron-plugin通過rpc與設備端進行南向通信。設備端agent則向上通過rpc與控制端進行通信,向下則直接在本地對網(wǎng)絡設備進行配置。Neutron-agent的實現(xiàn)很多,彼此之間也沒什么共性的地方,下面選取比較具有代表性的ovs-neutron-agent的實現(xiàn)進行簡單的介紹。
Ovs-neutron-agent的啟動入口為/neutron/plugins/openvswitch/agent/ovs-neutron-agent.py中的main方法,其中負責干活的兩行代碼在l 1471和l 1476。L 1471實例化了OVSNeutronAgent類,負責在本地配置OVS,而l 1476則啟動了與控制端的rpc通信。
OVSNeutronAgent的實例化過程中依次干了6個工作:啟動ovs br-int網(wǎng)橋;啟動rpc;啟動ovs br-eth1;啟動ovs br-tun;實例化OVSSecurityGroupAgent;開始rpc輪詢與監(jiān)聽。
rpc_loop做的工作主要就是輪詢一些狀態(tài),根據(jù)這些狀態(tài),進行相應的操作。比如一旦探測到本地的OVS重啟了(l 1295,l 1309),就重新創(chuàng)建本地的網(wǎng)橋(l 1294-1300),并重新添加port(l 1336);再比如一旦rpc監(jiān)聽到update_port事件(l 1309),則在本地使能相應的port(l 1336)。
ovs-neutron-agent的啟動也就是這些工作了,啟動完畢后,便開始了與相應plugin(OVS Plugin或者OVS Mechanism Driver)的rpc通信。
================= 代碼分析 ====================
Neutron的軟件實現(xiàn)就簡單地介紹到這里了,下一節(jié)我們來具體看看Neutron中各個OVS上的流表邏輯是怎樣的。
**四、Neutron OVS上的流表分析
**
在具體介紹OVS的工作機制之前,大家要先理解OVS并不是Neutron網(wǎng)絡實現(xiàn)的唯一選擇。
實際上,Neutron中底層網(wǎng)絡的實現(xiàn)千差萬別:有的agent本地是真正處理數(shù)據(jù)流的網(wǎng)絡設備(OVS,Router,LoadBalancer等),而有的agent本地是SDN控制器(如ODL、ONOS、OpenContrail、NSX等)。上述Neutron底層網(wǎng)絡的兩種模型示意如下。
第一種模型中Neutron相當于SDN控制器,plugin與agent間的通信機制(如rpc)就相當于簡單的南向協(xié)議。第二種模型中Neutron作為SDN應用,將業(yè)務需求告知SDN控制器,SDN控制器再通過五花八門的南向協(xié)議遠程控制網(wǎng)絡設備。當然,第二種模型中也可以把Neutron看做超級控制器或者網(wǎng)絡編排器,去完成OpenStack中網(wǎng)絡業(yè)務的集中分發(fā)。
以下我們講的是第一種模型中OVS處理數(shù)據(jù)流的工作機制。后一種模型中,SDN控制器也可以通過OpenFlow或者OVSDB來控制OVS處理數(shù)據(jù)流,對此本節(jié)暫時不進行討論,后續(xù)也會有文章會詳細介紹ODL和ONOS等SDN控制器對Openstack的支持。
================== 分隔線 ======================
以Overlay組網(wǎng)模型對OVS的工作機制進行介紹,具體分為兩個角度:OVS實現(xiàn)L2的基本連接,OVS對連接機制的優(yōu)化。
**(一)L2基本連接的實現(xiàn)
**
復原一下通信場景,其中的網(wǎng)絡基礎請參考“OpenStack網(wǎng)絡基礎”一小節(jié)。圖中某租戶有兩個網(wǎng)段,分別用橙紅色和藍色表示,網(wǎng)段間的互通要經(jīng)過網(wǎng)絡節(jié)點中的Router,網(wǎng)段內的通信不需要經(jīng)過網(wǎng)絡節(jié)點中的Router。網(wǎng)段間的互通可分為3步:橙紅色網(wǎng)段通過網(wǎng)段內通信找到Router,Router進行路由,Router通過藍色網(wǎng)段的網(wǎng)段內通信轉發(fā)給目的地。Router上的路由是linux內核實現(xiàn)的,我們不去關心,因此可以說租戶內部通信都是基于網(wǎng)段內通信實現(xiàn)的。
Overlay模型中,網(wǎng)段內通信涉及ovs br-int和ovs br-tun,計算節(jié)點和網(wǎng)絡節(jié)點中兩類網(wǎng)橋的實現(xiàn)沒有什么區(qū)別。概括地說,br-int負責在節(jié)點本地的網(wǎng)段內通信,br-tun則負責節(jié)點間的網(wǎng)段內通信。
在本節(jié)的場景內br-int實現(xiàn)為普通的二層交換機,即完成VLAN標簽的增刪和正常的二層自學習與轉發(fā),沒有必要進行過多的解釋,其代碼實現(xiàn)請參考“Neutron的軟件實現(xiàn)”中agent部分。
Br-tun采用多級流表實現(xiàn)節(jié)點間的網(wǎng)段內通信,下面直接通過圖示來看br-tun中多級流表的設計。圖中流表的序號不是固定的,可在neutron.plugins.openvswitch.agent.common目錄下的constants.py文件中修改。
所有流經(jīng)br-tun的數(shù)據(jù)包首先進入Table 0進行處理。Table 0對數(shù)據(jù)包的來源進行判斷,從與br-int相連的patch-int進入的數(shù)據(jù)包交給Table 1處理,從GRE或者VxLAN端口(不同節(jié)點間的隧道有不同的Port_ID)進入的分別交給Table 2、Table 3處理。Table 1根據(jù)數(shù)據(jù)包目的MAC地址判斷是否為單播,是則送往Table 20,否則送往Table 21,Table 20根據(jù)(VLAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射關系將單播包送到特定的隧道,Table 21將非單播包復制后送到所有隧道。進入Table 2或者Table 3的數(shù)據(jù)包,首先判斷TUNNE_ID是否合法,是則添加本地VLAN_ID并送往Table 10,否則丟棄。Table 10記錄數(shù)據(jù)包的VLAN_ID,MAC、入端口以及TUNNEL_ID,將(VLAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射關系寫入Table 20,然后將數(shù)據(jù)包從與br-int相連的patch-int送出。
可見,上述過程就是標準MAC自學習在隧道中的擴展,無非就是將(VLAN_ID,MAC)到PORT_ID的映射變?yōu)榱耍╒LAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射。這種自學習仍然要依賴于泛洪來完成,引入l2_population或者SDN控制器后可以避免掉泛洪。
(二)連接機制的優(yōu)化
OVS上,連接機制的優(yōu)化主要體現(xiàn)在l2_population機制,以及對DVR(Distributed Virtual Router,分布式L3-agent)的支持。
2.1 L2_population
虛擬機在通信前,會發(fā)送ARP請求去解析目的MAC與目的IP間的映射關系,這一過程需要發(fā)送二層的廣播包。由(一)中的介紹可知,這會導致隧道上的泛洪,這顯然是不能令人滿意的。
傳統(tǒng)網(wǎng)絡中ARP依賴于廣播泛洪的原因在于沒有一個集中式的控制平面,而Neutron中的數(shù)據(jù)庫存有所有虛擬機MAC地址與IP地址間的映射,可以說是一個天然原生的控制平面。因此有人提出了將該映射關系注入到OVS本地,在本地處理ARP廣播,以避免隧道上的泛洪,這就是l2_population。
L2_population的實現(xiàn)并不復雜,就是在1介紹的流水線中增加一個ARP Table去處理ARP Request。ARP Table中會事先存好MAC與IP的映射關系,如果ARP Table中匹配ARP Request消息中的目的IP,則構造一個 ARP 響應包,從ARP Request的入端口返回給虛擬機。如果匹配失敗,則跳轉到 Table 21繼續(xù)泛洪。上述過程如下圖所示,之所以保留ARP Table到Table 21的跳轉,主要是為了防止l2_population出現(xiàn)問題。
L2_population的工作就是這么簡單,卻可以大大減少不合意的隧道泛洪。其實dhcp也存在類似的問題,如果只在網(wǎng)絡節(jié)點上放置dhcp-server,那么所有的DHCP DISCOVER消息都要靠隧道泛洪發(fā)送到網(wǎng)絡節(jié)點上。當然,dhcp消息的數(shù)量和產生頻率遠遠趕不上arp,問題也不會那么明顯。
解決dhcp存在的上述問題,一種思路是在Table 21上專門寫一條高優(yōu)先級的dhcp流表項去匹配dhcp廣播消息,并將所有的dhcp消息都封裝送到網(wǎng)絡節(jié)點的隧道。另外,也可以采用類似于l2_population的思路,從Table 1上專門寫一條高優(yōu)先級的dhcp流表項去匹配dhcp消息,這條流表項只需要將dhcp消息通過相應的端口轉交給dhcp namespace即可。之所以用namespace實現(xiàn),是因為Dhcp消息封裝在應用層,OpenFlow流表無法直接支持dhcp消息的封裝,因此這個活得由分布在計算節(jié)點上的dhcp namespace來完成。
第一種思路優(yōu)點是實現(xiàn)簡單,但是一旦網(wǎng)絡節(jié)點發(fā)生單點故障,虛擬機便無法正常使用dhcp獲取IP,不過kilo版本中已經(jīng)有人在多個網(wǎng)絡節(jié)點中實現(xiàn)了dhcp_loadbalance(https://blueprints.launchpad.net/neutron/+spec/dhcpservice-loadbalancing)。第二種思路實現(xiàn)復雜一些,但能夠避免網(wǎng)絡節(jié)點單點故障帶來的問題,實現(xiàn)分布式dhcp。
2.2 DVR
上一小節(jié)簡略地提到了分布式的dhcp,這個工作社區(qū)有人提過但是反響并不是很大,而分布式的路由(Distributed Virtual Routing)卻很早就成為了社區(qū)的共識,并在Juno版本中給出了實現(xiàn)。
Neutron中Router用來實現(xiàn)同一租戶不同網(wǎng)段的虛擬機間的通信,這屬于東西向流量,具體可以分為兩種:1. 同一個物理節(jié)點上不同網(wǎng)段內的虛機之間的通信;2. 不同物理節(jié)點上不同網(wǎng)段內的虛機之間的通信。Router還用來實現(xiàn)虛擬機與Internet間的流量,這屬于南北向流量,具體也可分為兩種:1. 虛擬機訪問Internet的流量,通常需要經(jīng)過SNAT處理;2. Internet訪問虛擬機的流量,可能需要經(jīng)過DNAT處理。
在Neutron較早的版本中,上述流量都需要通過經(jīng)過網(wǎng)絡節(jié)點上的Router來處理,一旦網(wǎng)絡節(jié)點故障或者網(wǎng)絡節(jié)點上的Router掛掉了,上述類型的流量也就都丟掉了。解決這一問題也有很多種思路:
1)一種是通過部署多個網(wǎng)絡節(jié)點,在多個網(wǎng)絡節(jié)點間做調度的,不過這種很難實現(xiàn)各個Router本身狀態(tài)的一致性。
2)于是,就有了通過在Router間跑應用層面的VRRP來同步Router狀態(tài),這種方式是很不錯的,VRRP協(xié)議也比較成熟。但是問題在于,大部分流量仍然需要“繞彎子”進行傳輸,如同一個物理節(jié)點上不同網(wǎng)段內的虛機之間的通信可能需要到另一個物理節(jié)點的Router上處理。
3)再于是,DVR就出現(xiàn)了,通過把Router分布在各個計算節(jié)點中,各類流量都可以得到最優(yōu)的處理,也不會再有單點故障的問題了。
接下來對DVR的講解發(fā)生在下圖的場景中:某租戶有紅、綠兩個網(wǎng)段,兩臺虛擬機vm1、vm2分屬兩個網(wǎng)段,分別位于計算節(jié)點CN1、CN2,租戶擁有一個DVR路由器r1,分布在兩個計算節(jié)點之上。假定vm1已經(jīng)通過ARP獲得了CN 1中r1在紅色網(wǎng)段接口的MAC地址r1 red mac,現(xiàn)在vm1發(fā)起向vm2的ping request。
拋開流表的格式與下發(fā)的過程,先按照圖中序號來看一看DVR流表下發(fā)后通信各個階段的數(shù)據(jù)包特征。這里規(guī)定(源MAC,目的MAC,源IP,目的IP地址)為數(shù)據(jù)包的特征4元組。
1)vm1發(fā)出的ping包特征為(vm1 mac, r1 red mac, vm1 ip, vm2 ip),該數(shù)據(jù)包送至br-int-cn1。
2)br-int-cn1在之前ARP過程中學到了r1 red mac所在端口,將ping包直接轉發(fā)給CN1中的r1。
3)r1進行路由,得知目的虛擬機連接在綠色網(wǎng)段上,而且r1中存有目的虛擬機的靜態(tài)ARP表項,不需要進行ARP解析。于是CN1中的r1通過其綠色網(wǎng)段接口將ping包重新送回br-int-cn1。此時ping包特征為(r1 grn mac, vm2 mac, vm1 ip, vm2 ip),br-int-cn1還不知道vm2連在哪里,進行泛洪。
4)br-tun-cn1由br-int-cn1收到ping包,將源mac地址修改為全局唯一的dvr cn1 mac,并封裝好隧道,標記綠色網(wǎng)段的TUNNEL_ID,直接送往CN2。此時ping包被封裝在外層包頭內,其特征為(dvr cn1 mac, vm2 mac, vm1 ip, vm2 ip)。
5)br-tun-cn2收到后去掉外層包頭,打上綠色網(wǎng)段的本地VLAN標簽,送給br-int-cn2,此時ping包特征仍為(dvr cn1 mac, vm2 mac, vm1 ip, vm2 ip)。
6)br-int-cn2識別出這是CN1經(jīng)過綠色網(wǎng)段送過來的流量,于是將源mac地址改回r1 grn mac并剝掉VLAN標簽。br-int-cn2還不知道vm2連在哪里,就將ping包泛洪。此時ping包特征為(r1 grn mac, vm2 mac, vm1 ip, vm2 ip)。
7)vm2收到ping request,回復ping echo,反向的通信過程和上述基本一致。
上述步驟給出了通信的外在特征,下面說明某些步驟內在的實現(xiàn)原理。
1)“r1中存有目的虛擬機的靜態(tài)ARP表項”,是因為各個部署了DVR的計算節(jié)點中,l3-agent都事先從neutron數(shù)據(jù)庫中獲取了虛擬機的網(wǎng)絡信息,直接注入到了r1中。這是為了防止r1跨隧道泛洪獲取vm2的MAC地址(可以通過l2_population來實現(xiàn))。
2)“將源mac地址修改為全局唯一的dvr cn1 mac”,是因為在所有計算節(jié)點上,r1位于相同網(wǎng)段的接口mac地址是一致的,即CN1上的r1 red/grn mac與CN2上的r1 red/grn mac一致。因此為了防止對端br-tun上的混亂, Neutron為每個部署了DVR的計算節(jié)點分配了全局唯一的dvr mac地址,br-tun在進行隧道傳輸前都需要進行源MAC地址的改寫。
“并封裝好隧道,標記綠色網(wǎng)段的TUNNEL_ID,直接送往CN2”,DVR要求開啟l2_population事先學習(VLAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射,以避免隧道上的泛洪。
3)br-tun-cn2解封裝后,判斷流量由dvr cn1送過來,不進行自學習,直接將流量送給br-int-cn2。
4)br-int-cn2中實現(xiàn)存有所有部署了DVR的計算節(jié)點的全局唯一的MAC地址,因而可以識別dvr cn1送過來的流量,完成源MAC地址的回寫后進行轉發(fā)。
流表的邏輯跳轉圖如下所示(注意,某些Table的ID發(fā)生了變化,且未表示l2_population)。
Table 0對數(shù)據(jù)包的來源進行判斷,從與br-int相連的patch-int進入的數(shù)據(jù)包交給Table 1處理,從VxLAN端口(以VxLAN為例)進入的交給Table 4處理。Table 1判斷數(shù)據(jù)包是否為發(fā)向r1的ARP,或者其他發(fā)給r1的二層幀,如果是則丟棄(為了保證虛擬機送到r1的數(shù)據(jù)包只在本地轉發(fā))。如果Table 1判斷數(shù)據(jù)包是由r1發(fā)出來的,則將源mac地址改為CN1的dvr mac地址(為了避免對端br-tun上的混亂),然后送往Table 2。Table 2根據(jù)數(shù)據(jù)包目的MAC地址判斷是否為單播,是則送往Table 20,否則送往Table 21。Table 20根據(jù)(VLAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射關系將單播包送到特定的隧道,該映射關系可事先通過L2_populaiton學習到,也可以通過Table 10的觸發(fā)學習到。Table 21將非單播包復制后送到所有隧道。進入Table4的數(shù)據(jù)包,首先判斷TUNNE_ID是否合法,是則添加本地VLAN_ID并送往Table 9,否則丟棄。Table 9判斷數(shù)據(jù)包源mac地址是否屬于dvr mac地址(由于示例場景比較簡單,圖中示例流表只匹配了CN2的dvr-cn2-mac),如果是直接送給br-int-cn1處理,否則轉給Table 10進行學習。Table 10記錄數(shù)據(jù)包的VLAN_ID,MAC以及TUNNEL_ID,將(VLAN_ID,MAC)到(PORT_ID,TUNNEL_ID)的映射關系寫入Table 20,然后從與br-int相連的patch-int送出。下面給出各個流表項的標注,其中紅色的為新增的DVR表項。
DVR對于南北向流量的處理有兩種模型,第一種是SNAT在節(jié)點本地完成,第二種是SNAT仍需要到網(wǎng)絡節(jié)點進行,兩種模型分別示意如下。在節(jié)點本地進行SNAT則需要在計算節(jié)點的qr上為虛擬機分配浮動IP地址,而在網(wǎng)絡節(jié)點完成SNAT比較節(jié)省公網(wǎng)IP資源,具體選擇哪種模型,要視用戶實際的業(yè)務需求而定。
講到這里,對Neutron OVS上的流表分析就結束了。
審核編輯:郭婷
評論
查看更多