政采云业务网关实践:使用 Higress 统一替代 APISIX/Kong/Istio Ingress

科技   2025-01-03 18:02   浙江  

作者:政采云基础架构团队技术专家 朱海峰(片风)

业务网关项目背景




Cloud Native

由于一些历史的背景,政采云平台在网关建设上遇到一些问题:

容器网关配置较多,配置方式多样,运维压力较大:

  • 配置多是因为容器网关配置分为服务路由、搭建类路由、return/rewrite 类路由不同类型的路由。微服务架构使得服务数目多,搭建类平台的技术方案导致子域名非常多,网关的配置复杂度就是 MXN(M 是服务个数,N 是域名的个数),比如子域名个数约 400 多,服务个数约 500 多,整个配置量约 20w+;
  • 搭建类平台子域名单独定义根路径转发,每个页面的分发路径随意填写,导致网关的配置需要支持到每个搭建页面到路径的映射关系配置;
  • 业务的 return/rewrite 逻辑很多是业务服务迁移过程中产生的,旧的请求一直没有推动下线。一些网关规则配置以服务为中心管理,一些网关规则配置以域名为中心管理,各个服务的路由不唯一,经常会出现配置了网关规则不生效,运维需要排查哪里的配置冲突导致的该问题,并可能出现因一次变更影响其他路由规则的生效问题。
网关技术栈比较多:
  • 流量网关使用的是 openrestry,容器网关使用了 Istio IngressGateway,开放平台/业务网关使用了 Spring Cloud Gateway,旧的开放平台使用的是 kong,搭建网关对应的 node express,跨网网关(APISIX)等。虽然不同场景的网关对应不同开发团队,但不同的技术栈选型导致日常维护的工作量增大,同时也给后续的能力建设带来很多的问题。

业务诉求:

  • 随着业务发展,业务研发团队对于网关有一些可扩展的能力诉求,比如说认证、安全管控、请求体修改的需求等。
基于上述问题,今年年初政采云有限公司研发中心基础架构组启动了业务网关项目,在项目启动初期,基础架构工程师做了一次需求调研,最终总结出如下诉求:
① 网关配置难题治理。网关配置治理需要解决配置难、配置风险大的问题。
② 网关技术栈尽可能统一。基于降本提效的背景,统一技术栈有利于运维效率的提升;网关技术栈统一就要求网关的能力需要尽可能满足目前大部分业务场景,目前的业务场景有请求转发、请求重写、协议转换、插件扩展(比如之前的业务网关对接了阿里云的人机校验插件)等,且可持续发展,比如目前能看到的安全管控、流量治理、流量染色等能力。
基础架构团队的工程师经过一个月的需求调研、方案测试,最终给出了解决方案:

网关配置治理

  • 强化规范。基于目前的业务场景,以及后续可能需要支撑的业务场景,优化了域名使用规范,网关规则配置规范,并集成到日常的变更流程,强化规范的落地。

  • 网关规则需要分层配置。网关配置分层基于不同工程师的负责范畴进行分层,分为域名层和服务层两部分。运维工程师负责域名层的配置,研发工程师负责服务层的配置。

  • 网关规则的管理以应用为中心。应用需要涉及到资源,是有上线、下线等生命周期管理的,把服务层的网关规则跟应用绑定,即在元数据中心里面服务层网关规则就是应用的一个属性。服务层网关规则的生命周期就跟应用是一致的了。

网关技术栈的统一
  • 网关技术栈统一就涉及到网关服务的选型。

网关服务的选型




Cloud Native

技术栈统一是逐步达成的目标,不过从目前需要解决的问题紧急度上看,容器网关、业务网关需要合并,以一个技术栈解决网关配置治理、扩展能力的问题。经过社区活跃度、能力对比等多个维度的比较,最终筛选出 APISIX、Higress、Istio(IngressGateway)这三个网关服务。


Higress vs Istio(IngressGateway)
Higress 基于 Istio 的能力做了更上层的封装,以提高易用性,以及满足更多业务场景的需求。基于 Higress,我们可以获取如下收益:
  • 插件能力加强。Higress 在开源的 wasm client 上做了封装,更方便开发者做插件的开发,比如做了插件生效的范围控制,并且社区已有很多插件能力可以直接使用。

  • 扩展功能。Higress 在多数据源这块集成了多种主流注册中心,这些能力可以直接复用,不用重复建设;基于 Envoyfilter 提供了 http2rpc 的能力,并封装了单独的 CRD, 方便 http2dubbo 的配置。


APISIX vs Higress

APISIX 是一个比较优秀的云原生网关解决方案,底层基于 openresty,且在公司高速公路项目上也使用了 APISIX 做跨网络域的请求转发。不过考虑到目前网关重度使用场景是容器网关,该网关规则对应的是 virtualservice 资源,我们也有内部系统围绕 virtualservice 做了相关解决方案,原生支持 virtualservice 会简化迁移工作量,我们选择了 Higress。


为什么使用 Istio CRD
在技术选型的时候,我们不断的思考一个问题,为什么继续使用 Istio CRD,而不是使用 Kubernetes Ingress 或者 Gateway API 做业务网关的配置 sheme,选择了标准的规范会不会简化后续的网关能力建设?
Kubernetes Ingress 提供了基础的路由能力,不过与我们的使用场景相比还是简单了些,如果把我们网关的配置复制到 Kubernetes Ingress 的描述方式,会存在大量的注解信息配置,以及整体配置会膨胀很多倍。因为 Ingress 定义每个 Ingress 资源只能配置一个 Host,如果要多个 host 就需要对应多个 Ingress 资源,而 Istio CRD 里面就一个 virtualservice 资源,配置简洁,可读性较强。
随着业务的发展,网关侧的能力要求越来越高,比如流量治理、插件扩展能力、mesh 能力等,Ingress 满足不了我们对网关配置的要求。
Kubernetes 社区定义了 Gateway API,以解决 Ingress 目前存在的问题。不过目前 Gateway API 发布了 1.1 版本,能力的丰富度上还不是不如 Istio CRD,并且 Gateway API 在低版本的 Kubernetes 上存在兼容性问题。

最终我们继续选择 Istio CRD 做网关配置的资源。

社区的支持




Cloud Native


Higress 架构图
从 Higress 架构图看,Higress 数据面还是使用 Envoy 做请求转发,使用 Istio pilot 组件做配置发现,IstioCRD 是 Istio 默认支持的资源,使用 Higress+IstioCRD 理论上是很顺利的。
迁移过程遇到了一些问题,分享出来供参考:
  1. 基于域名聚合功能不生效。为了优化变更速度,Higress 默认开启了 enableSRDS,该特性会按照域名隔离生效到 Envoy 里面的配置,因为我们业务场景下一个路由对应的子域名特别多,之前是开启了基于域名合并网关配置,在使用 Higress 会导致配置量大增,关闭了 enableSRDS 该问题就解决了。

  2. 配置生效特别慢。在大量网关配置生效到 Higress 的时候会达分钟级别。经过 Higress 社区同学排查优化了这块逻辑,最终使用 Higress 配置的生效时间也是秒级的。

  3. 在有冲突网关规则下发生效的时候 Istio 出现生效混乱。Istio 1.22.0 以下的版本都存在一个问题,在有冲突网关规则下发的时候会在特定条件下出现生效混乱的问题,刚好我这次做网关规则迁移过程中发现了该问题,在我给 Istio 社区提 bug 的时候,他们刚在 1.22.0 版本修复该问题。Higress 社区同学很快的帮忙 merge 该修复的 commit,并发布在 Higress1.4.1 版本中。

  4. 在同样配置下,Higress 使用内存较高。从监控可以看到,在相同配置下,Higress Gateway 的内存使用明显比 Istio-IngressGateway 要高。经过 Higress 社区同学精简 Higress Gateway 的监控指标,两者也达到基本一致的资源使用。

Higress Gateway 与 Istio IngressGateway 内存占用对比
问题处理中,Higress 社区积极响应,基本上都是在问题稳定复现的当天就给出解决方案,配置生效慢问题只是我们场景下遇到的问题,他们本地复现比较困难的情况下,依然坚持在当天解决该问题。在 Higress 社区的大力支持下,问题都迎刃而解,事实证明,Higress+IstioCRD 替换 Istio 整体进度可控。
Higress 社区同学对于我们提的问题回复效率极高,我们在看 Higress 代码,学习插件开发的时候,经常会有些问题提到 Higress 社区钉钉群中,社区同学看到就会积极回复。

业务网关项目除了引入 Higress 取代 IngressGateway 作为业务网关外,还重点做了网关规则治理。下面我介绍下网关分层的解决思路,与业务耦合比较紧密,供参考。

网关分层的解决思路




Cloud Native

在网关规则治理上,结合目前网关规则的分层配置要求,我们定义了应用路由(appvirtualservice,简称 avs)的 CRD 资源,把路由配置分成两层,域名层和服务层。域名层对应了原来的 virtualservice 资源,服务层对应了 avs 资源,avs 是不带域名信息的,跟域名是分开的,研发人员操作的网关规则都是对应的 avs 资源,avs 资源最终会生效到 virtualservice 资源。

人员与资源操作关系
avs 资源举例:
apiVersion: arch.cai-inc.com/v1kind: AppVirtualServicemetadata:  labels:    app: web-a-front    vsLayer: app  name: web-a-front  namespace: testspec:  http:  - match:    - uri:        prefix: /a-index    route:    - destination:        host: web-a-front        port:          number: 80

基于实际的使用场景,在 avs 资源定义中,我们还定义了 PriorityClass(支持高,中,低三个等级,默认是中)字段,通过该字段决定该规则生效的优先级,部分缓解原来依赖创建时间决定规则生效优先级的不可控问题。

网关分层需要对原来人工维护的数量接近 2000 的 virtualservice 配置进行规范性整理,对整体逻辑影响比较大,为了保证整个过程可重复执行,我们开发了工具,把原来的 virtualservice 逻辑拆分成 virtualservice+avs 的两层配置结构。
基于原来的路由规则,我们把路由分为域名默认路由、服务路由(冲突服务路由、不冲突的服务路由)、rr 路由(return/rewrite 路由)。域名默认路由、rr 路由、冲突的服务路由跟域名是有关系的,需要网关运维人员维护处理;不冲突的服务路由(比例占比 90%)转换为 avs 资源,通过页面功能开放给研发人员处理。以此测算,分层前后网关规则的维护成本(问题排查以及出错概率)降低 90%。
分层解决了,我们面临一个问题,如何校验变更前后的数据一致性,以及如何做变更?

数据一致性校验
路由变更的数据一致性校验的方式是采集原来流量转发的日志,回放流量到网关分层后的测试环境中,再采集该测试环境的网关转发日志,两者做对比,输出差异报告,如果同一个请求(域名+url 相同),转发到 upstream cluster 不同,则说明网关分层后修改了原来的转发逻辑,需要优化分层逻辑或者人工处理。

流量校验逻辑图示
开发工具的时候两个点需要注意:
① 流量唯一性采集流量采集使用域名+url(去除参数)的 md5 做唯一性 key,对于有请求 url 路径上带了变化 id 的,比如/item/123445,通过正则表达式过滤成一条唯一的请求,流量明细会记录到文件中,包含流量的域名,url,后端服务,requestId 等字段,用于流量回放以及差异性验证。

② 回放流量使用 HEAD 请求。回放流量只需要验证转发逻辑的正确,为了避免影响到生产环境的流量,原来的请求 method 都会设置 HEAD,去掉参数和请求体内容进行回放。


变更方案

创建新的网关实例,分层之后的网关规则生效到新的网关实例,在负载均衡侧基于流量比例 1%->5%->10%->20%->50%->100% 的比例逐渐放大新网关实例承载的流量比例。

初步建设成果




Cloud Native

业务网关项目初步建设的成果还是较显著的:

  • 无感。整个业务网关的变更对业务研发侧基本是无感的,他们只是感知到有这种变更事件。

  • 网关规则治理目标达成。网关规则按照域名层和服务层进行分层,域名层属于基础配置,服务层以应用为中心进行管理,整体网关规则的治理目标基本达成。

  • 技术栈统一。业务网关(Higress)取代了容器网关(Istio IngressGateway),旧的开放平台(kong),跨网网关(APISIX),旧的业务网关(Spring Cloud Gateway),节省了相关服务所占的资源,同时节省了后续的维护成本。
引入 Higress 目前仅仅是开始,后续会基于 Higress 建设开放平台(认证鉴权、http 转 dubbo 等)、接入统一认证能力等,最终达成统一网关技术栈的目标。

阿里云云原生
发布云原生技术资讯、汇集云原生技术详细内容,定期举办云原生活动、直播,阿里产品及用户实战发布。与你并肩探索云原生技术点滴,分享你需要的云原生内容。
 最新文章