一种基于Kubernetes的轻量级PaaS微服务框架

2024-04-14 02:12崔华楼奕华狄坤王海
现代信息科技 2024年2期
关键词:负载均衡微服务

崔华 楼奕华 狄坤 王海

DOI:10.19850/j.cnki.2096-4706.2024.02.016

收稿日期:2023-09-08

摘  要:微服务框架主要有客户端负载均衡和服务端负载均衡两类设计模式。文章提出一种基于Kubernetes的轻量级PaaS微服务框架,框架采用服务端负载均衡模式,设计了自定义的ServiceRoute对象来描述服务路由需求,以ServiceRoute对象的变化来增删服务访问点,基于对服务访问点的DNS名称解析实现服务寻址,采用经LUA扩展的HAProxy实现服务路由和服务治理。框架采用标准的HTTP协议,架构简单清晰、组件实施方便、对应用无侵入,测试结果表明,该微服务框架工作稳定、性能良好,可为受限环境下部署微服务系统提供一种合适的解决方案。

关键词:微服务;PaaS;Kubernetes;负载均衡;服务寻址;服务治理

中图分类号: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  引  言

傳统的业务系统通常为单架构,然而随着业务增长引发的可扩展性需求逐渐紧迫,单体应用的局限性愈发明显,因此近年来业务系统逐步向微服务模式进行转变。和单体架构不同,微服务架构是由一系列职责单一的细粒度服务构成的分布式网络,服务间通过微服务框架的路由机制进行通信。

主流的微服务框架通常有两类设计模式[1]:一类是以SpringCloud [2]、Istio [3]为代表的主流微服务框架所采用的客户端负载均衡模式,即服务网格[4],在这种模式下每个微服务都有一个开放的端口,请求方通过构建服务名和端口的映射关系表可以直接向微服务对应的实例发送请求;另一类则是服务端负载均衡模式[5],在这种模式下,请求方并不直接与微服务的实例通信,而是先将请求发送给统一的微服务路由组件,再由该组件负责向实际的微服务实例转发请求。

一般而言,客户端负载均衡模式由于采用了服务间直接通信的方式,具有跳数少、故障点少的优势,但通常要求需要使用方进行代码级适配;而服务端负载均衡模式由于采用了增加路由节点转发请求的模式,一般不需要使用方进行特殊适配,但增长了调用链路、增加了故障点。两类微服务设计模式虽各有优劣,但随着系统复杂度的提升,尤其是微服务数量的增长,在客户端负载均衡模式下所有请求方都会面临着维护大量微服务配置与映射关系的压力。为此,本文提出了一种采用服务端负载均衡模式的基于Kubernetes[6]的轻量级PaaS微服务框架,采用基于Kubernetes原生名字解析[7]的服务寻址机制和基于HAProxy[8]的服务路由机制,可满足受限环境下客户端无修改接入微服务框架的需求。

1 系统设计

1.1  系统设计方案与组成

本文提出的基于Kubernetes的轻量级PaaS微服务框架,所有的组件都运行于同一个Kubernetes集群中,其整体的逻辑架构如图1所示。

系统具体包含如下组件:

API Server:负责管理微服务框架在Kubernetes中注册的ServiceRoute自定义资源对象,具体实现时既可以采用自定义扩展APIServer的方式,也可以将ServiceRoute对象作为CustomResourceDefinition注册到集群中,由Kubernetes原生的APIServer承担此功能;

服务路由组件:负责根据配置好的策略将调用方发起的服务调用请求转发给相应服务版本的某个实例Pod,在服务路由组件的每个实例中,都会运行一个负责本实例策略配置更新的主进程和一个负责请求转发的HAProxy进程。

控制组件:负责根据ServiceRoute对象的定义,在集群中创建/修改/删除与此对象关联的Kubernetes原生的Service对象。

与Kubernetes原生的服务路由机制[9]相比,由于Kubernetes原生的服务路由机制是通过直接访问的(Service IP, Service Port)并依赖NAT[10]技术实现(Service IP, Service Port) -> (Pod IP, PodPort)的映射,故服务调用仅能实现简单的4层负载均衡。而本文提出的方案由于增加了HAProxy作为服务路由组件,可在实现4层负载均衡的基础上进一步做到7层负载均衡及更多的服务治理能力(如熔断、多版本灰度等)。

1.2  实现原理

1.2.1  服务寻址原理

在本文所述的微服务框架中,每一个服务的不同版本都有一个对应的Service对象存在于Kubernetes集群中。为了能够使用统一的访问点访问服务,并支持通过自定义的规则进行版本选择和服务治理,微服务框架使用了自定义的ServiceRoute资源对象用于保存这些规则。微服务框架的控制组件会采用List & Watch机制跟踪监视集群中所有ServiceRoute资源对象的变化。在一个ServiceRoute资源对象创建后,控制组件就会根据此ServiceRoute资源对象的描述,在指定的Namespace中创建一个与该资源对象同名的、用作服务访问入口点的Service对象。该Service对象的类型为ExternalName,其指向的是一个位于特定Namespace中的Service对象,该Service对象代表了一个服务于本Namespace的服务路由组件。

当调用方通过目标服务的服务名发起HTTP调用请求时,首先需要对服务名进行地址解析,微服务框架通过在合适的名称空间中创建与服务名同名的别名服务方式,巧妙地将对服务名的域名解析最终转换成为对某个服务路由组件IP地址的解析。一次具体的服务寻址流程如图2所示。

由于在服务寻址的过程中,服务名的DNS解析需要交由Kubernetes集群来执行,因此其命名规则对寻址结果会产生影响。理论上说,在执行服务调用时,调用方可以在<服务名>和<服务名>.两种格式中任选其一,其差异在于前者只能调用在调用方所属的Namespace中发布的服务,而后者则可以调用在其他Namespace中发布的服务。但出于安全性考虑,本文所述的微服务框架对后者进行了一定的限制,即不允许服务调用方用任意的“”发起服务调用,而是只允许在调用时使用特定的“全局命名空间”(默认为“global”,也可根据需求自行定义)。同时,微服务框架会将那些需要供不同Namespace调用的服务统一归类为“公有服务”,这些服务除了在自身所在的Namespace中发布用作服务访问入口点的Service对象以外,也会在全局命名空间中发布用作服务訪问入口点的Service对象。

1.2.2  服务路由原理

调用方在获取到服务路由组件的IP地址后,就可以构造HTTP请求发送到该IP地址。由于该IP地址为Kubernetes中的ServiceIP,因此该请求会经过集群节点上的IPTables的NAT映射后转换为服务路由组件的某个实例Pod的IP,并由操作系统路由于对应的Pod中。在请求在到达Pod后,该请求会进入已在Pod中运行且侦听了当前端口的HAProxy进程中,由HAProxy根据灰度配置及请求信息为请求选择一个合适的目标服务版本(HAProxy的配置由服务路由组件的主进程侦听其所负责的Namespace中所有ServiceRoute对象的变更后动态生成并更新),并经负载均衡策略将该请求最终转发给该具体版本的某个Pod,这一过程的实例如图3所示。

1.2.3  服务治理原理

由于微服务框架引入了HAProxy作为服务路由的转发核心,因此服务路由组件可充分利用HAProxy的能力实现对服务的7层治理,包括但不限于:

多版本治理:在由Service Router生成的HAProxy配置中,每个服务的具体版本实例对应于HAProxy配置的一个后端,因此某一个特定的HTTP访问点可能会对应一个后端(单版本情形)或多个后端(多版本情形),在后一种情况下,微服务框架通过嵌入在HAProxy配置文件中的LUA脚本解析每一个HTTP请求头,并根据请求头中的字段或者规定的百分比为该请求选择一个后端。如果找不到合适的后端用于处理,则会将请求路由到一个特定的后端,该后端会直接向客户端返回错误码503。

熔断治理:在微服务框架中,可以为服务的每一个版本实例都配置熔断规则,指定在什么样的条件下对该版本实例的访问会被拒绝。熔断的实现是通过在HAProxy的后端中通过LUA脚本增加了一组统计规则,当一定时间窗口内的统计结果符合预先配置的熔断阈值时,后续一段时间内所有路由到该后端的请求都会被直接拒绝而不转发。

访问授权治理:微服务框架允许为每个可被调用的服务设置访问授权规则,并要求每个调用请求中携带一个特定的HTTP請求头,其中包含一串可以在容器中获得的、用于标识调用方身份的随机串码。在该请求到达HAProxy时,其中的LUA脚本会将该串码与预先生成的黑白名单列表进行匹配,并阻止那些根据规则不得发起调用的请求。

基于HAProxy实现服务治理的原理如图4所示,其核心在于通过在HAProxy的配置文件置入包含了治理规则的LUA脚本,使这些LUA脚本在Backend选择、Server选择等HAProxy请求转发过程的重要节点中得到执行,从而达到根据请求特征实现服务治理的目的。

1.3  实施方式

本文提出的微服务框架实施方式包括:制定一个可用于描述服务路由规则的ServiceRoute资源对象,提供一个可管理该资源对象的APIServer(可选),实现一个可侦听该资源对象变化并制作相应动作的控制器,为每一个需要加入微服务框架的Namespace部署一组服务路由器。

ServiceRoute资源对象的定义如下:

apiVersion: paas.io/v1

kind: ServiceRoute

metadata:

name: <名字,必须>

namespace: <命名空间(项目名),必须>

spec:

rule:

type: <灰度策略,必须,可在“Percentage”

“Header”中选择,也可置为空字符串(无策略)>

header: <如果灰度策略为“Header”,此处必填,表示需要对请求头中哪个字段的值执行正则匹配;否则可以省略>

prefer: <在策略不匹配时的优选版本>

global:

acl:

entries:

- name:

namespace: <如果 SA/Svc 与 svcroute 不在同一命名空间,此处需要写;否则可以不写>

- name:

namespace: <如果 SA/Svc 与 svcroute 不在同一命名空间,此处需要写;否则可以不写>

defaultAllow:

to:

- kind: Service

name: <服务名1,必须>

balance:

rule: <整数或字符串,可选:当采用百分比策略时,这里可以设置为整数或百分数;当采用Header正则策略时,这里设置用于匹配的正则表达式>

breaker:(此项可选,如果 threshold大于0,则启用基于错误统计的熔断)

threshold: <整数>

window: <整数>

breakTime: <整数>

connLimit: <整数,如果 connLimit 大于 0,则启用基于最大连接数的熔断>

port: (此项可选,如果服务对外暴露了多个端口,这里只选择其中一个端口进行导出)

targetPort: <端口,类似于“80-tcp”,参见Route对象的port字段>

由于目前的Kubernetes已经支持了功能较为完备的CRD,故实施此微服务框架时已不必采用独立的APIServer,而只需要将ServiceRoute资源对象注册为CRD即可。

控制器则可使用任意能够访问Kubernetes API的语言实现,并将其作为一个普通的Pod部署于集群当中即可。

服务路由器原则上应当按Namespace实施部署以实现不同Namespace间的隔离,同时额外为全局命名空间部署一组实例。一个服务路由器的Pod应当包括一个用任意能够访问Kubernetes API的语言实现的配置管理主进程和一个HAProxy进程。主进程负责侦听ServiceRoute的变化并据此生成HAProxy所需的haproxy.cfg文件,然后对HAProxy实施热重启以生效新的配置。

2  系统验证

本节基于上述方案进行了系统功能和性能的测试与验证,测试验证环境为一组由3台虚拟机作为master节点和3台物理机作为node节点组成的Kubernetes集群,Kubernetes的版本为Openshift Container Platform 3.11,虚拟机的主要配置如表1所示,物理机的主要配置如表2所示。

在功能测试阶段,对系统进行了4类不同场景的功能测试与验证,并针对异常恢复与长期稳定性两个场景进行了非功能测试与验证,涉及测试用例100余个,整个测试历经3天共计26万余次请求调用,系统功能正常。图5展示了功能测试中一个组合场景的测试结果:在该场景中涉及了①在相同Namespace中通过svc2级联调用svc11、②在相同Namespace中直接调用svc11、③跨Namespace调用svc11和④跨Namespace调用svc21四个场景,其中svc21部署了a和b两个版本且按1:1的比例分流、svc11部署了一个d版本,每次调用均会返回最终进入的服务实例名。从图5的结果可以看出,框架在四种场景下均可正常路由至正确的服务实例,其中场景④的返回结果也体现了1:1分流的特征。

此外,测试验证中还针对常见的路由场景进行了性能测试,主要测试了在使用不同数量的服务路由器实例数的条件下用相同的10 KB报文调用同一服务的性能差异,测试结果如图6所示。可以看到,当服务路由器实例数增加时,TPS的增长也近似于线性,结果显示系统具备较好的水平扩展能力。

3  结  论

本文提出了一种基于Kubernetes的轻量级PaaS微服务框架。该微服务框架采用了服务端负载均衡模式,以注册自定义资源对象控制Kubernetes中服务访问入口点的方式,充分利用了Kubernetes原生的DNS解析能力。微服务框架将基于DNS的服务寻址和基于HAProxy转发的服务路由相结合,在保持对应用零侵入的前提下实现了对负载均衡与服务治理能力的有效组合,架构简单清晰,组件实施方便,经测试证明该微服务框架工作稳定、性能良好,可为受限环境下部署的微服务系统提供一种轻量级、非侵入、高兼容的微服务框架解决方案。

参考文献:

[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—),男,汉族,湖北宜昌人,高级工程师,硕士,主要研究方向:数据库、中间件、云计算分布式技术;楼奕华(1984—),男,汉族,浙江金华人,高级工程师,博士,研究方向:云计算、DevOps;狄坤(1981—),男,汉族,北京人,工程师,硕士,研究方向:云计算、DevOps;王海(1979—),男,汉族,河南新乡人,高级工程师,硕士,研究方向:中间件、云计算分布式技术。

猜你喜欢
负载均衡微服务
基于供给侧改革理论的图书馆社交网络微服务研究
Linux负载均衡集群技术在网络服务器中的应用
Oracle MAA在汽车行业电子政务平台中的应用
微信公众平台在医院图书馆的应用现状调查
异构环境下改进的LATE调度算法
基于微信企业号的校园移动服务
微服务视角下高职图书馆数字资源使用分析
从单一模式系统架构往微服务架构迁移转化技术研究
基于负载均衡的云资源调度策略研究
基于微信公众平台的高校图书馆微服务现状及对策