探究PaaS網絡模型設計

【編者的話】PaaS的抽象邏輯使得其網絡模型與IaaS有所不一樣,本次經過重點說明Kubernetes和Docker的網絡,從而來探究PaaS的網絡模型設計。docker

【3 天燒腦式容器存儲網絡訓練營 | 深圳站】本次培訓以容器存儲和網絡爲主題,包括:Docker Plugin、Docker storage driver、Docker Volume Pulgin、Kubernetes Storage機制、容器網絡實現原理和模型、Docker網絡實現、網絡插件、Calico、Contiv Netplugin、開源企業級鏡像倉庫Harbor原理及實現等。安全

PaaS和IaaS的網絡需求

概念上來講,IaaS是基礎架構即服務,PaaS是平臺即服務。從服務化角度來講二者對於網絡的需求有共同點:微信

  1. 一臺宿主機的網絡隔離,一臺宿主機要運行多個環境黑盒(VM或者容器),這時候每一個環境黑盒的網絡須要隔離。
  2. 環境變動後的訪問一致性,好比VM或者容器遷移到其餘宿主機的時候,如何保證外部訪問不感知,比較通用的解決方案網絡代理層來解決。

實現上來講,IaaS是VM管理,PaaS是容器編排,二者的網絡也會有些不一樣:網絡

  1. 容器比VM輕量級,啓停更快,更方便遷移,因此PaaS的整個調度策略會更靈活,容器的遷移頻率是高於VM,當容器遷移的時候,PaaS須要更加快速的解決變化後的網絡訪問。
  2. VM安全高於容器,IaaS這部分會更多在隔離和安全上有所考慮,固然這個多是公有云和私有云的一個定位,我的認爲IaaS比較適合公有云,PaaS比較適合私有云。

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的網絡結構有:

  1. 物理網絡
  2. 虛擬層網絡
  3. 代理層網絡

Kubernetes和Docker的網絡說明

Kubernete Docker做爲目前最流行的開源PaaS實現,經過其實現細節能夠更加理解PaaS的網絡模型實踐。

容器網絡

Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0),Docker啓動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,稱爲Container-IP,同時Docker網橋是每一個容器的默認網關。由於在同一宿主機內的容器都接入同一個網橋,這樣容器之間就可以經過容器的Container-IP直接通訊。


Docker網橋是宿主機虛擬出來的,並非真實存在的網絡設備,外部網絡是沒法尋址到的,這也意味着外部網絡沒法經過直接Container-IP訪問到容器。

Pod內部容器通訊

Kubernetes中Pod是容器的集合,Pod包含的容器都運行在同一個宿主機上,這些容器將擁有一樣的網絡空間,容器之間可以互相通訊,它們可以在本地訪問其餘容器的端口。

實際上Pod都包含一個網絡容器,它不作任何事情,只是用來接管Pod的網絡,業務容器經過加入網絡容器的網絡從而實現網絡共享。

Pod的啓動方式相似於:
$ docker run -p 80:80 --name network-container -d <network-container-image> $ docker run --net container:network-container -d <image>
因此Pod的網絡實際上就是Pod中網絡容器的網絡,因此每每就能夠認爲Pod網絡就是容器網絡,在理解Kubernetes網絡的時候這是必需要須要清楚的,好比說Pod的Pod-IP就是網絡容器的Container-IP。

Pod間通訊

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

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,進羣參與,您有想聽的話題或者想分享的話題均可以給咱們留言。

相關文章
相關標籤/搜索