本文講的是<b>DockOne微信分享(一三零):探究PaaS網絡模型設計</b>【編者的話】PaaS的抽象邏輯使得其網絡模型與IaaS有所不同,本次通過重點說明Kubernetes和Docker的網絡,進而來探究PaaS的網絡模型設計。
<a href="http://dockone.io/article/2445">【3 天燒腦式容器存儲網絡訓練營 | 深圳站】本次教育訓練以容器存儲和網絡為主題,包括:Docker Plugin、Docker storage driver、Docker Volume Pulgin、Kubernetes Storage機制、容器網絡實作原理和模型、Docker網絡實作、網絡插件、Calico、Contiv Netplugin、開源企業級鏡像倉庫Harbor原理及實作等。</a>
概念上來說,IaaS是基礎架構即服務,PaaS是平台即服務。從服務化角度來說兩者對于網絡的需求有共同點:
一台主控端的網絡隔離,一台主控端要運作多個環境黑盒(VM或者容器),這時候每個環境黑盒的網絡需要隔離。
環境變更後的通路一緻性,比如VM或者容器遷移到其他主控端的時候,如何保證外部通路不感覺,比較通用的解決方案網絡代理層來解決。
實作上來說,IaaS是VM管理,PaaS是容器編排,兩者的網絡也會有些不同:
容器比VM輕量級,啟停更快,更友善遷移,是以PaaS的整個排程政策會更靈活,容器的遷移頻率是高于VM,當容器遷移的時候,PaaS需要更加快速的解決變化後的網絡通路。
VM安全高于容器,IaaS這部分會更多在隔離和安全上有所考慮,當然這個可能是公有雲和私有雲的一個定位,個人認為IaaS比較适合公有雲,PaaS比較适合私有雲。
以上部分我們讨論了PaaS網絡需求,總結來說PaaS需要解決主控端的網絡隔離和環境變更後的通路一緻性問題,然後在靈活性上需要更加注重,私有雲的定位可以減少因為安全和隔離的代價,保證高性能。
網絡隔離最基本問題就是要解決端口沖突,一種思路是容器通過端口映射通路,主控端的端口由系統配置設定避免端口沖突,這種方式對使用的便利性是有意義的,但并不理想,因為需要對各種端口進行映射,這會限制主控端的能力,在容器編排上也增加了複雜度。
端口是個稀缺資源,這就需要解決端口沖突和動态配置設定端口問題。這不但使排程複雜化,而且應用程式的配置也将變得複雜,具體表現為端口沖突、重用和耗盡。
NAT将位址空間分段的做法引入了額外的複雜度。比如容器中應用所見的IP并不是對外暴露的IP,因為網絡隔離,容器中的應用實際上隻能檢測到容器的IP,但是需要對外宣稱的則是主控端的IP,這種資訊的不對稱将帶來諸如破壞自注冊機制等問題。
是以就要引入一層網絡虛拟層來解決網絡隔離,現在說的比較多的大二層網絡,L2 over L3,比如OVS、Flannel、Calico等等。
一個通用方案來說通過代理層提供不變的通路入口,像OpenStack的網絡節點就是一個L3(IP)的通路入口,而PaaS更多的是提供L4(TCP、UDP)和L7(HTTP)的通路,L4比較流行的開源方案有LVS,L7的是Nginx和Haproxy。
是以PaaS的網絡結構有:
實體網絡
虛拟層網絡
代理層網絡
Kubernete Docker作為目前最流行的開源PaaS實作,通過其實作細節可以更加了解PaaS的網絡模型實踐。
Docker使用Linux橋接,在主控端虛拟一個Docker容器網橋(docker0),Docker啟動一個容器時會根據Docker網橋的網段配置設定給容器一個IP位址,稱為Container-IP,同時Docker網橋是每個容器的預設網關。因為在同一主控端内的容器都接入同一個網橋,這樣容器之間就能夠通過容器的Container-IP直接通信。
Docker網橋是主控端虛拟出來的,并不是真實存在的網絡裝置,外部網絡是無法尋址到的,這也意味着外部網絡無法通過直接Container-IP通路到容器。
Kubernetes中Pod是容器的集合,Pod包含的容器都運作在同一個主控端上,這些容器将擁有同樣的網絡空間,容器之間能夠互相通信,它們能夠在本地通路其他容器的端口。
實際上Pod都包含一個網絡容器,它不做任何事情,隻是用來接管Pod的網絡,業務容器通過加入網絡容器的網絡進而實作網絡共享。
Pod的啟動方式類似于:
是以Pod的網絡實際上就是Pod中網絡容器的網絡,是以往往就可以認為Pod網絡就是容器網絡,在了解Kubernetes網絡的時候這是必須要需要清楚的,比如說Pod的Pod-IP就是網絡容器的Container-IP。
Kubernetes網絡模型是一個扁平化網絡平面,在這個網絡平面内,Pod作為一個網絡單元同Kubernetes Node的網絡處于同一層級。
在這個網絡拓撲中滿足以下條件:
Pod間通信:Pod1和Pod2(同主機),Pod1和Pod3(跨主機)能夠通信
Node與Pod間通信:Node1和Pod1/ Pod2(同主機),Pod3(跨主機)能夠通信
為此需要實作:
Pod的Pod-IP是全局唯一的。其實做法也很簡單,因為Pod的Pod-IP是Docker網橋配置設定的,是以将不同Kubernetes Node的Docker網橋配置成不同的IP網段即可。
Node上的Pod/容器原生能通信,但是Node之間的Pod/容器如何通信的,這就需要對Docker進行增強,在容器叢集中建立一個覆寫網絡(Overlay Network),聯通各個節點,目前可以通過第三方網絡插件來建立覆寫網絡,比如Flannel和Open vSwitch等等。
Flannel由CoreOS團隊設計開發的一個覆寫網絡工具,Flannel 通過在叢集中建立一個覆寫網絡,為主機設定一個子網,通過隧道協定封裝容器之間的通信封包,實作容器的跨主機通信。Flannel将會運作在所有的Node之上,Flannel實作的網絡結構如圖所示:
Kubernetes中的Service就是在Pod之間起到服務代理的作用,對外表現為一個單一通路接口,将請求轉發給Pod,Service的網絡轉發是Kubernetes實作服務編排的關鍵一環。
Service都會生成一個虛拟IP,稱為Service-IP, Kuberenetes Porxy元件負責實作Service-IP路由和轉發,在容器覆寫網絡之上又實作了虛拟轉發網絡。
Kubernetes Porxy實作了以下功能:
轉發通路Service的Service-IP的請求到Endpoints(即Pod-IP)。
監控Service和Endpoints的變化,實時重新整理轉發規則。
負載均衡能力。
Kubernetes Porxy是一種分布式L3代理轉發, 預設是基于Iptables實作,這從設計上很值得借鑒,但是性能部分有待驗證。
Kubernetes中的Ingress提供了一個統一的對外代理入口配置,比如HTTP的通路配置,然後通過實作Ingress-Controller,Ingress-Controller的實作可以用Nginx、LVS等等,以Nginx來說,就Ingress-Controller監控Kubernetes API,生成Nginx配置,然後加載生效,而Nginx跟Pod的通信,可以走Service,但是考慮到Kubernetes Porxy的性能問題,建議直接和Pod通信。下面就是一個實作圖:
整體來看的一個網絡模型如下:
Q:有這麼多虛拟網絡,覆寫網絡,會不會有網絡延遲?
A:網絡虛拟會帶來性能損耗,比如Flannel需要将封包封裝到UDP包中傳輸,這中間的封包解包就會帶來損耗。是以網絡虛拟化的部分,軟體的實作還有待優化,其實更好的方式是硬體支援,比如現在提的很多的SDN網絡。
Q:Pod為什麼要有個網絡容器?
A: 一方面這是解耦,通過網絡容器來負責網絡配置,這樣對于業務容器來說穩定性會更高,比如在多個業務容器中,某一個業務容器斷了,這樣就不會導緻網絡中斷。
Q:Calico預設全網是打通的,怎麼做基于網段之間的隔離?
A:目前來說要做網段隔離,可能偏向安全性比較高的場景,我們目前是做私有雲場景,對隔離的要求沒那麼高。是以如果要做隔離的話,可以參考OpenStack的OVS方案。
Q:在某些應用場景下,Pod的IP需要固定,而不是重新開機之後IP可能會變化,請問如何滿足這種場景的需求?
A:Pod的IP需要固定的話,一種方式是修改Docker的代碼,據我所知騰訊有實作過。另外的方案就是做L3的代理,給Pod一個浮動IP,有點像OpenStack的實作。
Q:Ingress的流量預設是先走Service然後到Pod,還是直接到Pod?
A:取決你的實作,官方的實作是先走Sevice再到Pod,我們是直接到Pod。
Q:Ingress-Controller實作除了使用LVS和Nginx外,能否采用商用負載裝置來實作?實作是否取決于和Kubernetes API的對接?
A:可以,隻要有接口都可以實作,通過實作Ingress-Controller,比如對接F5的硬體裝置,隻要F5支援相關的API。
Q:代理入口上有哪些方法解決單點失效的問題呢?
A:這個比較傳統了,軟體實作就Keepalived之類的。
Q:Igress-Cntroller比較好的庫都有哪些,分别基于Nginx Haproxy LVS的?
A:GitHub有蠻多實作的,其實還是比較簡單的,像go語言的話,直接套用官方提供的demo即可,其他語言可以對接Kubernetes的API實作。
Q:這麼多層的網絡,多層轉發後網絡性能怎麼樣?有沒有辦法實作高速資料轉發解決方案?
A:代理層,虛拟層都會有損耗,這個就是要考慮管理成本和性能的權衡了。如何要實作高性能的話,就是要往SDN網絡研究,通過硬體層的支援來實作虛。
以上内容根據2017年07月11日晚微信群分享内容整理。分享人吳龍輝,網宿科技雲計算架構師,負責設計開發PaaS平台,《Kubernetes實戰》作者。 DockOne每周都會組織定向的技術分享,歡迎感興趣的同學加微信:liyingjiesa,進群參與,您有想聽的話題或者想分享的話題都可以給我們留言。
原文釋出時間為:2017-07-12
本文作者:吳龍輝
本文來自雲栖社群合作夥伴Dockerone.io,了解相關資訊可以關注Dockerone.io。
原文标題:DockOne微信分享(一三零):探究PaaS網絡模型設計