OpenFlow會不會城頭變幻大王旗?

作者簡介:儲子叡,互聯(lián)港灣軟件架構(gòu)師,資深網(wǎng)絡(luò)愛好者 曾供職于Juniper/Brocade/VMware,對網(wǎng)絡(luò)安全/操作系統(tǒng)內(nèi)核/包轉(zhuǎn)發(fā)/ASIC均有涉獵

“在革命的每個階段都有人退出,這一點也不奇怪,正如大多數(shù)創(chuàng)業(yè)公司都會死掉,因此任何時間退出從概率上來看往往都是正確的。”

我們的問題在于,OpenFlow還行不行,如果不行了,是不是該選擇退出?是徹底退出,還是給OpenFlow找個接班人?這個問題相信已經(jīng)在SDN界(如果真的有SDN界的話)持續(xù)了一段時間了。

讓人不禁有些氣餒的是,我們不得不進(jìn)行如下的思考,OpenFlow從當(dāng)紅炸子雞變成今天的過氣網(wǎng)紅,這期間到底發(fā)生了什么?先天不足還是后天發(fā)育不良?是時機(jī)未到還是參與者各自心懷鬼胎?

這些問題里最幽默的是,很多振振有詞的質(zhì)疑者,他們其實根本連OpenFlow/OpenFlow-Controller 架構(gòu)是什么也搞不清楚,更別說讀懂一條流表,抑或是看懂一行OVS的代碼。我雖然不是OpenFlow的鐵粉,也覺得有必要來個正本清源,談?wù)凮penFlow是什么,談?wù)勅绾巫叩竭@一步,再談?wù)剬淼氖虑椴贿t。

首先,要談?wù)揙penFlow,先要說控轉(zhuǎn)分離即控制平面(Control-plane)和轉(zhuǎn)發(fā)平面的(Forwarding-plane)的分離。轉(zhuǎn)發(fā)平面有時候也被叫做數(shù)據(jù)平面(Data-plane),其原因就是交換機(jī)/路由器/防火墻這些所謂的數(shù)通設(shè)備,其本質(zhì)特征就是轉(zhuǎn)發(fā),數(shù)據(jù)包從一個接口進(jìn)來,從另一個接口(可能是同一個接口)或者多個接口出去,如此而已。關(guān)鍵在于,進(jìn)來的數(shù)據(jù)包從哪個(或者哪些)端口出去,由誰來決定?毫無疑問是由控制平面決定??刂破矫娓鶕?jù)從管理平面(Management-plane)來的命令/配置,加上通過路由/廣播等方法學(xué)來的網(wǎng)絡(luò)拓?fù)?,?yīng)用到特定的數(shù)據(jù)包身上,從而得出相應(yīng)的轉(zhuǎn)發(fā)動作,通常而言,是把數(shù)據(jù)包復(fù)制一份,修改相應(yīng)的報文字段,再從另外一個接口送出去。

傳統(tǒng)設(shè)備上控制平面和轉(zhuǎn)發(fā)平面從來都是分離的。所謂控轉(zhuǎn)分離,是指把原先存在于每個設(shè)備的控制平面抽出來,集中放在一臺或者幾臺核心設(shè)備上,由這些設(shè)備計算出網(wǎng)絡(luò)拓?fù)浜兔總€具體流量需要經(jīng)過的轉(zhuǎn)發(fā)路徑,計算的依據(jù),依然是來自控制平面的命令/配置,以及可以學(xué)習(xí)的拓?fù)?。計算結(jié)果流表通過OpenFlow協(xié)議下發(fā)到每臺設(shè)備上,設(shè)備僅需要匹配這些下發(fā)的流表完成轉(zhuǎn)發(fā)動作即可。因此,要理解OpenFlow,必須理解流表。

首先要搞懂流表,流表就是一張表!和一張普通的數(shù)據(jù)庫表并沒有什么不一樣,都是由一些字段(Field)定義的,可以把它們稱為列。而流表的具體內(nèi)容,可以稱為行。列是需要預(yù)先定義(Pre-defined)的,而行則是可以隨時(Run-time)被增刪改查(CRUD)的。

我們先忽略O(shè)penFlow復(fù)雜的版本關(guān)系,看看這張表抽象以后是個什么樣子。

首先,Header Fields是數(shù)據(jù)包的包頭。我們知道幾乎所有的數(shù)據(jù)包都是由包頭(header)和負(fù)載(payload)組成的。一個數(shù)據(jù)包可能有很多個包頭組成的,這實際上就是網(wǎng)絡(luò)分層(layer)的本質(zhì),每一層都有自己的能夠提供的服務(wù)(service),而服務(wù)其實就是定義在包頭里的。下個層次的包頭對于上一個層次來說,是負(fù)載的一部分。打個比方來說TCP的包頭就是緊接在IP包頭的后面的,對于IP這個層次來說,TCP的包頭就是負(fù)載。所以,從數(shù)據(jù)流的視角來看,數(shù)據(jù)包是由一系列的包頭依次組成的,不同的轉(zhuǎn)發(fā)層面的動作,例如我們常說的二層交換,三層路由,四層防火墻,其實就是對于數(shù)據(jù)包這個連續(xù)的數(shù)據(jù)流,你看多遠(yuǎn)(多少個包頭)而已。其實并沒有本質(zhì)區(qū)別。

因此,OpenFlow 的Header Fields是一系列需要匹配的包頭的組合。

OpenFlow的轉(zhuǎn)發(fā)動作就是從以上連續(xù)的包頭的域(Field)里,找出需要匹配的那些,用來標(biāo)志出一個數(shù)據(jù)流(Flow),對于所有匹配這個流的數(shù)據(jù)包,均做相同的動作(Action),并且更新計數(shù)器(Counter)。對于所有Flow都不能匹配的數(shù)據(jù)包,則需要用Packet-in的消息把這個數(shù)據(jù)包送到控制器去,由控制器來決定怎么辦,或者丟棄,或者為這個包創(chuàng)建一個新的數(shù)據(jù)流。

通過OpenFlow完成的轉(zhuǎn)發(fā)動作,和原先傳統(tǒng)設(shè)備的轉(zhuǎn)發(fā)流程并沒有區(qū)別,換句話說,如果傳統(tǒng)設(shè)備廠商愿意,完全可以在自己單臺設(shè)備的控轉(zhuǎn)平面之間跑OpenFlow,因此,控轉(zhuǎn)分離的架構(gòu)不會給轉(zhuǎn)發(fā)設(shè)備帶來任何挑戰(zhàn),那么OpenFlow帶來的真正挑戰(zhàn)是什么?

如下是一個具體的OpenFlow的表,看看其中有何奧妙。

我們知道數(shù)據(jù)庫的設(shè)計,查起來快不快,關(guān)鍵在于鍵(Key)和索引(Index),以上這個表的問題是鍵在哪里?可能被用來做為匹配的字段高達(dá)十二個,而每一行都可能只有這十幾個字段中的幾個,沒有鍵和索引,沒辦法迅速查表!

為什么要查表?剛才只講了轉(zhuǎn)發(fā)動作中控制平面和轉(zhuǎn)發(fā)平面的互動,由控制平面來決定如何進(jìn)行轉(zhuǎn)發(fā),但是顯然一個數(shù)據(jù)流可能包括成千上萬個數(shù)據(jù)包,決定了第一個包怎么轉(zhuǎn)發(fā),其實基本就確定了后面所有的包如何轉(zhuǎn)發(fā),完全沒有必要請控制平面來參與所有包的處理,轉(zhuǎn)發(fā)平面需要做的僅僅是查表而已,這個包屬于曾經(jīng)被轉(zhuǎn)發(fā)過的流,簡單的復(fù)制一下轉(zhuǎn)發(fā)動作即可,這就是所謂的快速轉(zhuǎn)發(fā)(Fast-path)。一個數(shù)據(jù)包從入接口(Ingress)進(jìn)來,OpenFlow交換機(jī)需要確定他匹配哪個流,從而找到相應(yīng)的轉(zhuǎn)發(fā)動作,迅速的把這個數(shù)據(jù)包從出接口(Egress)送出去,然后趕緊去處理下一個數(shù)據(jù)包,必須迅速查流表,而不是線性查流表。換句話說,不能從第一行(Line)開始一行一行匹配,看這個數(shù)據(jù)包的Header Field是不是跟這一行匹配。如果這個表有成千上萬的行,逐行的查找是不可接受的,因為需要的時間,根本不能匹配10Gbps或者更高的速率!

首先看傳統(tǒng)網(wǎng)絡(luò)設(shè)備是怎么干的,傳統(tǒng)設(shè)備里也有轉(zhuǎn)發(fā)表,例如一個傳統(tǒng)的防火墻,他的轉(zhuǎn)發(fā)表可能支持一百萬個會話(session),標(biāo)志一個會話的特征是五元組(源目的地址/源目的端口/協(xié)議號),所以一個數(shù)據(jù)包進(jìn)來以后,防火墻需要做的就是把這個五元組提取出來,然后根據(jù)這個五元組算一個哈希值(Hash),根據(jù)這個哈希值,常數(shù)時間O(1)直接可以找到會話,然后或者匹配這個會話以后,就知道應(yīng)該把包送到哪個出接口,是不是需要對包頭進(jìn)行修改,進(jìn)行轉(zhuǎn)發(fā)即可。如果匹配不到任何會話(把這個數(shù)據(jù)包送給控制平面的CPU,看能不能建立一個新的會話)。傳統(tǒng)設(shè)備為什么可以這么干?因為他們的功能是限定的,他們需要處理的包頭的域是確定無疑的,那么提取這些域,然后做哈希查找/快速轉(zhuǎn)發(fā),全部可以用硬件實現(xiàn),從而達(dá)到非常高的轉(zhuǎn)發(fā)速率。

問題是到了OpenFlow這個新世界里,有些假設(shè)不存在了,還是以上這張表,在看到具體的表內(nèi)容之前,交換機(jī)/路由器是不可能預(yù)先知道需要提取哪些字段的,也很難提前做硬件電路設(shè)計,硬件雖說不是完全沒有辦法,但是局限很大,適應(yīng)所有字段全靈活匹配的騰挪空間嚴(yán)重不足,那還怎么快速查表,怎么轉(zhuǎn)發(fā)?

隨著OpenFlow版本的不斷升級,匹配(match)的字段由少變多,匹配本身也從定長變成了類似TLV的結(jié)構(gòu),如下圖

OpenFlow 1.0

OpenFlow 1.1

OpenFlow 1.3

雖然OpenFlow版本之間并不一致,但是“需要匹配的域是不固定的”這點并沒有變化,對于大多數(shù)習(xí)慣了“二層交換,三層路由,四層防火墻”的廠商來說,二三四層靈活組合的匹配方式,的確是太復(fù)雜了。雖然各家都在努力支持更多流表的種類,支持更多流表的數(shù)目,但跟傳統(tǒng)動輒七八十萬條路由,百萬級的策略/會話的大盒子(Device)來比,純OpenFlow設(shè)備能達(dá)到的性能和指標(biāo)的確是還差得很遠(yuǎn)。

因此,OpenFlow太過靈活,先天不足等等說法也就不足為奇了。

還好有些人并不這么想,硬件搞不定,就說軟件太靈活,這個鍋不能背!難道不能設(shè)計一個能搞定的硬件嗎?答案是可以的,不僅可以,還不止一種!我們需要的是重新定義一下轉(zhuǎn)發(fā)面的硬件,也就是所謂的PISA(Protocol Independent Switch Architecture),大家把這個事情統(tǒng)一一下認(rèn)識,至于具體各家各戶怎么實現(xiàn),大可以自己回家閉門造車,各顯其能。

PISA的核心是轉(zhuǎn)發(fā)平面可以編程(Programmable),編程語言也就是比OpenFlow更紅的P4了。那P4到底是不是OpenFlow的終結(jié)者/繼承者/替換者呢?首先看這個圖。

首先,Parser把數(shù)據(jù)包解析成一系列的Header,然后依次進(jìn)入Ingress和Egress兩類流水線。在流水線里可以經(jīng)歷一系列的匹配(M)/動作(A)的階段(Stage)。每一個Stage的核心是:一張表!匹配這張表,然后根據(jù)匹配結(jié)果做動作,跟我們上面說的一摸一樣對不對!那么這張表是OpenFlow的流表嗎?答案是,不一定。

準(zhǔn)確的說,某一類的流表可以轉(zhuǎn)化成PISA里的一張表??匆幌乱粡圥4的表,跟OpenFlow的表比較一下。

可以發(fā)現(xiàn)

  • P4的表是需要被P4程序明確定義的,依然是Match/Action這個思路。
  • P4的表需要匹配的鍵(Key)是固定的,如上圖的VRF/IP-Prefix
  • P4支持多級的表,數(shù)據(jù)包匹配完第一個表后可以匹配下一個表,因此,對于 不同包頭字段的匹配要求,可以用多個表來實現(xiàn)
  • P4的匹配項目可以支持最長前綴匹配LPM(longest prefix match),以及帶 掩碼的三元匹配(Ternary Match),這是需要硬件TCAM支持的,考慮到TCAM 的成本,這樣的匹配項目顯然也不能太多(但是好歹比支持OpenFlow任意匹 配簡單多了)。

最關(guān)鍵的一條,PISA 架構(gòu)要求可編程性,因此用P4定義的表是可以重新編程的,重新編程P4表可以導(dǎo)致重新生成一個交換機(jī)的固件(Firmware),交換機(jī)下載以后,可以重新分配他的硬件(流水線,內(nèi)存,TCAM等)資源,針對新的匹配表實現(xiàn)硬件加速。在此之前,基于ASIC的傳統(tǒng)轉(zhuǎn)發(fā)設(shè)備對此是不可想象的。ASIC被認(rèn)為是固定(fixed)的,一旦硬件成型以后其匹配/轉(zhuǎn)發(fā)能力就是確定而不可擴(kuò)展的,軟件只能通過修改寄存器來進(jìn)行微調(diào)。而進(jìn)行一次重要的ASIC版本升級,其消耗的時間和金錢都是巨大的。

所以簡單的來說,P4的出現(xiàn)并不是為了替換掉OpenFlow,而是為交換機(jī)支持OpenFlow提供了可能性。OpenFlow的設(shè)計的確是靈活,但是并不是“太過靈活”,事實上,支持任何類型的OpenFlow流表并沒有意義,實際情況下一臺網(wǎng)絡(luò)設(shè)備將要面對的流量和流量是可以預(yù)測的,是有限的,根據(jù)可能的OpenFlow流表寫好P4的程序是可能的,通過可編程的交換芯片實現(xiàn)硬件加速是可能的,一旦發(fā)生未知的流量/應(yīng)用重新編寫P4程序并下發(fā)到P4交換機(jī)也是完全可以的。因此可以這么說,P4一開始的誕生也許是為了讓交換芯片適應(yīng)OpenFlow(OpenFlow Adapter),后來逐漸發(fā)展成了一種全新的可編程的交換機(jī)架構(gòu)PISA,不僅表的匹配是可編程的,Parser也是可以編程的,匹配以后的動作Action也是可以編程的,PISA可以說是轉(zhuǎn)發(fā)層面的一場革命。

OpenFlow的流表和P4的表本質(zhì)上是一樣的,都是從控制層面到轉(zhuǎn)發(fā)層面的消息,而P4則定義了整個轉(zhuǎn)發(fā)層面,和OpenFlow所處的位置不完全一致。P4和OpenFlow可以很好的協(xié)同工作,所以不存在有了P4就可以代替OpenFlow的說法,至于P4是OpenFlow 2.0的說法也是非常不嚴(yán)謹(jǐn)?shù)模˙TW,P4-runtime成為OpenFlow 2.0還倒是真的有點可能)。做為參考資料,可以看下https://github.com/p4lang/switch/blob/master/p4src/OpenFlow.p4,看OpenFlow和P4這對好基友是怎么一起工作的 :)

談完了轉(zhuǎn)發(fā)平面,再來討論一下控制平面的事情,OpenFlow是控制器發(fā)給交換機(jī)的,交換機(jī)有了PISA,那Controller呢?從這個架構(gòu)誕生的第一天起,如何解決Controller的單點故障問題就被一直被質(zhì)疑。解決單點故障的唯一辦法就是把單點變成多點,也就是用多個Controller來代替單一的Controller,那么多個Controller之間數(shù)據(jù)如何同步?這又是一個老生常談的分布式系統(tǒng)的問題。

我們知道,分布式系統(tǒng)有CAP原理。

闡述了分布式系統(tǒng)中的一個事實:一致性(Consistency)、可用性(Availability)和分區(qū)容錯性(Partition Tolerance)不能同時保證。三個只能選擇兩個。很不幸,這是所有分布式系統(tǒng)都具備的特性,并不是OpenFlow-Controller架構(gòu)獨有的“缺陷”!即使是最紅的分布式系統(tǒng)區(qū)塊鏈技術(shù),也得服從CAP原理。換句話說,沒有萬能的金丹。那種希望CAP兼得的想法,只能說是瘋狂或者幻想(Pure Madness)。

首先來解釋一下這個原理。假設(shè)有兩臺Controller A、B,兩者之間互相同步保持?jǐn)?shù)據(jù)的一致性?,F(xiàn)在B由于網(wǎng)絡(luò)原因不能與A通信(Network Partition),此時某個交換機(jī)向A發(fā)了Packet-in,A通過計算以后發(fā)現(xiàn)需要下發(fā)流表。他有兩種選擇:

  • A拒絕下發(fā)流表,這樣能保證與B的一致性,但是犧牲了可用性,交換機(jī)不能在有限的時間內(nèi)得到確定的響應(yīng)。
  • A正常向Client下發(fā)流表,但是這樣就不能保證與B的一致性了。

由于眾所周知的原因,我們面臨的網(wǎng)絡(luò)環(huán)境,Network Partition是必然的,網(wǎng)絡(luò)非??赡艹霈F(xiàn)問題(斷線、超時),因此CAP理論一般只能AP或CP,也就是在可用性和一致性里二選一。

  • CP: 要實現(xiàn)一致性,則需要一定的一致性算法。
  • AP: 要實現(xiàn)可用性,則要有一定的策略決議到底用哪個數(shù)據(jù)。

在以上的例子里,顯然應(yīng)該首先滿足可用性,A控制器應(yīng)該先下發(fā)流表,保證交換機(jī)可以正常工作,等到AB之間的網(wǎng)絡(luò)恢復(fù)以后,再設(shè)法將這個變化同步給B,使得AB之間達(dá)到最終一致性。(Eventually Consistency)。如果這個分布式系統(tǒng)不止AB這兩個節(jié)點,而是足夠復(fù)雜,最終一致性可能不是通過簡單的同步(Sync)可以完成的,可能需要再多個節(jié)點之間通過投票來完成。也就是著名的共識算法(如Paxos和Raft)。區(qū)塊鏈技術(shù)也高度依賴共識算法,一個基本的認(rèn)識是,去中心化(Decentralization)需要參與投票的節(jié)點足夠多,才可以避免有人可以控制51%以上的算力。同理,如果有人抱怨控制器不可靠或者不同步,原因可能僅僅是控制器不夠多。如果僅僅有兩臺數(shù)據(jù)不一致的控制器,如何確定哪一臺的數(shù)據(jù)是完備的?如果有三臺或者更多,可能就會簡單一點,讓他們?nèi)ネ镀本秃昧耍吘苟嗯_控制器集體發(fā)瘋的可能性比較小。

因此,為了避免單點故障引入了分布式系統(tǒng),CAP原理是分布式系統(tǒng)固有的特征,這不是并不是OpenFlow-Controller架構(gòu)的什么固有缺陷。通過共識算法,達(dá)到分布式系統(tǒng)的最終一致性,是完全可以實現(xiàn)的。事實上,主流的SDN-Controller早已實現(xiàn)。可以參考如下的論文https://www.telematica.polito.it/~giaccone/papers/icc16-onos.pdf

話又說回來了,控制器也不是越多越好的,傳統(tǒng)的網(wǎng)絡(luò)里,每臺設(shè)備都有控制平面,其實就是個控制器無限多的分布式系統(tǒng)。這些控制器之間跑著各種各樣五花八門的控制協(xié)議,想讓他們達(dá)成某種共識,幾乎是不可能的。傳統(tǒng)網(wǎng)絡(luò)基本上是一個既沒有一致性C也沒有可用性A的不可控的分布式系統(tǒng),這個系統(tǒng)的形成有其歷史原因,跟互聯(lián)網(wǎng)一步步從一個個試圖互聯(lián)的孤島變成無所不在的智能網(wǎng)絡(luò)的歷程有關(guān),目前看,似乎工作的還可以,但是這不是我們固步自封拒絕變化的理由。我們需要更好的互聯(lián)網(wǎng),需要更好的一致性和可用性,在傳統(tǒng)設(shè)備的世界里自娛自樂,不能帶來這一切。

綜合起來看,OpenFlow的紅旗,說得更準(zhǔn)確一些,SDN的紅旗,恐怕還是要繼續(xù)打下去了。

極客網(wǎng)企業(yè)會員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進(jìn)一步核實,并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2018-06-11
OpenFlow會不會城頭變幻大王旗?
OpenFlow會不會城頭變幻大王旗?,作者簡介:儲子叡,互聯(lián)港灣軟件架構(gòu)師,資深網(wǎng)絡(luò)愛好者 曾供職于Juniper/Brocade/VMw

長按掃碼 閱讀全文