基于 Istio 的灰度发布实现

发布时间 2023-04-05 21:57:36作者: GaoYanbing

PAAS平台是一个被严重低估的平台,概括来说,它主要的目的就是=加速开发过程及解决应用部署上线的问题。

 

一家大型的公司,技术架构上离不开 PAAS平台,PAAS平台主要解决如下一些共性的问题:

 

  1.  软件生产线的问题。CICD 持续集成和发布,以 Devops 为核心的能力必须依赖 PAAS。

  2. 分布式服务化的问题。分布式服务化的服务高可用、服务编排、服务调度、服务发现、服务路由

  3. 提高服务的可用性 SLA。提高服务可用性SLA 所需要的分布式、高可用技术架构和运维工具。

  4. 软件能力的复用。软件工程的能力就是软件能力的复用。

 

 

本期我们主要解决 Paas 平台中服务部署及更新时的问题,以提高服务可用性SLA。

 

任何一种应用上线后都有生命周期,必然要不停的迭代上线、更新发布。

 

如果每次更新,都是让开发拿着包去找运维更新应用,那生产的事故是不可避免的。一旦人为操作失误,需要回退时,工程师的压力不可想像。既要面临老板的“关心”,还要双手飞速的敲着各种命令。

 

没有经历过这种场景的工程师的人生是不完美的。

 

为了解决频繁救火,引用灰度发布能力,是每个生产系统必不可少的步骤。

 

 

01

灰度发布

 

 

目前实用灰度发布的技术,大多使用网关或是 serviceMesh 技术来解决。

 

Kubernetes 上的默认网关,一般会使用 Ingress。很多开源的网关如:ApiSix、kong、Traefix 等,都有这个能力。

 

但是它们大多只能解决服务外部访问时的灰度问题,并不能解决服务间相互调用时灰度的问题。

 

图片

通俗来讲:就是如果一个服务 ServiceA 访问 ServiceB,我们如果要对 ServiceA 做灰度,我们需要暴露 ServiceA 访问地址,以 Ingress 形式来访问 ServiceA。然后在 Ingress 上加上灰度的版本地址,让流量切换到新的版本,或是控制流量。

 

但是想想,如果我们想对serviceB 做灰度呢?

 

serviceA 访问 serviceB 的地址时,大多是服务发现提供的注册服务名。如果我们要使用这种方式对 ServiceB 做灰度,意味着我们需要修改 ServiceA 访问 ServiceB 时的访问地址,要把它修改成 Ingress 的地址!这种方式显然不能满足生产的要求,因此我们需要服务间灰度。

 

本文,我们实现 ServiceMesh 来实现灰度发布,使用 ServiceMesh 的技术好处是它不仅可以实现服务间的灰度,还可以对任何一个微服务配置网关,让它实现外部访问时的灰度。

图片

 

02

概念

 

 

生产上的灰度发布,又名金丝雀发布。与蓝绿发布惟一不同之处就是流量比例的设定。

图片

对于灰度发布,每次新建一个新版本,然后把流量引入一部分到新的版本上面,经过验证没有问题,可以逐步调整流量比例,直到流量全部引入到新版本。此时可以将老版本下线。

取名金丝雀的原因,是因为这个过程,跟早期矿工检测矿井是否含有瓦斯过程很类似。

 

由于金丝雀这种鸟类对瓦斯非常敏感,只要井里面有瓦斯,它的反应就特别大。矿工们就能马上感知,并撤出。

 

类似于把流量引入到新版本,发现有不正常更象,此时可以马上回退版本,而不至于造成严重的生产事故。

 

这就是取名金丝雀发布的来由。

 

蓝绿发布,就是只设定两个版本。要上线时,把流量全部切换到新的版本,如果有问题,立马把流量切回老版本。

 

其实跟灰度发布一样,每次发布的时候,都部署了两个版本,无非蓝绿是把流量比例给到 100%。

 

图片

 

 

03

实战

 

 

1. 安装 istio

 

curl -L https://istio.io/downloadIstio | sh -# 将 istioctl 加入到命令./bin/istioctl install

 

2. 安装 Bookinfo 示例

 

# ns 需要打上相应 labelkubectl label namespace default istio-injection=enabled#代码位于官方仓库 https://github.com/istio/istiokubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

 

4. 查看出来的示例

 

NAME                              READY   STATUS    RESTARTS   AGEdetails-v1-7b7fd4bc5b-sx4pn       2/2     Running   0          4h38mreviews-v3-757885dbbd-cfxj7       2/2     Running   0          4h38mreviews-v2-88b9b58b6-vs6kn        2/2     Running   0          4h38mproductpage-v1-7d58df8df8-5qbdn   2/2     Running   0          4h38mreviews-v1-78c899b5fb-pcps9       2/2     Running   0          4h38mratings-v1-767cd7944-nfdgc        2/2     Running   0          4h38m

 

5. 暴露 productpage 服务,从外部访问

 

图片

 

多刷新几次,可以看到 reviews 会变化

 

图片

图片

 

 

原因是有三个 reviews 版本:

 

图片

 

 

6. 配置流量访问比例

 

首先要配置 dr,定义三个版本:

 

apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:  name: reviewsspec:  host: reviews  trafficPolicy:    loadBalancer:      simple: RANDOM  subsets:  - name: v1    labels:      version: v1  # 匹配reviews deployment label  - name: v2    labels:      version: v2  - name: v3    labels:      version: v3

 

此时可以配置流量比例,将流量比例设置为版本 v1 v3 各一半

 

vs 如下:

 

apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: reviewsspec:  hosts:    - reviews  http:  - route:    - destination:        host: reviews        subset: v1      weight: 50    - destination:        host: reviews        subset: v3      weight: 50

 

kubectl apply -f samples/bookinfo/networking/destination-rule-reviews.yamlkubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

apply 上面两个 yaml ,可以看到流量只在两个版本之间切换。

 

 

你也可以任意来调整上述的比例,实现流量的分配到不同的后端。但是需要注意:需要保证分配到各版本的比例总和为 100%,否则会报错。

 

如果是生产,记得一定要先 apply destinationRule,定义好各版本后;再 apply virturalService,分配流量。因为如果没有 apply DR,直接apply vs 分配流量,否则会出现流量丢失的问题。

 

03

总结

 

 

我们通过上述的演示已经成功实现了 Istio 对流量的分配。既然已经能够自由的分配流量,那么把技术包装成业务模型,即灰度发布和蓝绿发布,已经是很简单的事情了。