畢小紅,劉 淵,陳 飛
(江南大學 數字媒體學院,江蘇 無錫 214122)
目前,伴隨著云計算服務的快速發展,百度、阿里巴巴、AWS、Google等互聯網公司紛紛提供了云平臺。然而,具有不易擴展、難以維護、升級風險大等特點的日益龐大的單體應用程序,其開發正變得越來越復雜,甚至在很大程度上已經不能適應當前快速變化的市場環境。分布式微服務軟件架構模式以其模塊化、可擴展、高可用的應用能力以及其促進組織架構融合方面的優勢,可以顯著地為企業增強市場競爭力。雖然微服務架構為應用程序的開發帶來了諸多優勢[1],但是其在構建、部署、維護分布式的微服務系統方面并不容易。而容器所提供的輕量級、面向應用的虛擬化運行環境為微服務提供了理想的載體?;谌萜骷夹g的容器集群部署管理工具Kubernetes極大地簡化了容器化微服務創建、集成、部署、運維的整個流程,從而推動了微服務在云端的大規模使用。微服務由于獨立進程眾多、以容器為應用發布的載體,其架構下各組件的溝通、協調對網絡有較高的要求。目前,基于Flannel的網絡采用封包解包的NAT機制實現網絡通信,導致了一定的網絡性能消耗[2]。因此,需要研究更快速的Docker容器網絡構建方式來滿足容器集群對高帶寬通信服務的要求。
本文將Calico網絡與Kubernetes集成進行結合,建立微服務容器化應用平臺,并基于該平臺對Web微服務做進一步測試與評估。
微服務架構[3]是一項在云中部署應用和服務的新技術,其以專注于單一責任與功能的小型功能區塊為基礎,利用模塊化的方式組合出復雜的大型應用程序,各功能區塊使用與語言無關的API集相互通信。微服務采用分布式應用,應用程序按照功能被分解成一組松耦合的服務,這些程序可能運行在不同的設備上,每個服務實例一般都是一個進程。服務間的交互通過進程間的通信來實現,服務間的通信[4]意味著需要處理諸如網絡延遲、不可靠的網絡和應用層中的變化負載等相關問題。因此,保證網絡的可靠性、合理地部署微服務是有效提高微服務性能的關鍵。
Docker[5-6]是一個基于Go語言開發、遵從Apache 2.0協議、輕量級虛擬化的容器管理引擎。Docker通過Namespace實現資源隔離,由于該特征,Docker容器在運行時沒有類似于虛擬機的額外操作系統開銷,從而提高了資源利用率,并且提升了諸如IO等方面的性能。Docker具有細粒度、松耦合、可移植、輕量級虛擬化的特點,與微服務的理念相輔相成,為微服務提供匹配的實現機制,可實質性地改變新型應用的開發和發布方式。
Docker利用傳統客戶端-服務器的架構模式[7],用戶通過Docker客戶端與Docker服務器進行通信,并將請求發送給服務器Docker守護進程,Docker守護進程執行一系列的容器管理命令。Docker總架構如圖1所示。

圖1 Docker總架構
Docker使用Namespace作為網絡實現的基礎。Namespace主要提供關于網絡資源的隔離[8],包括網絡設備、IPv4和IPv6協議棧、IP路由表、防火墻等所有網絡資源[9]。在圖1中,Docker通過driver模塊創建執行環境。Libcontainer是一個獨立的容器管理包,當需要為容器創建網絡環境時,Network driver創建并配置Docker容器的網絡環境,通過Libcontainer實現對容器的具體操作。目前,Docker總架構中網絡部分已經被抽離出來,稱之為Libnetwork[9]模塊,Libnetwork定義一個容器網絡模型,提供一個一致的編程接口和應用程序網絡抽象,可以通過插件的形式給容器提供網絡功能,也可以與第三方網絡插件進行結合以滿足開發者在各種場景下的需要。Libnetwork容器網絡模型如圖2所示。其中,網絡Sandbox[10]代表容器的網絡命名空間,包含容器的完整網絡棧,不同的容器間可以完全隔離。Endpoint相當于一個容器接入網絡的虛擬網卡。Network代表一組可以直接相互通信的容器集合。宿主機上同一網絡的容器都通過Veth鏈接到該網絡命名空間上。

圖2 Libnetwork容器網絡模型
Docker從其1.9版本開始,就實現了基于Libnetwork的多主機覆蓋網絡模式[11],其中包括bridge、host、null、remote、overlay、macvlan 6種網絡驅動,bridge是Docker默認的網絡驅動,Libnetwork的remote驅動定義了基本的創建網絡、創建端口的接口,對應的REST Server實現了這些接口,并可以提供整套Docker網絡。
隨著Docker的迅速發展,越來越多的云計算廠商開始探索Docker在實際生產環境中的應用。由于Docker原生網絡功能無法滿足廣大云計算廠商的要求,因此出現了大批第三方SDN解決方案,以彌補在部署大規模Docker集群時Docker網絡性能低下、功能不足的缺陷。文獻[12]針對Kubernetes設計了一個重載網絡工具Flannel。文獻[13]開發了跨宿主機的容器網絡工具Weave和Calico跨主機網絡插件等。文獻[14]創建了一個虛擬網絡,通過在容器中添加專用的虛擬網卡來搭建自己的網絡,用以連接部署在多臺主機上的Docker容器。基于Weave網絡的容器如同被接入了同一個網絡交換機,從而在不破壞Docker容器原有網絡的同時,實現了跨主機通信。Weave能夠穿透防火墻并運行在部分連接的網絡上,此外,Weave的通信支持加密,因此,用戶可以通過一個不受信任的網絡連接到主機[15]。但是,從性能和使用角度來看,Weave也有較大的缺陷:Weave自定義容器數據包封包解包方式的傳輸效率較低,性能上的損失也較大,集群配置較復雜,需要通過Weave命令行來手工構建網絡拓撲,這在大規模集群的情況下自動化程度較低。
Flannel是由CoreOS團隊針對Kubernetes設計的一個重載網絡工具,其目的在于幫助每一個使用Kubernetes的CoreOS主機構建一個完整的子網[16]。類似于Weave、Vxlan,Flannel提供了一個可配置的虛擬覆蓋網絡。Flannel以守護進程的形式運行,負責子網的分配,使用Etcd存儲、交換網絡配置、狀態等信息,其網絡架構如圖3所示。

圖3 Flannel網絡架構
Flannel和Overlay方案均使用覆蓋網絡[17],盡管覆蓋網絡對底層網絡依賴較少,配置相對簡單,但是其網絡封裝是一種傳輸開銷,對網絡性能會有影響,不適用于對網絡性能要求較高的生產場景,且由于對底層網絡結構缺乏了解,因此覆蓋網絡無法做到真正有效地控制流量,這也會對網絡性能產生影響[18]。
Calico[19]是一個3層的數據中心網絡方案,能夠支持高效可控的虛擬機、容器、裸機間的通信,其基于BPG協議和Linux本身的路由轉發機制,不依賴特殊硬件,沒有使用NAT或Tunnel等技術。Calico沒有使用重載網絡,能夠方便地部署在物理服務器、虛擬機(如OpenStack)及容器環境下。同時,其自帶的基于Iptables的訪問控制(ACL)管理組件,能夠滿足比較復雜的安全隔離需求。Calico為每個工作負載提供一個完全自動化的虛擬防火墻,以保護工作負載,并在該工作負載受損時保護其余應用程序。Calico能夠自動將任何網絡策略概念從編排環境映射到Calico網絡環境[20]。
Calico使用與互聯網相似的原則構建其高度可擴展的網絡架構,并提供一個平面IP網絡,可以在沒有任何封裝的情況下進行通信。此外,其網絡架構還使用無狀態IP-in-IP覆蓋,可以路由已存在的覆蓋網絡數據包。基于Calico的容器網絡實現3層隔離,有效避免了ARP風暴。此外,基于Iptable/Linux內核轉發,有效提高了轉發效率,降低了性能損耗。
Kubernetes是Google開發的集群管理系統平臺,其在Docker技術的基礎上被構建出來[21],為容器化的應用提供資源調度、部署運行、服務發現、灰度升級及在線升級等一系列功能。同時,Kubernetes還提供了完善的管理工具,可以進行管理開發、測試、監控的各個環節。因此,Kubernetes能夠提供一個全新的基于容器技術的分布式架構解決方案。
Kubernetes的網絡基于Docker設計,其模型的設計遵循以下原則:每個Pod都有一個獨立的IP地址,所有的Pod都在一個可以連通的扁平網絡空間中。運行在不同的基礎設施節點上的Pod可以通過IP地址進行互相訪問。同時,在Kubernetes集群的網絡中,所有的容器都不用NAT的方式進行通信,所有節點都可以直接通信。在Kubernetes系統中,同一個Pod內的不同容器共享一個網絡命名空間,同一個Pod內的容器可以通過本機連接另一容器的端口,且可以共享部分資源,通過共享資源,容器之間的相互通信可以更高效。Google公司設計的Kubernetes主要在云環境GCE中運行,在該環境下,Kubernetes無需第三方網絡支持。但是,若脫離GCE環境運行Kubernetes與Docker集成平臺,就需要網絡插件的支持。目前,Kubernetes使用第三方支持的Flannel網絡插件實現網絡通信。
Calico網絡架構及其核心組件如圖4所示。Calico架構主要由Felix、Etcd、BGP 客戶端、BIRD(路由反射器)4個核心組件構成。Felix運行在每臺需要運行容器的節點上,負責配置路由及ACLs等信息來確保各終端的連通狀態;Etcd是分布式鍵值存儲,負責網絡元數據的一致性,確保Calico網絡狀態的準確性;BGP客戶端負責把Felix寫入內核的路由信息并分發到當前Calico網絡,確保節點間通信的有效性;BIRD(路由反射器)是在大規模部署時使用,其摒棄所有節點互聯的網格模式,通過一個或多個BIRD(路由反射器)來完成集中式的路由分發。

圖4 Calico網絡架構
Calico網絡在每一個節點利用Linux內核實現一個虛擬路由,以此負責數據的轉發,每個虛擬路由通過BGP協議將自身運行的路由信息向整個Calico網絡內傳播,較小規模的應用部署可以直接互聯,大規模應用下,可通過指定的BIRD(路由反射器)來完成通信。在Calico中,數據包有可能跨多個節點傳輸,但是無需對其中間節點進行配置。對于一個被送到容器的數據包,最后的一跳是從該容器的宿主到容器自身。此外,Calico基于Iptables還提供豐富而靈活的網絡策略,通過各個節點上的訪問控制(ACLs)來提供工作節點的多租戶隔離、安全組以及其他可達性限制等功能。
本文設計的基于Calico網絡與Kubernetes集成的網絡通信架構模型如圖5所示。其中,API是整個集群的核心,負責各個模塊之間的通信。集群內部的功能模塊通過API將信息存入Etcd,控制器、調度器通過API讀取這些信息,從而實現各模塊之間的信息交換。

圖5 基于Calico與Kubernetes的網絡通信架構
控制器作為集群內部的管理控制中心,主要負責管理Node、Pod副本、服務端點、命名空間、服務賬號、資源定額等處于預期的工作狀態。調度器的作用是實時監測集群中已調度的Pod及待調度的Pod,按照特定的調度算法和調度策略將其綁定到集群中的一個Node節點上,并將信息寫入Etcd中。Kube-proxy通過Etcd客戶端監測服務器和終端的變化,當新增服務時,服務處于監聽狀態,此時初始化Iptable規則。當新增終端endpoint時,注冊endpoint以便負載均衡器選擇。Node節點上的Kubelet周期性地向API報告自身的狀態,API接受后將信息保存到Etcd中,并監測來自File、Etcd、Http的Pod配置信息,當配置發生變化時,Kubernetes把期望狀態和當前運行狀態進行同步。在Kubernetes集群中,每個工作節點上都會運行Kubelet以守護進程,Kubelet處理Master發布給本節點的任務。并用Pause容器為每個Pod創建容器。
Calico作為Kubernetes依賴的底層網絡,在每個Node節點上構建虛擬路由,通過Calico虛擬路由可將本節點上在同一網段中的網絡報文以原始的狀態傳遞到目標容器中。該過程的實現無需如Flannel網絡的疊加網絡傳遞過程,從而可以大大降低網絡性能損耗。
本文實驗的3個操作系統為Centos 7.0虛擬機,內存1 GB,CPU 1核,主頻為2.6 GHz,IP地址分別為192.168.159.128(Kube-Master節點),192.168.159.129(Node節點),192.168.159.130(Node節點),其中,Master節點作為Kubernetes集群中的管理節點,2個Node節點作為Kubernetes集群中的工作節點。實驗采用一個可訪問的Etcd集群(192.168.159.128:2379),Calico使用其進行數據的存放和服務發現。此外,將3個節點上的Iptables INPUT策略設為ACCEPT,同時安裝Docker,并設置Docker守護進程的啟動,參數cluster-store為Etcd集群(192.168.159.128:2379)。分布式安裝并配置Kubernetes容器編排系統,設置192.168.159.128主機為Kube-Master節點,其余2個主機為Kube-Node節點。在Node節點上安裝Calico-cni插件,當Pod創建后,將該Pod添加到Calico網絡。使用Calico進行網絡的連接和IPAM的配置。代碼如下所示。
{
“name”:“my_name”,
“type”:“Calico”,
“Kubernetes”:{
“k8s_api_root”:“http://192.168.159.128:8080”
}
“IPAM”:{
“type”:“Calico-IPAM”
}
}
Calico網絡控制器運行在Kubernetes的Pod里,實現了多種網絡策略的自定義。網絡策略管理網絡的連通性。網絡策略通過Label標簽篩選作用到每個Pod和服務上,同時需要網絡插件配合實現網絡策略。
Calico節點啟動后會查詢Etcd,其他Calico節點使用BGP協議建立連接。容器啟動時,劫持相關Docker API并進行網絡初始化。查詢Etcd自動分配一個可用IP,創建一對Veth接口用于容器和主機間的通信,并在主機路由表添加指向該接口的路由。
通過上述對Calico網絡和其他各種網絡的通信原理之間的比較,以及對Kubernetes網絡原理進行的分析,理論上可以得出,基于Calico的Docker網絡具有良好的網絡性能,Calico網絡與Kubernetes的集成設計具有可行性。本文在相同的測試環境下進一步對Docker容器在跨主機通信中不同的網絡模式進行實驗測試,通過實驗分析Calico的網絡性能。
Iperf3是一種開源的網絡性能測試工具,可以測量最大TCP帶寬,此外,其具有多種參數和UDP特性,可以報告帶寬、延遲抖動和數據包丟失等數據。本文采用Iperf3測試容器帶寬以得出平均網絡傳輸速率。
3.2.1 網絡測試方案
第2節詳細敘述了Calico網絡與Kubernetes集成的實現,本節在此基礎上對該網絡的性能進行針對性的測試,同時在相同環境下將其與其他多主機容器網絡性能進行比較,構建Docker容器并測試不同容器間的通信質量。本文實驗采用帶寬性能指標來體現網絡的傳輸速率與性能,實驗測試方案如表1所示。

表1 網絡測試方案
方案的設計主要針對微服務之間的通信模式,測試其網絡速率。方案1針對單宿主機,在基于bridge、Weave、Flannel、Calico網絡模式下,容器C1作為Iperf3服務器,容器C2作為Iperf3客戶端,測試Docker容器的通信速率并進行比較。方案2測試容器跨主機通信的模式,當容器底層為overlay、Weave、Flannel、Calico與物理主機網絡時,將通信速率進行比較。通過上述測試反映出容器網絡在通信過程中的損耗。
上述方案對容器節點對進行了網絡性能比較,本文進一步從微服務應用的角度考慮,增加Node節點,并在多容器節點的環境下測試Calico網絡性能的變化。在待新增Node上部署好軟件環境,并修改Kubernetes的配置文件,指定主節點IP地址和端口號,再啟動該Node上的Kubelete和Kube-proxy服務,實現軟件環境Node節點的擴展。最后,分別在容器節點數量為2、10、20、30、40、50、60、70、80、90、100時,測試網絡速率的變化情況。
3.2.2 測試結果分析
針對表1中的2種方案進行TCP測試,多次測量容器在60 s內傳輸的數據信息量和帶寬數據,結果如圖6、圖7所示。

圖6 單宿主機不同網絡模式下的帶寬比較

圖7 跨宿主機不同網絡模式下的帶寬比較
在多節點環境下,Calico的網絡性能測試結果如圖8所示。

圖8 多節點下Calico網絡性能
本文實驗是在同一軟、硬件環境配置的基礎上進行的,由圖6可以看出,單節點情況下各種網絡的通信速率相差甚微,說明容器在同一宿主機中的網絡傳輸損耗相對較少。因此,在微服務應用的部署方式上,可以考慮盡可能地將耦合度比較高的容器應用部署在同一臺宿主機上,這樣會大大提高微服務應用的效率。由圖7可以看出,在進行跨主機通信時,基于Calico網絡容器的傳輸速率非常接近于宿主機的傳輸速率,基于Weave、Flannel、overlay網絡的容器在數據轉發速率上,相對于物理網絡損耗了約50%,其中Flannel網絡帶寬只占物理網絡的10%左右。由圖8可以看出,隨著容器節點數的增加,網絡性能有所下降,但是相對于單節點對下Flannel網絡的性能,多節點下的Calico網絡仍然具有很大的性能優勢。因此,在大規模的微服務應用部署和調度上,基于Calico網絡的容器在性能上具有明顯的優勢。
通過Docker容器的Calico網絡與Kubernetes集成構建微服務應用的PaaS平臺,本文通過設計Web微服務應用案例,進一步驗證該平臺的高可用性及強大的擴展能力。Web應用系統架構如圖9所示。

圖9 Web微服務應用系統架構
Web微服務應用系統是基于PHP+Redis 2層分布式架構的Web應用,通過Web讀寫分離的高可用集群進行部署。其中共有3個service和16個Pod節點,每個Pod中運行一個容器。主數據庫Redis Pod運行Master-Redis數據庫容器,用于Web應用進行“寫”的操作,將“寫”的內容保存在Redis-Master中;從數據庫Redis Pod運行Redis-slave容器,同時采用5個Pod構建,用于前端Web讀取數據,并與Master-Redis中數據保持同步。Frontend-Pod運行PHP Web服務,在網頁上輸入和輸出內容,同時啟動10個實例組成集群,實現客戶端對網站訪問的負載均衡。通過Kubectl客戶端命令(Kubectl scale rc-replicas=x)改變replicas參數的值來增加Pod數量,通過命令Kubectl rolling-update -f xx.yaml來升級Pod中容器,實現應用容器的可擴展,最后,創建Redis-Master服務、Redis-slave服務和php-Frontend服務。
系統實現硬件環境:采用VMware Workstation 10虛擬網卡,3臺64位的Centos 7虛擬機,內存1 GB,Intel CPU 1核,主頻為2.6 GHz。軟件環境:操作系統 Liunx/amd 64,底層網絡采用Calico v 1.0.2,高可用存儲軟件Etcd v 3.0.5,容器編排軟件Kubernetes v 1.4,Docker容器v 1.12。
通過Makefile構建所需要的Redis容器和Web頁面容器,上傳至鏡像倉庫,配置服務及副本控制器的yaml文件,利用Kubernetes創建并啟動容器。服務器通過Labels標簽選擇Pod對象實現負載均衡功能。設置NodePod參數映射物理機端口,提供服務器的對外訪問。服務器之間通過Kubernetes系統中的DNS進行注冊與發現,進而實現微服務之間的通信。系統搭建完成后,用戶通過訪問服務器地址以訪問Web系統,其中系統內部Pod之間的相互通信通過查詢服務器IP地址和端口號實現,客戶端獲得服務列表如表2所示。

表2 服務列表
利用Web壓力測試工具測試整個場景中所有請求的響應情況。在場景中每個請求都有一個響應時間,其中50%的用戶響應時間小于1 043 ms,60%的用戶響應時間小于1 147 ms,最大的響應時間小于8 785 ms。Web服務器每秒處理的請求數為87,相對基于Flannel網絡的處理請求數目(63)提高了38%。實驗結果表明,Web服務器處理并發請求時對網絡的性能具有依賴性,本文對應用部署平臺網絡性能進行了優化,提高了微服務的應用能力,同時也驗證了Kubernetes的高可用性與高效性。
本文研究基于Calico網絡的容器化應用平臺,提出實現微服務容器化應用的方案,實驗結果表明,該方案能有效提高容器跨主機網絡通信的性能,為Docker容器提供了豐富、靈活和安全的網絡策略。此外,因為Calico網絡易于部署,可擴展至數以萬計的服務器和數以百萬的工作負載,所以本文方案也為大規模分布式部署微服務應用提供了理想的網絡解決途徑。下一步將針對網絡的規模和穩定性做深入探究。
[1] 郝庭毅,吳 恒,吳國全,等.面向微服務架構的容器級彈性資源供給方法[J].計算機研究與發展,2017,54(3):597-608.
[2] RAMALHO F,NETO A.Virtualization at the network edge:a performance comparison[C]//Proceedings of 2016 IEEE International Symposium on a World of Wireless,Mobile and Multimedia Networks.Washington D.C.,USA:IEEE Press,2016:1-6.
[3] YOUSIF M.Microservices[J].IEEE Cloud Computing,2016,3(5):4-5.
[4] BALALAIE A,HEYDARNOORI A,JAMSHIDI P.Microservices architecture enables DevOps:migration to a cloud-native architecture[J].IEEE Software,2016,33(3):42-52.
[5] 王 鵑,胡 威,張雨菡,等.基于Docker的可信容器[J].武漢大學學報(理學版),2017,63(2):15-25.
[6] BERNSTEIN D.Containers and cloud:from LXC to docker to Kubernetes[J].IEEE Cloud Computing,2014,1(3):81-84.
[7] 楊 鵬,馬志程,彭 博,等.集成Docker容器的OpenStack云平臺性能研究[J].計算機工程,2017,43(8):26-31.
[8] 齊 勇.基于docker的網絡服務質量控制器的設計與實現[D].濟南:山東大學,2015.
[9] Docker container networking[EB/OL].[2017-05-10].https://docs.docker.com/ engine/userguide/networking/.
[10] EDELMAN J.Docker networking[EB/OL].[2017-04-25].http://www.dasblinkenlichten.com/docker-networking-101-hostmode/.
[11] XIE Bin,SUN Guanyi,GUO Ma.Docker based overlay network performance evaluation in large scale streaming system[C]//Proceedings of 2016 IEEE Conference on Advanced Information Management,Communicates,Electronic and Automation Control.Washington D.C.,USA:IEEE Press,2016:366-369.
[12] 龔 正,吳治輝,葉伙榮,等.Kubernetes權威指南[M].北京:電子工業出版社,2016.
[13] Google.Calico documentation[EB/OL].[2017-05-10].http://docs.projectcalico.org/v2.0/introduction/.
[14] 馮明振.基于macvlan的Docker容器網絡系統的設計與實現[D].杭州:浙江大學,2016.
[15] 王亞玲,李春陽,崔 蔚,等.基于Docker的PaaS平臺建設[J].計算機系統應用,2016,25(3):72-77.
[16] DUSIA A,YANG Y,TAUFER M.Network quality of service in Docker containers[C]//Proceedings of 2015 IEEE International Conference on Cluster Computing.Washington D.C.,USA:IEEE Press,2015:527-528.
[17] 何震葦,嚴麗云,李慧云.基于開源PaaS技術的互聯網業務平臺自動部署方案[J].電信科學,2015,31(10):172-179.
[18] JARAMILLO D,NGUYEN D V,SMART R.Leveraging microservices architecture by using Docker technology[J].IEEE SoutheastCon,2016,16(5):1-5.
[19] CALINCIUC A,SPOIALA C C,TURCU C O,et al.OpenStack and Docker:building a high-performance IaaS platform for interactive social media applications[C]//Proceedings of 2016 International Conference on Develop-ment and Application Systems.Washington D.C.,USA:IEEE Press,2016:287-290.
[20] Google.Network policies[EB/OL].[2017-05-10].http://Kubernetes.kansea.com/docs/user-guide/networkpolicies.
[21] MEDEL V,RANA O,BAARESJ,et al.Adaptive appli-cation scheduling under interference in Kubernetes[C]//Proceedings of the 9th IEEE/ACM International Conference on Utility and Cloud Computing.Washington D.C.,USA:IEEE Press,2016:426-427.