天天看點

洪強甯:宜信PaaS平台基于Calico的容器網絡實踐

洪強甯:宜信PaaS平台基于Calico的容器網絡實踐

本文内容來自由七牛雲主辦的ECUG Con,獨家授權InfoQ整理完成

容器雲面臨的網絡挑戰

在傳統的IDC的架構裡面網絡是很重要的事情,在虛拟機環境中網絡的發展已經有很多成熟的解決方案,現在為什麼還在研究新的方案呢?因為雲計算。雲計算在2013、2014年之前的時間段,其主要的發力點在虛拟機。但是從容器技術出現之後,虛拟機被更輕量的容器方式颠覆,進而大幅降低開發、運維、測試和部署、維護的成本。當然也帶來了很多在虛拟機裡沒有面臨過的問題。

在網絡層面,容器的本質是幾個被封裝了的程序。這必然導緻每個容器都會有自己完整的網絡棧、有自己的IP。是以整個雲的基礎設施——叢集裡有大量的網絡和IP要管理,并且程序的啟動和結束是與容器伴生的,程序生滅的頻繁程度超過了虛拟機幾個量級。建立一個虛拟機會開啟很多程式,程式之間彼此通信,但和虛拟機外部的通訊是少很多的。而容器的誕生,從網絡管理角度來說,微服務架構呼之欲出。

用容器做遷移的時候,如果一台機器當機了,對應用而言希望是無感覺的。是以,如果容器所在的主機出故障,就帶來了新的問題,即容器IP的任意漂移。在建立虛拟機的時候,IP位址的配置設定是一種靜态方式;但是在容器上面,IP位址的配置設定通常是動态配置設定。一個容器啟來的時候,通常我們不會知道它的IP是什麼,隻有起來之後才知道。

在容器雲的場景下,我們傾向于把多個應用放在一個應用上運作,這導緻應用和應用之間需要做安全隔離——我們不希望一個出問題的應用會影響其他的應用。是以說容器之間需要決定哪個容器可以通信,哪個不能通信。以前在虛拟機的時代,通過大量分層可以解決,但容器環境裡這件事情的難度提高了。

是以我們選擇網絡解決方案的需求也發生了變化,最大的要求是容易管理。網絡間通信量大了,不能夠承受太大的損耗。而當發生容器間遷移的時候,需要一種機制,來保證遷移後的IP不會發生變化。同時,它的解決方案是需要細粒度的安全政策。

容器本身是一個單機軟體,并沒有為跨主機的網絡考慮太多。跨主機容器互聯的解決方案最典型的是兩台主機之間通過一個交換節點實作連通。在主機内起十到幾十個主機的規模,考慮到主機上有沒有足夠的CPU和記憶體,在這個主機上做靜态IP規劃幾乎是不太可能。這時候我們就引入SDN技術——用軟體的方式定義網絡,軟體資料發生變化時網絡就相應地發生變化。

常見SDN方案

簡單的談一下DockerBridge,關于主機内部的網絡管理工作。每個容器裡面都有一個虛拟網卡,和主機上的虛拟網卡做配合,所有容器内的虛拟網卡都可以和主機通信。通過端口映射,我調用對方的容器服務的時候,不能使用該容器直接的位址,必須使用它主機的位址。因為有了這樣一個轉發,網絡通訊的性能有所損耗。當然,還有一個問題更嚴重,通路你的容器先要搞清楚你的主機是什麼,這樣網絡通訊會跳來跳去。不但麻煩,還會帶來端口沖突。每建立一個容器會綁定一個端口,怎麼管理好這些端口是一個很大的挑戰。

第二個解決方案是Flannel,這個想法很好。每個主機負責一個網段,在這個網段裡面配置設定一個IP位址。通路另外一台主機的時候,通過網橋到達主機上的IP位址,這邊會有一個裝置,程式會把你發的包讀出來,去判斷你的目标位址是什麼,歸哪台機器管。還會把你的IP包外面加一個UDP包,發到目标位址。收到之後,會把前面的包扔掉,留下來的就是目标容器位址。這個方法有幾個問題,第一個是要做封包的操作。第二個問題是每個主機上的容器是固定的,容器的不同主機之前的遷移必然帶來IP的變化。

再來說說Weave,他的思路是共享IP而非綁定。在傳輸層先找到目标位址,然後把包發到對端,節點之間互相通過協定共享資訊。Flannel和Weave的特點是類似的,都用的是UDP或者是VxLAN的技術。事實上使用UDP性能是很差的,VxLAN和UDP差不多,它有一個網絡切隔,而且在裡面可以跑二層協定。還有一種是IPIP封包,直接把一個IP包封裝在一個IP包裡面。

以上不難看出,原生網絡性能比較差,使用UDP的時候性能損失在50%以上,使用VxLAN也會有20%~30%的損耗。是以我要在核心上封包,使用硬體來解決這些問題。而且容器和容器之間出現通訊故障,調試的時候非常困難。

關于封包

回過頭來想一下,我們為什麼要封包?其實它是改包,主要解決的問題是同一個問題。即容器網絡裡,主機間的不知道對方的目标位址,沒有辦法把IP包投遞到正确的地方。

傳統的二層網絡是用路由來互相通路,不需要封包。但是路由規則怎麼維護?利用BGP(基于TCP之間兩兩連接配接)搞一個分布式的路由叢集能否滿足規模?

Metaswitch:容器内部配一個路由指向自己主控端的位址,路由規則下發,這是一個純三層的網絡沒有封包,接近原生網絡性能。

在容器裡面我們怎麼做呢?我們發現了Calico項目。不同主機上的每個容器内部都配一個路由,指向自己所在的IP位址;每台伺服器變成路由器,配置自己的路由規則,通過網卡直接到達目标容器,整個過程沒有封包。

是以這是一個純三層網絡,沒有引入一個DP,沒有封包。在主機内部做另外一個容器,可以三條到達終端,你可以知道是誰出了問題,調試的時候很容易,很好管理。容器内的應用資料傳出來,和二層完全隔離,對于我們絕大多數的應用來講隻需要三層就夠了,很少有應用處理二層。

那麼,路由交換是不是很難呢?用傳統的BGP技術就可以實作。這個協定在大規模應用下是一個很好的場景。而且BGP有一個自治域的概念。在這個場景下會有一個問題,路由之間的資訊交換實際上是基于TCP協定,每兩個之間都有一個TCP連接配接,規模大了以後複雜度非常高。是以在這種場景下,大概是幾百個主機直接使用BGP的方式來做;再大一點的話,選擇分布式互聯,這樣可以把網絡規模繼續擴大,最後能夠支援到幾萬台機器。如果不需要這些政策,不做商業邏輯和業務邏輯,隻是用BGP來做路由互聯的話,其實還是很簡單和高效的。

金融業務的具體實作

宜信内部的做法是用powerstrip實作,還有一個是手工去做,啟動容器直接用Docker,然後自己再去設定IP。如果容器之間都互通,建立容器的時候都通過配置環境變量,會建立一個Profile,配置好iptables 以及ipset可以保護我們的伺服器。再稍微複雜一點的話,可以修改ACL規則,如果有很多個APP,每個APP都需要通路資料庫,每增加一個IP都要修改配置這樣顯得太麻煩,我們可以通過給所有的APP打标簽的方式來解決這個問題。

配置容器的三種方法:

用powerstrip來Hijack劫持Docker的API,這個思路很有意思。

calicoctr container指令。

libnetwork驅動(需Docker1.9以上)。

因為做的是金融業務,性能其實不是最吸引人的,ACL應用是宜信關注的重點。比如在宜信的場景下做雲平台的時候,會有應用的概念。一個應用有多個容器,互相可通路;不同應用的容器互相不能通路;一個應用對另外一個應用提供服務,作為服務容器并且規定哪些可以通路。所有的應用容器能夠通路叢集,應用容器不可以通路自己所在的叢集的任何一台伺服器。總之,我們要實作應用可以通路主機上指定的服務,可以通路除本網段之外的其他網段。

Calico使用總結

Calico的應用場景主要是IDC内部,推薦部署在二層網絡上,這樣所有路由器之間是互通的。這種場景是大二層的解決方案,所有伺服器都在裡面。但大二層主要的問題是彈性伸縮的問題。頻繁開關機的時候,容器啟停雖然不影響交換機,但容易産生廣播風暴。網絡規模太大的時候,一旦出現了這樣的問題,整個網絡都會有故障,這個問題還沒有解決的特别好。

Calico作為一個純二層的應用問題不大。我們可以把叢集分成了很多網段,對外是三層網絡的結構。叢集内部分成多個自制域,比如一個機櫃是一個自制域,之間通過交換路由的方式實作在三層容器到容器的互通。瓶頸在于容器的路由資訊容量。是以說本質上它不是一個應對網際網路規模的解決方案,但對宜信場景是夠用的。

我們實施的時候遇到一些坑,比如容器在啟動時沒有網絡、操作ETCD的時候BGP配置頻繁加載,等等,最後我們多一一解決了。我們也發現了driver方案功能方面的弱點,現在還繼續使用劫持API的方法。如果要在雲上使用,如果支援BGP,直接可以用;如果不支援BGP可以用IPIP。現在英特爾的網卡支援兩個協定,一個是GRE、一個是VxLAN。如果真的把它放在雲上,我們可以考慮一下把VxLAN引進來,性能上的差别不是很大。

本文根據洪強甯在ECUG Con的演講整理而成,ECUG(Effective Cloud User Group,實效雲計算使用者組)是由Erlang愛好者、分布式領域的知名專家組成的民間技術團體。ECUG Con是該組織一年一度交流雲計算産業前沿技術的大會。

本文轉載自InfoQ網站。

繼續閱讀