相信不少兄弟的SDN啟蒙都是各種高大上的論文中五花八門的概念和應(yīng)用,等到真把開源控制器和mininet裝好,要開始干活了,才發(fā)現(xiàn)什么traffic engineering, 什么consistent update,根本不是那么回事兒。大家要處理的第一個包甚至都不是TCP,而是ARP,而且還是廣播!這里有兄弟可能會想到DHCP,LLDP,甚至?xí)氲絀Pv6的鄰居發(fā)現(xiàn),博主會在以后的文章中詳細(xì)討論它們,這次只講ARP。
SDN控制器管理的是由一些交換機(包括OVS和物理交換機)構(gòu)成的網(wǎng)絡(luò)而不是網(wǎng)絡(luò)邊緣的服務(wù)器(包括bare metal server和vm),但是SDN控制器在proactive的編輯各種表的時候又需要知道服務(wù)器在網(wǎng)絡(luò)當(dāng)中的位置。ARP幾乎成為最好的甚至是唯一的獲取這些信息的渠道(IPv6鄰居發(fā)現(xiàn)是另外一個話題),因為從ARP我們至少可以學(xué)到兩件事情:第一,每一個mac究竟出現(xiàn)在網(wǎng)絡(luò)中哪臺交換機的哪個端口。第二,每一個mac上究竟有哪些IP地址。
也許有兄弟會問:我們可以通過服務(wù)器發(fā)出的任何二層或者三層的報文來學(xué)到這兩件事情,為什么一定是ARP呢?答案有三:首先,既然ARP是每一臺服務(wù)器發(fā)出的幾乎第一個報文,我們?yōu)槭裁床恢苯訌倪@個報文中學(xué)到以上的信息呢?既然做proactive的SDN,那就應(yīng)該在第一時間學(xué)習(xí)網(wǎng)絡(luò)中服務(wù)器的位置。其次,如果我們的SDN網(wǎng)絡(luò)連ARP都沒有處理好,服務(wù)器都沒法收到ARP reply,那么也就沒有后面的其他報文了。第三,也是最重要的原因:我們其實并不知道網(wǎng)絡(luò)邊緣的服務(wù)器是什么設(shè)備,它可能是一個一般意義上的服務(wù)器,也可能是一個防火墻,或者是一個第三方的路由器。如果我們在SDN網(wǎng)絡(luò)邊緣看到了一個三層的報文,并且簡單的認(rèn)為這個報文的src mac和src IP來自同樣一臺服務(wù)器,那么就錯大了。
我們不妨拿傳統(tǒng)的交換機和SDN控制器管理的網(wǎng)絡(luò)做個類比。在傳統(tǒng)的交換機上,mac learning是一個非常簡單的過程:我在port1上看到了mac1,那么交換機就有了一個二層的表項:到mac1走port1。在SDN的世界里,并沒有什么本質(zhì)的不同:我們在switch1 port1上看到了mac1,那么到mac1就走switch1 port1。唯一的不同是:傳統(tǒng)交換機的學(xué)習(xí)就發(fā)生在交換機上。而在SDN的世界里,學(xué)習(xí)發(fā)生在SDN控制器里(有人稱之為centralized mac learning),因為控制器一定要知道它管理的這個網(wǎng)絡(luò)究竟連接了一些什么mac/IP,才能proactive的編輯整個SDN網(wǎng)絡(luò)的流表。一種比較常見的方式是:交換機把ARP request/reply以packet-in的形式發(fā)給控制器,控制器便學(xué)習(xí)到了mac, vlan, IP, 交換機和端口之間的關(guān)系。在開源的floodlight里有一個類似的例子,在所有其他開源的控制器里,也都有類似的例子。
講到這里,做OpenStack/CloudStack的兄弟們會仰天大笑:太老土了吧,還centralized mac learning?有了orchestration之后,網(wǎng)絡(luò)中所有vm的一切信息在第一時間已經(jīng)被控制器知道了!此言不假,但有兩個問題:第一,如果有人沒有部署orchestration而只用物理服務(wù)器怎么辦?其實,對于SDN網(wǎng)絡(luò)而言,orchestration也是某種意義上的mac learning,只不過這個learnning沒有通過ARP。
第二個問題則更加重要,無論SDN控制器用何種方式學(xué)到mac/IP在網(wǎng)絡(luò)中的位置,這僅僅是第一步,接下來的問題是:怎樣回復(fù)服務(wù)器發(fā)出的ARP request? 這個問題是SDN系統(tǒng)設(shè)計的一個挑戰(zhàn),并且這個挑戰(zhàn)會隨著系統(tǒng)feature的不斷豐富,一次又一次的出現(xiàn)。接下來博主主要會從L2和L3兩個方面分析一下這個問題可能的解法,歡迎大家查漏補缺。
如果source和destination處于一個subnet,這是一個純二層的問題。有兩種極端的解法。
極端解法一:讓SDN控制器回復(fù)所有的ARP request。既然SDN控制器已經(jīng)通過orchestration或者ARP packet-in的方式學(xué)習(xí)到了網(wǎng)絡(luò)中的mac,那么只要將所有ARP request都以packet-in的形式發(fā)送到控制器,控制器就完全有能力將ARP reply通過packet-out的方式回復(fù)給source。
這種極端做法顯而易見的缺點是:過多的ARP request會讓SDN控制器應(yīng)接不暇,成為潛在的安全隱患。于是,不少SDN廠家在這種方案的基礎(chǔ)上進(jìn)行了改進(jìn),一種改進(jìn)的思路是:既然控制器上有一個大表記錄著網(wǎng)絡(luò)中所有IP到mac的映射,那么我們就可以在所有網(wǎng)絡(luò)邊緣交換機上把這個表cache下來,這樣,當(dāng)交換機再次收到ARP request的時候,就可以通過查找這個表直接回復(fù)相應(yīng)的ARP reply,而不需要廣播。
以上這個改進(jìn)確實是個可行的方案,但是有兩個前提:1)用戶不在乎高可靠性(high availability),2)一定要部署在有orchestration的環(huán)境當(dāng)中。但這兩個大大的前提往往會讓相當(dāng)一部分客戶止步。首先如果source和destination都好好的,但是SDN控制器宕了,于是最基本的ARP便無法正常工作,這是一件讓任何客戶都很難接受的事情。其次,在沒有orchestration的環(huán)境當(dāng)中,有些服務(wù)器是不主動說話的(silent server),也就是說在silent server發(fā)出第一個ARP之前,控制器根本沒有機會得知它的存在。在這種情況下,SDN網(wǎng)絡(luò)必須要能夠正確的廣播ARP request,當(dāng)SDN網(wǎng)絡(luò)收到silent server的ARP reply之后,還要能夠正確的將其轉(zhuǎn)發(fā)。
極端解法二:在一個廣播域中廣播ARP request。既然極端解法一并不適用于所有的情形,那么我們便很自然的想到了另外一個極端解法,索性廣播ARP request吧,該誰回復(fù)ARP reply就讓誰回復(fù)。這樣做有幾個好處,首先是SDN網(wǎng)絡(luò)中ARP的行為和傳統(tǒng)二層交換中ARP的行為是一致的。客戶在destination打開tcpdump會看到ARP request。而在之前的方案中,destination是看不到ARP request的。單就這一點,在向客戶解釋說明的時候就省了好多事。第二個好處是即便控制器宕了,只要source和destination還在,ARP就能工作。第三個好處是這個方案解決了silent server的問題,只要廣播處理的正確,silent server就能夠收到ARP request并回復(fù)ARP reply。
當(dāng)然這個方案的代價也很大,就是要正確的處理廣播。如果僅僅是二層網(wǎng)絡(luò),我們可以用spanning tree,用SDN控制器計算spanning tree是一件麻煩但能夠做到的事情。如果是二層被三層隔離,就需要打隧道了。以vxlan為例,最初vxlan要求在underlay網(wǎng)絡(luò)中部署IP multicast來處理ARP,沒有人愿意,于是才有了后來的unicast-only vxlan。
博主把極端解法二稱為“種樹”:從本質(zhì)上來講,SDN控制器其實在為每一個廣播域種一棵沒有環(huán)的樹,好讓ARP在這棵樹上廣播。如何高效的“種樹”是真正體現(xiàn)各個廠家硬實力的地方,不管是用spanning tree在二層種樹,打隧道在三層種樹還是其他方法,這棵樹都必須要做到:無論任何網(wǎng)絡(luò)拓?fù)浠蛘呷魏尉W(wǎng)絡(luò)事件,有且只有一個廣播報文到達(dá)廣播域中的各個服務(wù)器。
分析到這里,博主已經(jīng)把當(dāng)source和destination在一個subnet時,處理ARP的種種考慮走馬觀花的討論了一遍。博主才疏學(xué)淺,但在博主知識范圍內(nèi)的ARP解決方案基本就是在以上兩個極端之間找一個折中并做一定的創(chuàng)新。
討論完source和destination處于同一個subnet的情況,我們來看一下兩者處于不同subnet的情況,這時我們需要考慮兩個問題。
問題一:誰是default gateway?
傳統(tǒng)網(wǎng)絡(luò)中,二層三層的界限往往非常清晰,二三層分界的地方就是default gateway所在的地方。但在seamless vm migration大行其道的今天,二層三層的界限越來越模糊,我們已經(jīng)很難明確的指出default gateway在網(wǎng)絡(luò)當(dāng)中的位置了,于是常聽人們感嘆:default gateway is everywhere。博主見識有限,到目前為止見到的default gateway大體上會出現(xiàn)在三個地方。
第一種情形是網(wǎng)絡(luò)中有一個專門的router(可能是硬件也可能是OVS)來做default gateway,這種情形常出現(xiàn)在overlay的解決方案中,比如Juno release之前的neutron reference implementation,比如vxlan L3 gateway。有客戶擔(dān)心這種方案的高可靠性,于是人們又在這種方案之上加入了VRRP。
第二種情形是default gateway在SDN控制器上。有些開源的SDN控制器就在采用這種方式。一種常見的邏輯是這樣的:source發(fā)出了ARP request問default gateway的mac,交換機把這個ARP request以packet-in的形式告訴控制器,控制器再以packet-out的形式把ARP reply發(fā)給source,于是source就知道了default gateway的mac。我知道有兄弟會說:這樣控制器不又成了單點故障和bottleneck了嗎?所以人們在此基礎(chǔ)之上進(jìn)行了改進(jìn),發(fā)明了第三種部署default gateway的方式。
這第三種方式就是把default gateway部署在所有的網(wǎng)絡(luò)邊緣的交換機上,有人稱之為destributed default gateway。在情形二中,SDN控制器已經(jīng)掌握了所有subnet的default gateway,我們完全可以把這個信息以某種方式cache/offload到所有的網(wǎng)絡(luò)邊緣的交換機上。這樣,這些交換機就可以代替控制器回復(fù)所有要default gateway mac的ARP request。
在以上三種方案中,方案一目前來說最常見。方案三在被越來越多的人接受,因為它的優(yōu)勢實在太明顯了。
問題二:如何處理silent server?
如果沒有部署任何的orchestration system,如果網(wǎng)絡(luò)中還有大量的bare metal server,那么silent server帶來的問題就不容忽視。我們設(shè)想一下下面這個場景:source和destination處在不同的subnet,并且destination是一個silent server。如果source向destination發(fā)了一個ping echo request,由于SDN控制器對destination一無所知,所以網(wǎng)絡(luò)中不會有關(guān)于destination的任何表項,于是這個echo request被很自然的packet-in到了控制器,此時的控制器又能對這個packet-in做什么呢?
博主目前還沒有看到任何關(guān)于這個問題的公開討論。一個最魯莽的辦法就是控制器以packet-out的方式在SDN網(wǎng)絡(luò)邊緣的所有端口上發(fā)ARP request,要destination IP所對應(yīng)的mac。如果destination真的接入了我們的網(wǎng)絡(luò),便會回復(fù)ARP reply,那時控制器便會學(xué)習(xí)到destination連接在哪臺交換機的哪個端口,相應(yīng)的表項便會得到更新。只是這樣一個魯莽的方法代價太大了。如果哪位兄弟有更好的辦法,歡迎提出來大家一起討論。
講到這里,博主已經(jīng)把SDN系統(tǒng)設(shè)計中關(guān)于ARP的考量梳理了一遍。不過ARP不會就此罷休。在以后的文章中,博主還會討論到NAT和floating IP,到那時,ARP會卷土重來,給我們制造更多的麻煩。