雷 擎
(對外經濟貿易大學信息學院,北京 100029)
隨著云計算的發展,微服務架構的優勢使其逐漸成為云服務提供商普遍采用的軟件體系結構。微服務對其構成的云應用程序進行的細粒度控制,縮短了將新功能投入運營的時間,已被諸如Facebook、LinkedIn和Amazon之類的大型Web公司廣泛使用。微服務通過基于虛擬機VM或基于容器虛擬化的基礎架構技術,可以提供高度的可伸縮性、可用性和可移植性。但是,由于基于微服務的部署更具動態性和易變性,架構和部署方式不同于傳統應用程序,也給系統監測和性能建模帶來了新的挑戰。
與傳統軟件架構相比,微服務具有更高的發布頻率和速度,在運營環境中進行廣泛性能測試的可行性受到限制,所以基于單體服務器的性能評估和傳統軟件測試的性能評估都不完全適合于微服務[1]。通過對微服務和云測試領域已發表的論文研究發現,學者們研究的成果集中在云應用程序建模、構建和服務方面,對云服務性能測試研究較少,大多數與微服務的性能測試沒有直接關系。對于微服務性能測試方面的研究,包括測試方法、測試工具、基準測試以及評價標準和機制都還處于探索階段。
針對微服務的服務特性,本文借鑒Web服務質量的測試方法和評價標準,基于Kubernetes平臺對微服務的虛擬化平臺和架構性能進行測試研究。在實驗過程中采用了新的仿真工具Kubemark,通過Kubemark在Kubernets上部署集群,使用從運營數據中提取出的負載模型加載仿真負荷,測試不斷增加的負載或突然的負載峰值是否可能會違反Kubernetes的服務級別目標SLO(Service Level Objectives),測試不同類型的微服務負載會對系統資源產生的性能影響,是對微服務性能測試方法、工具和評價標準的一種嘗試和探索。
通過對國內外微服務研究領域的研究成果進行對比,本文發現雖然有一些學者對于微服務安全性、可用性和系統性能進行了研究,但研究的重點主要集中在體系結構方面[2]。
國外的學者對于微服務性能方面的研究主要從2個角度展開:一是從集群硬件平臺角度,在微服務體系結構下,分別直接加載CPU的基準測試、網絡性能基準測試,收集CPU利用率、內存訪問延遲、網絡帶寬和延遲以及存儲開銷等數據,使用硬件的性能指標來衡量微服務平臺的性能[3,4];另一方面是基于AWS Lambda、Microsoft Azure等商業的云平臺,通過API加載負荷,測試虛擬機和容器的啟動運行時間、狀態轉換、負載能力等來評估不同微服務架構的虛擬平臺性能[5,6]。另外,有一些學者在云計算的虛擬化技術之間的性能比較領域做了大量工作,例如對于同樣的基準測試,測試KVM、Docker、LXC和CoreOs Rocket等對于系統硬件性能的差異[7]。這些研究成果也可以從側面反映采用不同虛擬化技術的系統中,微服務可能呈現的性能。
國內的學者對于微服務的研究主要集中在應用方面,對于云平臺性能的研究在2015年已經有學者涉及[8],在輕量虛擬化技術之間的性能對比,以及虛擬機和容器技術的性能方面,國內學者已經開始有所關注[9 - 11]。但是,有關這些問題研究的方法、深度和熱度,與國外的研究相比還有很大的距離。有關微服務性能和測試方面的研究,也還沒有搜索到相關的學術論文。
從國內外的研究來看,目前微服務性能測試的研究與用戶所獲得服務的性能和質量都沒有直接關系,也缺少基于Kubernetes平臺的性能研究。由于在微服務架構中,每個微服務都實現自己的功能,并通過與語言和平臺無關的API與其他微服務進行通信,微服務的資源使用量取決于所實現的功能和工作負載,因此本文借鑒Web服務性能評估方法,直接測試微服務的吞吐量、請求成功率、響應時間分布等性能指標來進行微服務系統性能評估,是一個有意義的嘗試。
云計算的2個關鍵技術——資源管理中的隔離技術和控制技術,是云計算根據消費者需求動態分配和重新分配不同的物理和虛擬資源的基礎,從而能夠實現云計算的多負載、高并行管理和運行。資源隔離是指一項工作負載的執行不能影響同一系統上另一工作負載的執行要求。資源控制是指將工作負載限制為一組特定資源的能力。目前云資源管理主要基于2種技術:虛擬機和容器。研究人員發現,基于以Docker為代表的容器化帶來的開銷更少,與基于虛擬機管理程序的云相比,具有更好的資源控制能力,可以獲得更好的應用程序性能。但是,微服務使用容器技術以Docker模式進行部署,隔離性也相對較差,如果需要很高的安全性,就必須通過犧牲純容器部署的性能來獲得更多可靠的隔離。
Kubernetes是一個開源的容器編排系統,基本工作單元稱為Pod。每一個Pod都擁有其自己的唯一IP地址,可以與集群中的任何其他Pod相互訪問。Kubernetes將一個或多個容器部署在Pod中,在靈活性和隔離性上有更多的優勢[12]。
Kubernetes高層架構由控制組件和監測組件組成。 控制組件保持整個系統功能一致性,監測組件負責計算系統資源的使用情況,收集指標,監視整個系統的運行狀況,如圖1所示。

Figure 1 Kubernetes architecture圖1 Kubernetes體系機構
(1)控制組件。
控制組件主要包含7個組件。其中Apiserver是Kubernetes控制平面的前端,即主服務器上提供Kubernetes API服務的組件。 Kubectl提供針對Kubernetes集群運行命令的命令行界面。 etcd實現一致且高度可用的鍵值存儲,用作所有集群數據的Kubernetes后備存儲。 Scheduler是主服務器上的組件,用于監視未分配節點的新Pod,并選擇一個要在其上運行的節點。 Controller-Manager是主機上的運行控制器。 從邏輯上講,每個控制器是一個單獨的進程,但是為了降低復雜性,它們都被編譯為單個二進制文件并在一個進程中運行。 Kubelet是集群中每個節點上運行的代理,管理并確保容器正常運行。Kube-Proxy組件通過在主機上維護網絡規則并執行連接轉發來啟用Kubernetes服務。
(2)監測組件。
監測組件主要包含2個組件。其中cAdvisor是專門為容器而構建的,是開源容器資源使用和性能分析代理,支持Docker容器。在Kubernetes中,cAdvisor已集成到Kubelet二進制文件中。cAdvisor會自動發現計算機中的所有容器,并收集CPU、內存、文件系統和網絡使用情況統計信息。cAdvisor還可以通過分析計算機上的“root”容器來提供整個計算機的使用情況。Heapster是Kubernetes 1.0.6及更高版本兼容的性能監視和指標收集系統,不僅可以收集有關系統的工作負載,Pod和容器的性能指標,還可以收集群集生成的事件和其他信號。Heapster完全開源,并且支持多種用于持久存儲數據的后端。
本文采用Kubemark模擬集群測試工具來實現微服務性能測試的研究。Kubemark是Kubernetes的一個獨立模塊,可以用于構建Kubernetes的模擬測試集群,進行Kubernetes上微服務的性能測試[13]。
在頂層設計上,Kubemark集群由2部分組成(如圖2所示):一個真實的控制節點(Kubemark Master Node)和由一組“虛擬(Hollow)”節點構成的模擬集群(External Cluster)。其中任何加前綴“虛擬(Hollow)”的組件都是實際組件對應的模擬組件,內部使用其真實核心代碼實現。例如Kubelet的對應模擬組件是HollowKubelet。Kubemark使用這些模擬組件創建仿真測試集群,從而確保了模擬性能測試程序的可維護性。模擬集群建立在真實的Kubernetes集群之上,用每一個真實的Pod可以作為模擬集群中一個工作節點(HollowNode),其中運行模擬組件HollowKubelet、HollowProxy和HollowNodeProblemDetector。因此,單個真實節點能夠運行多套Kubelet和Kube-Proxy程序集來模擬多個節點。到Kubernetes v1.6為止,Kubemark可以支持5 000個節點的集群規模。實際上,Kubernetes所有基準測試是基于Kubemark構建的模擬集群,而不需要構建數千個真實節點。

Figure 2 Kubemark architecture圖2 Kubemark體系結構
通過Kubemark性能測試工具,本文可以使用較少的硬件資源構建大型的Kubernetes模擬集群,配置模擬集群的應用測試數據集,在模擬的Kubernetes集群上運行端到端測試e2e(End-to-End),獲得集群的性能指標。Kubemark集群的測試數據雖然與真實集群略有不同,但可以代表真實集群的數據。因此,Kubemark可用于直接在真實集群上運行端到端測試,作為對真實集群執行性能測試的方案。
云平臺的用戶通常通過Internet從Web瀏覽器訪問自己訂制的資源(例如數據、軟硬件資源或第三方服務),并且通過與云服務提供商所簽定的合同,即服務級別協議SLA(Service-Level Agreement),來為使用的計算機資源和服務付費。SLA規定了服務提供商在給定價格必須提供的服務質量QoS(Quality of Service),包括服務時間段、服務響應時間和吞吐量等。服務性能QoS的要求一般體現為服務響應時間和吞吐量。與吞吐量相比,Web客戶更直接的體驗通常是服務響應時間。例如,點擊一個鏈接,看到響應頁面的時間的長短會讓用戶對Web服務的質量有更加直觀的感覺。
因此,本文在測試中對微服務的性能進行度量的標準采用RFC 2679和IETF RFC5166定義的p百分位數,也就是在服務響應時間某界限內的服務請求所占總量的百分比,又稱為百分位數延遲。這個標準在服務和網絡性能研究中已經被研究人員廣泛采用[14,15]。假定fT(t)是響應時間T的概率分布函數。TD是客戶根據客戶支付的費用請求,并與其服務提供商達成一致的期望目標響應時間,則保證SLA服務性能指標的公式為:

(1)
其中,客戶在不到TD的時間得到服務響應的服務請求,至少占所有請求總數的γ%,這個性能指標就稱為p百分位數。通過這個性能指標,客戶可以統計服務的QoS是否達到服務商承諾的標準;另一方面,服務商可以通過這個指標進行反向計算,來測量系統提供各種不同服務的性能差異,以及整個系統所提供的總體服務性能和業務可擴展尺度。
SLA中具體定義服務響應時間的是服務級別目標SLOs,使用Kubernetes定義的服務性能標準如表1所示。

Table 1 SLOs for service response time
在實驗中,通過Kubemark的監測代理獲取每個服務請求所發出的請求時間和響應資源時間,然后對占所有請求總數分別在50%,90%和99%時,對這些服務請求的響應時間界限進行統計,以此來測度系統提供各種不同微服務的性能差異,以及在系統微服務負載逐步增加時,Kubernetes中各種資源響應的情況,測度不同微服務對于系統性能的壓力和影響情況。
性能測試是為了獲得系統在某種特定的條件下(包括特定的負載條件下)的性能指標數據。本文測試方案包括密度測試(Density Testing)和負載測試(Load Testing)。密度測試是測試一個節點支持不同數量Pod時的各項性能指標。通過密度測試,可以選擇單節點最佳的Pod配置數量。負載測試是在系統上模擬實際用戶負載的過程,檢測微服務及其系統在正常和高負載期間的行為。
本文實驗基于Kubernetes,采用集群模擬工具Kubemark作為測試工具,使用腳本語言創建一個包含100個節點的模擬測試集群,模擬測試集群平均節點密度采用每個節點設置30個Pods,如表2所示。測試中,采用端到端測試策略加載數據,測試Kubernetes通過REST over HTTP提供的系統級微服務性能。

Table 2 Simulation cluster configuration
測試的數據根據端到端腳本設計測試任務加載,測試包括POST、PUT、DELETE、PATCH和GET等各種API請求對系統資源操作時,Kubernetes所提供的微服務性能,具體的各種API的請求數量不定。在測試時,針對每一個API請求,采集在處理這個請求時所使用到的各種系統資源響應時間數據。例如,采集Kubernetes平臺響應POST請求所需要的endpoints、pods、nodes等資源信息,獲取其服務響應時間數據。由于各種API請求使用的系統資源有很大部分相同,例如pods、namespaces等,表3中間一列列出了測試中所有的資源對象,對應于表3中左邊一列所有的API操作。具體每一種API操作對于系統資源的使用,在后續有具體圖表說明。例如,向Kubernetes平臺POST其定義的資源endpoints,獲取其服務響應時間數據。資源具體的測試動作和所操作的資源對象如表3所示。

Table 3 Tests tasks and resource objects
在測試過程中,主要采集API調用的服務響應延遲和Pod啟動時間數據,選取微服務的關鍵SLI(Service Level Indicator)服務請求延遲,獲取指標在百分位為50,90和99時的數據值作為測試結果數據。
(1)密度測試。
本文進行的密度測試是測試集群Pod創建后進行調度,然后配置到每個節點上,最后成功啟動所耗費的時間。測試過程中,每個節點將從無到有完成30個Pods配置啟動,對于模擬測試集群的100個節點,將有3 000個Pods需要創建、調度、運行并啟動。圖3中展示了在測試過程中50%,90%,99%和100%的Pods成功啟動時所耗費的時間延遲,并通過堆積圖顯示了啟動過程中各階段所耗費的時間延遲。通過這個測試可以看出,在系統微服務負載逐步增加時,總體上對微服務性能的影響,通過Kubernetes中各種資源響應的情況(如Pod)可以看出,不同微服務對于系統性能的壓力和影響情況,限于篇幅本文只給出了對于GET和LIST微服務各種系統資源的響應時間。

Figure 3 Delay of each stage of Pod startup in Density Testing圖3 密度測試中Pod完成啟動的各階段延時
在完成所有Pods啟動過程中,平臺也同時模擬用戶發出微服務請求,通過DELETE、GET、LIST、PATCH、POST和PUT對所有的資源進行操作。其中對Pods進行操作的各種服務請求響應時間延遲如圖4所示。圖4中分別給出了50%,90%和99%的請求被成功響應的時間延遲。

Figure 4 Microservice performance for Pod operations in Density Testing圖4 密度測試中對Pod操作的微服務性能
表3中其他資源的操作性能,在測試中都有相應的性能數據產生,本文選取了GET和LIST微服務請求作為示例,分別給出了50%,90%和99%的請求被成功響應的時間延遲,如圖5和圖6所示。圖中的x軸是操作的資源對象,標識是參照表3的資源對象縮寫。

Figure 5 Request response delay for GET requests in Density Testing圖5 密度測試中GET請求的請求響應延遲

Figure 6 Request response delay of LIST request in Density Testing圖6 密度測試中LIST請求的請求響應延遲
(2)負載測試。
負載測試通常是根據預期的客戶行為和系統日常狀態對系統運行時負荷、狀態和用戶服務請求進行建模。負載測試中通過向系統加載模擬的負荷和服務請求,查驗系統中各種資源的使用狀況和響應時間,從而衡量系統的服務質量(QoS)性能,以及確定系統在正常和預期峰值負載條件下的行為。一般情況下,在允許軟件系統上線之前,都需要在與生產環境相同的測試環境中進行負載和性能測試。如果系統或服務受服務級別協議或SLA約束,則負載測試尤為重要。
本文使用Kubemark建立了Kubernetes平臺日常運行模型,通過端到端測試模式模擬用戶行為加載了對各種系統資源操作的微服務請求,具體的操作請求和系統資源如表3所示。在測試過程中系統提供各種不同微服務的性能差異,本文實驗收集了DELETE、GET、LIST、PATCH、POST和PUT等對表3中所有資源進行操作服務請求的相關數據,分析所有這些統計數據并生成負載測試報告,從這些報告中可以看出各種不同微服務的性能差異。本節選取具有代表性的數據作為示例進行分析,包括資源Pod的各種操作請求的響應時間延遲(如圖7所示)、GET、LIST微服務請求的響應時間延遲(如圖8和圖9所示)。

Figure 7 Performance of microservice for Pod operations in Load Testing圖7 負載測試中對Pod操作的微服務性能
從圖7可以看出,在對Pod的操作提供服務時,90%的GET、LIST、PATCH、POST和PUT請求可以在5 000 ms內得到響應,其中50%的服務請求得到響應的延遲時間是另40%的一半左右,而剩余的9%請求,需要比90%的請求耗費多1~3倍的時間才能得到響應。相比較而言,對Pod的DELETE操作請求與其他操作的區別比較明顯,它耗費12 000 ms左右才能完成90%的請求響應,這比其他操作的多1~2倍的時間。但總體上說,這些服務響應時間都遠遠小于1 s,符合Kubernetes所定義的SLOs,即99%的API調用在1 s內響應。
圖8和圖9分別給出了GET和LIST對各種資源的操作請求的響應時間,包括成功地響應50%,90%和99%請求的時間延遲。圖中的x軸是操作的資源對象,標識是參照表3的資源對象縮寫。其中PATCH、POST和PUT請求呈現的數據形態與圖8的GET相似。

Figure 8 Request response delay for GET request in Load Testing圖8 負載測試中GET請求的請求響應延遲

Figure 9 Request response delay of LIST request in Load Testing圖9 負載測試中LIST請求的請求響應延遲
本文使用集群仿真工具Kubemark創建了100個節點Kubernetes集群,選擇端到端(End-to-End)的測試策略對Kubernetes所提供的微服務性能進行測試,并給出了集群微服務的性能分析。實驗結果表明,通過模擬真實平臺的運行狀況,仿真測試能夠給出集群資源的利用狀態和對資源操作的相關性能指標。仿真測試是云平臺微服務性能測試的有效研究方法。通過仿真測試可以規避在真實云平臺微服務性能測試所面臨的運營、成本、規模、安全、測試數據等問題。如果在生產環境中出現了系統可用性問題,可以通過對運營時的負載特點進行仿真實驗來解決,或者通過仿真實驗來發現生產環境中有可能存在的致命問題。