Mesos容器網路解決方案
CNUTCon2016已經落下帷幕,但是其精彩內容我們還在久久回味。今天小數為大家帶來的是數人云CTO肖德時在容器大會上的演講實錄,從理論說起,將實踐進行到底,讓我們一起來探討容器網路的問題以及解決
Mesos是數人云的主要的技術棧之一,並且我們很早就開始在實踐Mesos應用。從數人云的角度,我們希望容器的快速分發能夠幫助客戶實現快速交付。現在Mesos社群的發展非常快,Mesos有一個重要的特性Unified Container,讓Mesos可以交付容器。而接下來有一個更熱的話題—— 一容器一IP,在當前容器圈用網路方案如何解決這個問題,大家各顯神通,但是真正能把網路和容器說清楚的並不是特別多,結合數人云長時間的積累和實踐,在這裡我想跟大家一起探討容器的網路以及Mesos的解決方案,為大家提供一個參考。
Mesos的網路問題
Mesos 1.0其實已經有了一個完整的容器Interface的規範, CNCF(Cloud Native Computing Foundation)提供了Container Network Interface的介面,希望在Mesos社群裡規範網路的使用,讓大家有一個介面能夠複用網路。剛剛釋出的Mesos 1.0會遇到一些問題。最常見的就是我們無法逾越的一容器一IP,對於這個問題大家都有各自的看法,但是Mesos的過程裡面是sandbox,是沒有IP的概念的,所以要思考如何用容器的方式獲得IP。
第二,有了IP接著會出現服務發現的問題,什麼是服務發現?最簡單的是DNS,一個名字對多個IP。第三,有了網路之後,所有的資料之間有了聯絡,它們之間如何隔離是一個問題。例如,有一個數據庫專門為業務A使用,另外一個數據庫供業務B使用,就有兩個Wordpress,這兩個多租戶之間沒有任何的聯絡,我們希望它們之間的網路是隔離的, Mesos有一個可以讓大家立即使用的解決方案是Calico這個專案,雖然也有商業的公司在做這個專案,但是它的原始碼和思想是可以被複用的,所以我這次主要是與大家分享一容器一IP實現的方式。
實現一容器一IP為什麼選擇Calico?
一臺機器有自己的MAC地址,常規的主機上有自己的IP,MAC地址跟IP之間是有關聯的,也有三層的概念在裡邊,但是這是主機的網路,容器起來以後也是有MAC地址的,但是它是一個虛擬的MAC地址,如何獲得一個真實的IP或者想要給它分配的IP,就引出了一個概念——L3的虛擬網路,可以在沒有真實MAC地址或者MAC地址是一樣的情況下能給它分配不同的IP。Linux的Kernel有Filter的概念,可以對資料流進行轉換,在前面可以打包頭,我們就可以在Linux完整的基礎之上在路由的規則上做判斷, Linux Bridge模式的話是可以造IP的, Calico專案原始碼的基礎就是Linux的這個能力。之所以每個容器之間有隔離的作用,是因為它可以對每一個容器分不同的網段,網段之間是隔離的,本來兩個網段之間就沒有路由規則,無法相通。
Mesos有一個CNI的支援為什麼非常重要?之前使用Mesos和Doker的時候,我們有很多方式可以獲得IP,但這些方式對於Mesos生態圈裡面來說很難有規範, Mesos發展到如今已經把Doker去掉,對於網路這部分它需要一個規範,這個規範就是CNI規範。CNI規範是一個Json,這個Json非常簡單是一個很好的語義,而且它可以支援IPV4,以及之後的IPV6。一個配置檔案能夠描述整個網路結構已經足夠,有了CNI之後有很多種實現,Calico只是其中一種,大家會看到有硬體的、有Contive、有Weave,有Vxlan的模式等等,它們內部其實都有Overlay的模式。
Mesos本身是為資料中心設計的一套叢集,需要了解資料中心的網路結構有兩個非常關鍵的指標——南北的資料流和東西的資料流,南北的資料流就是從資料中心外面到資料中心內部的資料流。網路結構可能有路由器,閘道器,下面可能有LoadBalance,但它跟容器相關的網路是沒有關係的。我們通過容器的方式,類似於是想水平擴充套件的,基於這個網路的概念,我們提出想要一個比較複雜的網路結構。
網際網路公司普遍是記憶體比較小但機器比較多,常常一兩千臺機器;但有的傳統企業用的是大型機或者用的機器都比較大,他們的機器四五臺機就能組成一個網路,記憶體比較多,一臺機器可以跑兩三百個容器,四五臺機器能跑幾千個容器,這就是Clico和一些第三方的解決方案要解決的問題——管理IP的網段,因為IP地址是有限的,並且真實的網段是一套,而所有的這些分的IP的網段也是真實的,要去管理它的衝突。現在大家想到的是自己搞一個IP的管理介面,對IP進行管理把它固定住,但當容器越來越多的時候,就會有很多問題。
針對資料中心東西向的解決方案,Calico提出的一種方法是基於BGP協議。BGP協議是對路由規則進行控制,也就是說在沒有MAC地址的情況下,路由有路由表,路由表多了以後有兩件事,第一是要廣播,第二是這個路由表大了,軟體模擬的方式會有效能瓶頸,並且還要做精細化的訪問控制。因為兩個網段之間用的虛擬網段,有可能會衝突,一兩個網段的時候可能沒有問題,當幾十個APP之間隔離的時候兩個虛擬網段用的可能是同樣的IP地址,要保證它們兩個不通,如果通的話還要保證兩個IP不能衝突。那麼有沒有更好的方式?有,就是MAC Vlan——用主機的方式管理虛機。
這與Host的模式(不用自己的虛擬網路,用原生的主機模式網路)相比,只是加了一層MAC地址的管理。但是它有一個比較大的問題是對硬體有依賴,因為MAC是要轉IP的,而IP地址一定是有限的,MAC地址也是有限的,如果有衝突都是靠硬體來控制的,它並不能很輕易地上雲,雲端MAC地址不受控制,基本上是在私有云的基礎上用MAC Vlan的方法去做。對於Mesos的解決方案我們希望的是通用型的,有一個網路標準CNI, Calico是比較靈活的而有保障的。這是今天推薦這樣一個方案的原由。
在學習網路的過程中,有幾個知識比較重要。首先,什麼是三層網路?其實就是二層交換,三層路由。當前的路由器已經非常先進, Overlay最大的一個特點就是利用了路由這樣一個基本的知識點。大家會看到從S0這一塊進來以後一定是一個路由表,路由表之後會制定一些policy,然後到每一個網絡卡上再去劫持,去做一個路由表和一些規則,到機器上以後這個Brige有了一個新的網絡卡,是不依賴於MAC地址的,它的好處在於可以連線一個非常大的網,容器可以隨意的起,起幾百個容器都能連起來,我們只需把網配好就可以了。
但是傳統Overlay因為功能太強、太先進,一定要打無數個包頭才能從最遠端到裡邊。Vxlan以最新代表的SDN的網路非常先進,但是軟體模擬這種網路是非常脆弱的,規模越大效率越低,因為最簡單的問題就要解包、拆包,拆到最後拆到MAC地址和IP。網路資料包有拆包、解包的過程,只有讓它少一點拆包解包的能力,這樣速率才會高。通俗地說,當前所有用Doker網路的解決方案都是有損耗的,除非不使用或者使用Vxlan,Vxlan也沒有用虛擬網路,所有的虛擬網路都是有損耗的,所以目前無損耗的方式是不可能做到的。
這個包頭或者路由表在規則少、規模小的時候,效率還是很高的。上圖兩行紅字,第一個是Overlay對Overlay的,這是純的Vxlan的網路,像Docker的Swarm就用這種原生的網路建立,它的問題就在於它是虛擬的去轉換,所以整個網路非常弱,損耗只能到40%,60%都損耗掉了。並不是說網路不先進,瓶頸在於它實現的是一個參考,如果用硬體或第三方的結構,用Docker Swarm解決不了,那麼網路基本上是不可用的。第二個是Calico的Overlay,損耗差不多也是百分之十幾,是目前為止我們看到的一個最好的方式。這個基礎資料來自Percona這個公司,它做的MySQL發行版,在Master和Slave之間做同步,資料量增大這個瓶頸才能壓測出來,從而得到這個基礎資料報告。
Doker非常好用,但是Doker內建Swarm的特性,Doker Swarm就是兩行命令就能建立的網路,非常簡單。這個網路非常適合在測試環境和在單機的模式下除錯網路,它有自己的DNS、名字、網路IP,也可以自己管理,非常方便。但是到了生產級別用網路Mesos容器方案的時候,Calico這個方案可以幫助大家更好地理解和解決這個問題。
Calico是如何做的?
在上圖中,它的原理是IP Table,使用了Calico的元件,用BGP去做,其中一個關鍵點就是它要儲存這個路由規則,還要刷每臺機器的路由。它首先要用etcd儲存這些資訊,因為本地無法儲存,要保證一致性。第二,它的路由表要刷給別的機器,每臺機器都要去傳,所以每臺機器都是跟etcd有關聯的,觸發BGP去刷。它是無中心的,每臺機器刷完以後,這邊路由表規則一變,Mesos所有機器的路由表就變了,看起來好像網是通了。因為每臺機器出來的時候走的是S0的IP,到那邊的時候也是S0,但是路由做了規則轉換,所以兩邊都是通的,能跨主機的IP實現了這樣的過程。
這裡它做了一個小小的手術,因為網路結構越複雜,要對封包做的越多,在這個網段裡面跳一下的時候需要給訊息包頭打個標籤,IP要打不同的標籤,才能到那個網路裡面。它做了一個權衡,認為網路不要太多,可能就是一百臺機器的規模,因為有ARP廣播,廣播風暴在網路裡面非常常見,Mesos本身又不管網路。 Calico現在的做法就是在中間加了一個Route Reflector。BIRD也是第三方的,是Linux路由表的一個儲存,它利用第三方的儲存來儲存自己的路由規則,然後保證這個路由規則能夠被其它方主動去抓,這樣就從原來推的方式變成抓的方式,簡單地解決了這個問題。Mesosphere就是參考這個實現了一套類似於Calico的網路方案,叫Minuteman,也是開源的,在open dcos上面有這樣一個方案,大家可以去參考。這個就是Calico具體的實現。
對於Mesos的網路結構,要有Framework的概念,也要有Slave、Executer的概念。Launch Calico做了一個外掛安裝在每臺機器上,之後Framework呼叫、起一個任務的時候會劫持和觸發IP規則的啟用,Calico自己有IP management,下發到Slave那有一個隔離模組,做策略的隔離,獲得IP做一個Policy,然後做一個隔離。這一塊就是呼叫IP Table、IP Set去做,做完以後再去更新Master資訊放到Zookeeper裡面。然後獲得了一個Task的IP。尤其像現在沒有Doker的情況下,UnifiedContainerize 更是這種模型了。其實安裝的元件就是一個Calico的BGP Agent,以及一個Felix,Agent刷本地的,Felix去刷別人的。
最終,Mesos目前真實的IP網路結構就是這樣一個模型:每臺機器上面有一個小路由器,我把它定義為是一個路由器,其實就是路由規則,它儲存完以後每臺機器裡的容器的IP是可以不一樣的,也可以一樣的,但是左邊的這臺機器的IP跟右邊這臺機器的IP是不通的,路由表雖然刷了但是不通的。它可以通過廣播的方式告訴右邊的,右邊再刷一下自己的路由規則,這邊一訪問的時候,因為用IP Table把它的Package切了,就類似於Router把它改了,destination也改了,傳到另外一臺機器上,那邊也因為路由規則相應的做了轉換,所以相應的加了路由的包到裡邊,容器知道這個資料包了就可以接通。Router這邊它是模擬的、虛擬的,機器越多,由於它要主動去推,其效能就會下降。Calico的方式就是在外面再架一箇中央路由器,然後讓使用者刷,再從中央路由器去取,這樣就減少廣播的節點。
Mesosphere最新的做法,是用的Erlang的模型做了一個P2P的網路結構。好處在於可以點對點地刷路由,也就是說這兩臺機器的應用之間有關聯才去刷,如果沒有關聯,像Calico就刷一次,每個表都要刷,因為它不知道使用者會不會在下一秒去啟動新的容器,所以這種結構是傳統的網路結構。但是Mesosphere的Minuteman做法就更先進一點,它的做法就是點對點地去刷,容器起來的時候去刷,侷限性是隻能在一個數據中心裡面做這件事,因為它是一個實驗型的專案,我們尚不清楚它的效能和規模,僅在此與大家分享一下。謝謝大家。