前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >APISIX 结合 Istio 实现全链路灰度

APISIX 结合 Istio 实现全链路灰度

作者头像
我是阳明
发布2023-09-29 10:11:50
4690
发布2023-09-29 10:11:50
举报
文章被收录于专栏:k8s技术圈k8s技术圈

作者:苏万亮,中国移动云能力中心软件研发工程师,专注于云原生、微服务、算力网络等领域。

前言

近期团队想利用Istio对产品做全链路灰度,但是对于产品已经选择Apisix作为网关的场景,出于不改变产品原有架构的考虑,不想再引入Istio Ingress Gateway,而只依赖开源的Apisix又无法对产品做到全链路灰度,因此便调研能否将Apisix和Istio结合实现全链路灰度。本文就介绍一下两种可行的方案,与大家一起探讨学习。

问题介绍

上图是简化的一个产品服务调用关系图。其中,Apisix ingress承接外部流量,根据路由规则请求client服务,client服务还会请求provider服务。现在的目的就是对服务client和provider全部做灰度,实现全链路灰度。而Apisix只能对入口服务client进行灰度,做不到全链路灰度。因此考虑引入Istio来实现全链路灰度,为了不改变产品的原有架构,不引入Istio Ingress Gateway,依旧只使用Apisix ingress一种网关。结合Apisix和Istio实现全链路灰度,在配置具体流量规则时共有两种方案,下面对两种方案做详细介绍。

方案一:网关注入sidecar,重写host

对于Istio的灰度方式,我们知道若一个已注入sidecar的服务所配置的灰度规则(virtualservices和destinationrules)想生效,需要请求访问它的服务同样也注入sidecar(是一个istio envoy)。因此对于入口服务client,若引入Istio Ingress Gateway当然没有问题,Istio Ingress Gateway本身就是一个envoy,现不引入Istio Ingress Gateway的话,就需要对Apisix的数据面注入sidecar,如下图所示。

对于服务client,其正常灰度规则配置如下:

apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: client spec: host: client subsets: - labels: version: v0-0-1 name: v0-0-1 - labels: version: v0-0-2 name: v0-0-2 --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: client spec: hosts: - client http: - match: - headers: client_version: exact: v0-0-2 route: - destination: host: client subset: v0-0-2 - route: - destination: host: client subset: v0-0-1

上述规则中,hosts的配置为client(kubernetes的完全限定域名),表示根据访问client服务的请求是否带请求头client_version:v0-0-2决定流量路由到某版本。而对于Apisix来说,一般配置规则为:hosts为www.xxx.com,匹配到某路径转发到client服务。这样Apisix和Istio的规则就匹配不上,导致灰度规则不生效。

因此若想服务client的灰度规则生效的话,则需要在外部流量进入Apisix网关后,重写其host。对于重写host,可使用Apisix的插件proxy-rewrite将请求host(www.xxx.com)改成k8s内部域名(test.ns.svc.cluster.local)。具体配置如下:

apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: ingress-testclient spec: http: - backends: - serviceName: client servicePort: 8070 match: hosts: - www.xxx.com paths: - /client/* name: testclient-route-default plugins: - config: host: client.wgb.svc.cluster.local enable: true name: proxy-rewrite - config: burst: 1 key: remote_addr key_type: var nodelay: true rate: 1 rejected_code: 503 rejected_msg: limit-req-error enable: true name: limit-req

通过上述配置,外部流量经过Apisix后,其请求头host:www.xxx.com就被重写成host:client.wgb.svc.cluster.local,从而匹配到服务client的virtualservices中的host,灰度规则生效。

上述方案虽然可以实现client服务的灰度,但其很明显的问题就是若client服务本身会根据传入的host值来处理业务,那丢失原有的host,对业务带来的影响就很大。

方案二、各施其职,不重写host

对于Apisix来说,虽然不能对产品做到全链路灰度,但是其针对入口服务,即图中的client服务,是具备灰度发布能力的。因此第二个方案就是将入口服务交给Apisix来灰度,其余非入口服务交给Istio来灰度。

通常一个产品由多个微服务构成的话,其大部分服务都不是入口服务,因此都可以用Istio实现这些服务的灰度发布。Istio的灰度方式不做赘述,以provider服务为例,通常是会部署两个deployment对应其两个版本,一个service关联这两个版本的pod,再通过配置virtualservices和destinationrules即可实现灰度。对于整个产品全链路灰度,最好是能将灰度版本的服务部署方式统一起来,即对于入口服务client,也部署两个deployment对应其两个版本,一个service关联这两个版本的pod,但用Apisix的路由配置来实现灰度。具体方式就是利用ApisixRoute+ApisixUpstream实现下发规则路由到不同版本的client服务。Apisix相关配置如下:

apiVersion: apisix.apache.org/v2 kind: ApisixUpstream metadata: name: client spec: subsets: - name: v0-0-2 labels: version: v0-0-2 - name: v0-0-1 labels: version: v0-0-1 --- apiVersion: apisix.apache.org/v2 kind: ApisixRoute metadata: name: ingress-testclient spec: http: - backends: - serviceName: client servicePort: 8070 subset: v0-0-2 match: exprs: - op: Equal subject: name: client_version scope: Header value: v0-0-2 hosts: - testclient.com paths: - /client/* name: route-v2 priority: 1 - backends: - serviceName: client servicePort: 8070 subset: v0-0-1 match: hosts: - testclient.com paths: - /client/* name: route-default

从上述配置可以看出,首先ApisixUpstream根据不同版本的pod的标签创建subset,配置规则与Istio中的destinationrules类似,其次ApisixRoute也只需要定义好匹配规则,选择路由到服务client的某个subset。整个配置同样只需要client服务存在两个deployment对应其两个版本,一个service关联这两个版本的pod。

需要注意的是虽然client服务是用Apisix做灰度,但其也需要注入sidecar,因为provider的灰度规则需要client同样是一个envoy。另外该方案仅针对服务的灰度发布能力,没有对Apisix的数据面注入sidecar,若产品还需要提供完整的服务拓扑或链路追踪功能,对Apisix的数据面注入sidecar即可。

总结

本文针对产品已使用Apisix作为网关,并想在不改变产品原有架构的前提下,对产品的所有服务实现全链路灰度,提出了两种可行的方案。两种方案各有利弊,方案一实现较简单,但需重写host,要考虑产品能否接受,不适用于所有产品;方案二无需重写host,产品都能接受,但灰度逻辑略复杂,配置也略复杂。因此,使用哪种方案需根据产品本身架构来决定。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-09-28 21:39,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 问题介绍
  • 方案一:网关注入sidecar,重写host
  • 方案二、各施其职,不重写host
  • 总结
相关产品与服务
服务网格
服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档