崔華 樓奕華 狄坤 王海



DOI:10.19850/j.cnki.2096-4706.2024.02.016
收稿日期:2023-09-08
摘? 要:微服務(wù)框架主要有客戶端負載均衡和服務(wù)端負載均衡兩類設(shè)計模式。文章提出一種基于Kubernetes的輕量級PaaS微服務(wù)框架,框架采用服務(wù)端負載均衡模式,設(shè)計了自定義的ServiceRoute對象來描述服務(wù)路由需求,以ServiceRoute對象的變化來增刪服務(wù)訪問點,基于對服務(wù)訪問點的DNS名稱解析實現(xiàn)服務(wù)尋址,采用經(jīng)LUA擴展的HAProxy實現(xiàn)服務(wù)路由和服務(wù)治理。框架采用標準的HTTP協(xié)議,架構(gòu)簡單清晰、組件實施方便、對應(yīng)用無侵入,測試結(jié)果表明,該微服務(wù)框架工作穩(wěn)定、性能良好,可為受限環(huán)境下部署微服務(wù)系統(tǒng)提供一種合適的解決方案。
關(guān)鍵詞:微服務(wù);PaaS;Kubernetes;負載均衡;服務(wù)尋址;服務(wù)治理
中圖分類號:TP311? 文獻標識碼:A? 文章編號:2096-4706(2024)02-0070-06
A Lightweight PaaS Microservice Framework Based on Kubernetes
CUI Hua1, LOU Yihua1,2, DI Kun1,2, WANG Hai1,2
(1.Travelsky Technology Co., Ltd., Beijing? 101318, China;
2.Beijing Civil Aviation Bigdata Engineering Research Center, Beijing? 101318, China)
Abstract: There are two main design patterns for microservices frameworks: client-side load balancing and server-side load balancing. This paper proposes a lightweight PaaS microservice framework based on Kubernetes. The framework adopts a server-side load balancing mode, designs a custom ServiceRoute object to describe service routing requirements, adds or removes service access points based on changes in the ServiceRoute object, implements service addressing based on DNS name resolution of service access points, and implements service routing and governance using LUA extended HAProxy. The framework adopts the standard HTTP protocol, with a simple and clear architecture, convenient component implementation, and non-invasive application. Test results show that the microservices framework works stably and performs well, providing a suitable solution for deploying microservices systems in restricted environments.
Keywords: microservice; PaaS; Kubernetes; load balance; service addressing; service governance
0? 引? 言
傳統(tǒng)的業(yè)務(wù)系統(tǒng)通常為單架構(gòu),然而隨著業(yè)務(wù)增長引發(fā)的可擴展性需求逐漸緊迫,單體應(yīng)用的局限性愈發(fā)明顯,因此近年來業(yè)務(wù)系統(tǒng)逐步向微服務(wù)模式進行轉(zhuǎn)變。和單體架構(gòu)不同,微服務(wù)架構(gòu)是由一系列職責(zé)單一的細粒度服務(wù)構(gòu)成的分布式網(wǎng)絡(luò),服務(wù)間通過微服務(wù)框架的路由機制進行通信。
主流的微服務(wù)框架通常有兩類設(shè)計模式[1]:一類是以SpringCloud [2]、Istio [3]為代表的主流微服務(wù)框架所采用的客戶端負載均衡模式,即服務(wù)網(wǎng)格[4],在這種模式下每個微服務(wù)都有一個開放的端口,請求方通過構(gòu)建服務(wù)名和端口的映射關(guān)系表可以直接向微服務(wù)對應(yīng)的實例發(fā)送請求;另一類則是服務(wù)端負載均衡模式[5],在這種模式下,請求方并不直接與微服務(wù)的實例通信,而是先將請求發(fā)送給統(tǒng)一的微服務(wù)路由組件,再由該組件負責(zé)向?qū)嶋H的微服務(wù)實例轉(zhuǎn)發(fā)請求。
一般而言,客戶端負載均衡模式由于采用了服務(wù)間直接通信的方式,具有跳數(shù)少、故障點少的優(yōu)勢,但通常要求需要使用方進行代碼級適配;而服務(wù)端負載均衡模式由于采用了增加路由節(jié)點轉(zhuǎn)發(fā)請求的模式,一般不需要使用方進行特殊適配,但增長了調(diào)用鏈路、增加了故障點。兩類微服務(wù)設(shè)計模式雖各有優(yōu)劣,但隨著系統(tǒng)復(fù)雜度的提升,尤其是微服務(wù)數(shù)量的增長,在客戶端負載均衡模式下所有請求方都會面臨著維護大量微服務(wù)配置與映射關(guān)系的壓力。為此,本文提出了一種采用服務(wù)端負載均衡模式的基于Kubernetes[6]的輕量級PaaS微服務(wù)框架,采用基于Kubernetes原生名字解析[7]的服務(wù)尋址機制和基于HAProxy[8]的服務(wù)路由機制,可滿足受限環(huán)境下客戶端無修改接入微服務(wù)框架的需求。
1 系統(tǒng)設(shè)計
1.1? 系統(tǒng)設(shè)計方案與組成
本文提出的基于Kubernetes的輕量級PaaS微服務(wù)框架,所有的組件都運行于同一個Kubernetes集群中,其整體的邏輯架構(gòu)如圖1所示。
系統(tǒng)具體包含如下組件:
API Server:負責(zé)管理微服務(wù)框架在Kubernetes中注冊的ServiceRoute自定義資源對象,具體實現(xiàn)時既可以采用自定義擴展APIServer的方式,也可以將ServiceRoute對象作為CustomResourceDefinition注冊到集群中,由Kubernetes原生的APIServer承擔(dān)此功能;
服務(wù)路由組件:負責(zé)根據(jù)配置好的策略將調(diào)用方發(fā)起的服務(wù)調(diào)用請求轉(zhuǎn)發(fā)給相應(yīng)服務(wù)版本的某個實例Pod,在服務(wù)路由組件的每個實例中,都會運行一個負責(zé)本實例策略配置更新的主進程和一個負責(zé)請求轉(zhuǎn)發(fā)的HAProxy進程。
控制組件:負責(zé)根據(jù)ServiceRoute對象的定義,在集群中創(chuàng)建/修改/刪除與此對象關(guān)聯(lián)的Kubernetes原生的Service對象。
與Kubernetes原生的服務(wù)路由機制[9]相比,由于Kubernetes原生的服務(wù)路由機制是通過直接訪問的(Service IP, Service Port)并依賴NAT[10]技術(shù)實現(xiàn)(Service IP, Service Port) -> (Pod IP, PodPort)的映射,故服務(wù)調(diào)用僅能實現(xiàn)簡單的4層負載均衡。而本文提出的方案由于增加了HAProxy作為服務(wù)路由組件,可在實現(xiàn)4層負載均衡的基礎(chǔ)上進一步做到7層負載均衡及更多的服務(wù)治理能力(如熔斷、多版本灰度等)。
1.2? 實現(xiàn)原理
1.2.1? 服務(wù)尋址原理
在本文所述的微服務(wù)框架中,每一個服務(wù)的不同版本都有一個對應(yīng)的Service對象存在于Kubernetes集群中。為了能夠使用統(tǒng)一的訪問點訪問服務(wù),并支持通過自定義的規(guī)則進行版本選擇和服務(wù)治理,微服務(wù)框架使用了自定義的ServiceRoute資源對象用于保存這些規(guī)則。微服務(wù)框架的控制組件會采用List & Watch機制跟蹤監(jiān)視集群中所有ServiceRoute資源對象的變化。在一個ServiceRoute資源對象創(chuàng)建后,控制組件就會根據(jù)此ServiceRoute資源對象的描述,在指定的Namespace中創(chuàng)建一個與該資源對象同名的、用作服務(wù)訪問入口點的Service對象。該Service對象的類型為ExternalName,其指向的是一個位于特定Namespace中的Service對象,該Service對象代表了一個服務(wù)于本Namespace的服務(wù)路由組件。
當(dāng)調(diào)用方通過目標服務(wù)的服務(wù)名發(fā)起HTTP調(diào)用請求時,首先需要對服務(wù)名進行地址解析,微服務(wù)框架通過在合適的名稱空間中創(chuàng)建與服務(wù)名同名的別名服務(wù)方式,巧妙地將對服務(wù)名的域名解析最終轉(zhuǎn)換成為對某個服務(wù)路由組件IP地址的解析。一次具體的服務(wù)尋址流程如圖2所示。
由于在服務(wù)尋址的過程中,服務(wù)名的DNS解析需要交由Kubernetes集群來執(zhí)行,因此其命名規(guī)則對尋址結(jié)果會產(chǎn)生影響。理論上說,在執(zhí)行服務(wù)調(diào)用時,調(diào)用方可以在<服務(wù)名>和<服務(wù)名>.
1.2.2? 服務(wù)路由原理
調(diào)用方在獲取到服務(wù)路由組件的IP地址后,就可以構(gòu)造HTTP請求發(fā)送到該IP地址。由于該IP地址為Kubernetes中的ServiceIP,因此該請求會經(jīng)過集群節(jié)點上的IPTables的NAT映射后轉(zhuǎn)換為服務(wù)路由組件的某個實例Pod的IP,并由操作系統(tǒng)路由于對應(yīng)的Pod中。在請求在到達Pod后,該請求會進入已在Pod中運行且偵聽了當(dāng)前端口的HAProxy進程中,由HAProxy根據(jù)灰度配置及請求信息為請求選擇一個合適的目標服務(wù)版本(HAProxy的配置由服務(wù)路由組件的主進程偵聽其所負責(zé)的Namespace中所有ServiceRoute對象的變更后動態(tài)生成并更新),并經(jīng)負載均衡策略將該請求最終轉(zhuǎn)發(fā)給該具體版本的某個Pod,這一過程的實例如圖3所示。
1.2.3? 服務(wù)治理原理
由于微服務(wù)框架引入了HAProxy作為服務(wù)路由的轉(zhuǎn)發(fā)核心,因此服務(wù)路由組件可充分利用HAProxy的能力實現(xiàn)對服務(wù)的7層治理,包括但不限于:
多版本治理:在由Service Router生成的HAProxy配置中,每個服務(wù)的具體版本實例對應(yīng)于HAProxy配置的一個后端,因此某一個特定的HTTP訪問點可能會對應(yīng)一個后端(單版本情形)或多個后端(多版本情形),在后一種情況下,微服務(wù)框架通過嵌入在HAProxy配置文件中的LUA腳本解析每一個HTTP請求頭,并根據(jù)請求頭中的字段或者規(guī)定的百分比為該請求選擇一個后端。如果找不到合適的后端用于處理,則會將請求路由到一個特定的后端,該后端會直接向客戶端返回錯誤碼503。
熔斷治理:在微服務(wù)框架中,可以為服務(wù)的每一個版本實例都配置熔斷規(guī)則,指定在什么樣的條件下對該版本實例的訪問會被拒絕。熔斷的實現(xiàn)是通過在HAProxy的后端中通過LUA腳本增加了一組統(tǒng)計規(guī)則,當(dāng)一定時間窗口內(nèi)的統(tǒng)計結(jié)果符合預(yù)先配置的熔斷閾值時,后續(xù)一段時間內(nèi)所有路由到該后端的請求都會被直接拒絕而不轉(zhuǎn)發(fā)。
訪問授權(quán)治理:微服務(wù)框架允許為每個可被調(diào)用的服務(wù)設(shè)置訪問授權(quán)規(guī)則,并要求每個調(diào)用請求中攜帶一個特定的HTTP請求頭,其中包含一串可以在容器中獲得的、用于標識調(diào)用方身份的隨機串碼。在該請求到達HAProxy時,其中的LUA腳本會將該串碼與預(yù)先生成的黑白名單列表進行匹配,并阻止那些根據(jù)規(guī)則不得發(fā)起調(diào)用的請求。
基于HAProxy實現(xiàn)服務(wù)治理的原理如圖4所示,其核心在于通過在HAProxy的配置文件置入包含了治理規(guī)則的LUA腳本,使這些LUA腳本在Backend選擇、Server選擇等HAProxy請求轉(zhuǎn)發(fā)過程的重要節(jié)點中得到執(zhí)行,從而達到根據(jù)請求特征實現(xiàn)服務(wù)治理的目的。
1.3? 實施方式
本文提出的微服務(wù)框架實施方式包括:制定一個可用于描述服務(wù)路由規(guī)則的ServiceRoute資源對象,提供一個可管理該資源對象的APIServer(可選),實現(xiàn)一個可偵聽該資源對象變化并制作相應(yīng)動作的控制器,為每一個需要加入微服務(wù)框架的Namespace部署一組服務(wù)路由器。
ServiceRoute資源對象的定義如下:
apiVersion: paas.io/v1
kind: ServiceRoute
metadata:
name: <名字,必須>
namespace: <命名空間(項目名),必須>
spec:
rule:
type: <灰度策略,必須,可在“Percentage”
“Header”中選擇,也可置為空字符串(無策略)>
header: <如果灰度策略為“Header”,此處必填,表示需要對請求頭中哪個字段的值執(zhí)行正則匹配;否則可以省略>
prefer: <在策略不匹配時的優(yōu)選版本>
global:
acl:
entries:
- name:
namespace: <如果 SA/Svc 與 svcroute 不在同一命名空間,此處需要寫;否則可以不寫>
- name:
namespace: <如果 SA/Svc 與 svcroute 不在同一命名空間,此處需要寫;否則可以不寫>
defaultAllow:
to:
- kind: Service
name: <服務(wù)名1,必須>
balance:
rule: <整數(shù)或字符串,可選:當(dāng)采用百分比策略時,這里可以設(shè)置為整數(shù)或百分數(shù);當(dāng)采用Header正則策略時,這里設(shè)置用于匹配的正則表達式>
breaker:(此項可選,如果 threshold大于0,則啟用基于錯誤統(tǒng)計的熔斷)
threshold: <整數(shù)>
window: <整數(shù)>
breakTime: <整數(shù)>
connLimit: <整數(shù),如果 connLimit 大于 0,則啟用基于最大連接數(shù)的熔斷>
port: (此項可選,如果服務(wù)對外暴露了多個端口,這里只選擇其中一個端口進行導(dǎo)出)
targetPort: <端口,類似于“80-tcp”,參見Route對象的port字段>
由于目前的Kubernetes已經(jīng)支持了功能較為完備的CRD,故實施此微服務(wù)框架時已不必采用獨立的APIServer,而只需要將ServiceRoute資源對象注冊為CRD即可。
控制器則可使用任意能夠訪問Kubernetes API的語言實現(xiàn),并將其作為一個普通的Pod部署于集群當(dāng)中即可。
服務(wù)路由器原則上應(yīng)當(dāng)按Namespace實施部署以實現(xiàn)不同Namespace間的隔離,同時額外為全局命名空間部署一組實例。一個服務(wù)路由器的Pod應(yīng)當(dāng)包括一個用任意能夠訪問Kubernetes API的語言實現(xiàn)的配置管理主進程和一個HAProxy進程。主進程負責(zé)偵聽ServiceRoute的變化并據(jù)此生成HAProxy所需的haproxy.cfg文件,然后對HAProxy實施熱重啟以生效新的配置。
2? 系統(tǒng)驗證
本節(jié)基于上述方案進行了系統(tǒng)功能和性能的測試與驗證,測試驗證環(huán)境為一組由3臺虛擬機作為master節(jié)點和3臺物理機作為node節(jié)點組成的Kubernetes集群,Kubernetes的版本為Openshift Container Platform 3.11,虛擬機的主要配置如表1所示,物理機的主要配置如表2所示。
在功能測試階段,對系統(tǒng)進行了4類不同場景的功能測試與驗證,并針對異常恢復(fù)與長期穩(wěn)定性兩個場景進行了非功能測試與驗證,涉及測試用例100余個,整個測試歷經(jīng)3天共計26萬余次請求調(diào)用,系統(tǒng)功能正常。圖5展示了功能測試中一個組合場景的測試結(jié)果:在該場景中涉及了①在相同Namespace中通過svc2級聯(lián)調(diào)用svc11、②在相同Namespace中直接調(diào)用svc11、③跨Namespace調(diào)用svc11和④跨Namespace調(diào)用svc21四個場景,其中svc21部署了a和b兩個版本且按1:1的比例分流、svc11部署了一個d版本,每次調(diào)用均會返回最終進入的服務(wù)實例名。從圖5的結(jié)果可以看出,框架在四種場景下均可正常路由至正確的服務(wù)實例,其中場景④的返回結(jié)果也體現(xiàn)了1:1分流的特征。
此外,測試驗證中還針對常見的路由場景進行了性能測試,主要測試了在使用不同數(shù)量的服務(wù)路由器實例數(shù)的條件下用相同的10 KB報文調(diào)用同一服務(wù)的性能差異,測試結(jié)果如圖6所示。可以看到,當(dāng)服務(wù)路由器實例數(shù)增加時,TPS的增長也近似于線性,結(jié)果顯示系統(tǒng)具備較好的水平擴展能力。
3? 結(jié)? 論
本文提出了一種基于Kubernetes的輕量級PaaS微服務(wù)框架。該微服務(wù)框架采用了服務(wù)端負載均衡模式,以注冊自定義資源對象控制Kubernetes中服務(wù)訪問入口點的方式,充分利用了Kubernetes原生的DNS解析能力。微服務(wù)框架將基于DNS的服務(wù)尋址和基于HAProxy轉(zhuǎn)發(fā)的服務(wù)路由相結(jié)合,在保持對應(yīng)用零侵入的前提下實現(xiàn)了對負載均衡與服務(wù)治理能力的有效組合,架構(gòu)簡單清晰,組件實施方便,經(jīng)測試證明該微服務(wù)框架工作穩(wěn)定、性能良好,可為受限環(huán)境下部署的微服務(wù)系統(tǒng)提供一種輕量級、非侵入、高兼容的微服務(wù)框架解決方案。
參考文獻:
[1] RABIU S,YONG CH,MOHAMAD SMS. A Cloud-Based Container Microservices: A Review on Load-Balancing and Auto-Scaling Issues [J]. A Cloud-Based Container Microservices: A Review on Load-Balancing and Auto-Scaling Issues, 2022(3): 2, 80-92.
[2] COSMINA I. Pivotal Certified Professional Spring Developer Exam [M]. [S.I.]:Apress,2017.
[3] SHARMA R, SINGH A .Getting Started with Istio Service Mesh [M].[S.I.]:Apress,2020.
[4] LI W B,LEMIEUX Y,GAO J. Service Mesh: Challenges, State of the Art, and Future Research Opportunities [C]. 2019 IEEE International Conference on Service-Oriented System Engineering (SOSE).San Francisco:IEEE,2019:122-1225.
[5] ZHENG B P,YIN J W,PANG S Y,ZHENG T,et al. A Zone Routing Algorithm for Service Network [C]. 2020 International Conference on Service Science.Xining:IEEE, 123-128.
[6] CARRI?N C. Kubernetes scheduling:Taxonomy, ongoing issues and challenges [J]. ACM Computing Surveys, 2022,55(7):1-37.
[7] ERDENEBAT B,BUD B,KOZSIK T. Challenges in service discovery for microservices deployed in a Kubernetes cluster – a case study [J]. Infocommunications Journal,2023:69-75.
[8] PRASETIJO A B,WIDIANTO E D, HIDAYATULLAH E T. Performance comparisons of web server load balancing algorithms on HAProxy and Heartbeat [C]//2016 3rd International Conference on Information Technology, Computer,and Electrical Engineering(ICITACEE).Semarang:IEEE, 2016:393-396.
[9] NGUYEN N,KIM T. Toward Highly Scalable Load Balancing in Kubernetes Clusters [J]. IEEE Communications Magazine, 2020,58(7): 78-83.
[10] KHATOUNI A S,ZHANG L,AZIZ K,et al. Exploring NAT Detection and Host Identification Using Machine Learning [C]//2019 15th International Conference on Network and Service Management (CNSM). Halifax:IEEE, 2019:1-8.
作者簡介:崔華(1977—),男,漢族,湖北宜昌人,高級工程師,碩士,主要研究方向:數(shù)據(jù)庫、中間件、云計算分布式技術(shù);樓奕華(1984—),男,漢族,浙江金華人,高級工程師,博士,研究方向:云計算、DevOps;狄坤(1981—),男,漢族,北京人,工程師,碩士,研究方向:云計算、DevOps;王海(1979—),男,漢族,河南新鄉(xiāng)人,高級工程師,碩士,研究方向:中間件、云計算分布式技術(shù)。