Istio服务网格进阶③:基于Istio服务网格实现灰度发布机制
基于Istio服务网格实现灰度发布机制
文章目录
- 基于Istio服务网格实现灰度发布机制
-
- 1.应用程序主流发布方案
-
- 1.1.蓝绿发布
- 1.2.滚动发布
- 1.3.灰度发布
- 1.4.A/B测试发布
- 2.Istio灰度发布实现目标
- 3.在Istio中部署多个版本的知识点系统
-
- 3.1.创建程序所在的命名空间并开启自动注入
- 3.2.编写Deployment资源编排文件
- 3.3.编写Service资源编排文件
- 3.4.编写Gateway以及VirtualService资源编排文件
- 3.5.创建所有资源完成部署
- 3.6.访问知识点系统
1.应用程序主流发布方案
1.1.蓝绿发布
Web应用程序在逻辑上分为A、B两组,在升级过程中,首先将B组从负载均衡器中移除,然后在B组的Web服务器中进行V2版本的升级,A组V1版本依旧正常提供应用服务,当B组完成应用升级后,将B组重新挂载到负载均衡器中,然后将V1版本的A组从负载均衡器中移除,这种发布模式被称为蓝绿发布。
蓝绿发布的特点:
- 策略简单,过程通过脚本来实现,只需要从负载均衡中移除相应的服务器。
- 升级/回滚的速度快,当B组升级完提供线上服务时,A组虽然被负载均衡器移除了,但是也不会立刻进行版本升级,而是当一段时间后,线上程序稳定了再进行版本升级,当线上程序异常了,也可以直接将B组移除,将A组重新添加,不管是升级还是回滚的速度都非常快,只需要调整负载均衡的配置即可。
- 用户无感知、平滑过渡,整个过程中用户是没有感知的。
蓝绿发布的缺点:
- 需要正常业务程序提供流量支撑的两倍及以上的服务器资源,较为浪费资源。
- 有问题影响的范围比较广,例如新版本的问题发现的比较晚,AB两组的服务器全部升级版本了,涉及回滚就会比较麻烦。
1.2.滚动发布
Kubernetes集群的Pod程序版本升级的默认方式就是滚动发布,先运行一个新版本的Pod,健康检查机制通过后才会将旧版本的Pod删除,不断的执行这个过程,直到所有的Pod全部升级成新的版本为止。
**滚动发布的特点:**用户无感知、平滑过渡,新旧版本都存在于集群中,用户也不会感觉到程序进行了版本升级。
滚动发布的缺点:
- 部署的周期比较长,当健康检查通过后才会进行下一个Pod的升级。
- 不易回滚,回滚的方式也是一个一个Pod进行回滚,周期长。
- 影响的范围很大。
1.3.灰度发布
灰度发布又称为金丝雀发布,灰度发布是通过只升级集群中的一部分WEB的版本,然后进行流量访问控制,将一批用户的请求转发到新版本的应用程序上,另外一批用户继续使用旧版本的应用程序,如果用户对新版本的程序没有异常问题的发生,那么会逐步扩大范围,最终将所有的WEB进行版本升级。
灰度发布的例子:一个应用程序有2个版本,V1版本为线上生产环境的版本的,V2版本为即将上线的版,需要同时将两个版本的应用程序部署,并且全部接入到负载均衡中,通过灰度发布控制,V1版本承担90%的流量,V2版本承担10%的的流量,观察运行效果,循序渐进,最新V1版本下线,V2版本提供线上服务。
灰度发布的特点:
- 影响范围略低,仅是某一批用户开始使用新的版本,即使存在问题也只是少数人。
- 保证整体系统的稳定性,可能只能20%的用户在使用新版本,剩下80%依旧是旧版本的程序。
- 用户无感知、平滑过渡。
- 新旧版本共存、实时观察反馈动态。
**灰度发布的缺点:**灰度发布设计相对复杂,对自动化的要求比较高,要精确控制。
1.4.A/B测试发布
A/B测试发布是灰度发布的另一种模式,主要是针对不同批次用户使用不同版本后的信息采样,对收到的反馈数据进行对比,也就相当于全部上线新版本之前,先要看看用户的使用反馈,该加功能的加功能,改修复的修复,当用户都比较满意时,再进行版本是否要升级。
A/B测试的精确性更高,上线后的故障率也会相对降低,维护成本较高。
2.Istio灰度发布实现目标
以知识点系统为例基于Istio实现灰度发布,知识点系统各个版本的镜像均托管在docker hub中。
灰度发布实现目标:
-
用户流量全部转发到V1版本。
-
90%的用户流量转发到V1版本 10%的流量转发到V2版本。
-
100%的流量转发到V2版本 下线V1版本。
3.在Istio中部署多个版本的知识点系统
在Istio中部署多个版本的
3.1.创建程序所在的命名空间并开启自动注入
创建知识点系统所使用的命名空间并设置Sidecar自动注入。
1.创建一个目录存放使用的资源编排文件[root@k8s-master samples]# mkdir istio-knowsystem2.创建命名空间[root@k8s-master istio-knowsystem]# kubectl create ns prod-knowsystemnamespace/prod-knowsystem created3.开启Sidecar自动注入[root@k8s-master istio-knowsystem]# kubectl label ns prod-knowsystem istio-injection=enablednamespace/prod-knowsystem labeled
3.2.编写Deployment资源编排文件
1)V1版本
[root@k8s-master istio-knowsystem]# vim knowsystem-v1.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: knowsystem-v1 namespace: prod-knowsystem labels: app: knowsystemspec: replicas: 1 selector: matchLabels: app: knowsystem version: v1#关联pod的标签 template: metadata: labels: app: knowsystem version: v1#通过配置一个version=v1的标签来声明程序的版本是V1 spec: containers: - image: jiangxlrepo/know-system:v1 name: knowsystem-v1
2)V2版本
[root@k8s-master istio-knowsystem]# vim knowsystem-v2.yaml apiVersion: apps/v2kind: Deploymentmetadata: name: knowsystem-v2 namespace: prod-knowsystem labels: app: knowsystemspec: replicas: 1 selector: matchLabels: app: knowsystem version: v2#关联pod的标签 template: metadata: labels: app: knowsystem version: v2#通过配置一个version=v2的标签来声明程序的版本是V2 spec: containers: - image: jiangxlrepo/know-system:v2 name: knowsystem-v2
3.3.编写Service资源编排文件
[root@k8s-master istio-knowsystem]# vim knowsystem-svc.yaml apiVersion: v1kind: Servicemetadata: name: knowsystem-svc namespace: prod-knowsystem-svc labels: app: knowsystemspec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: knowsystem#将标签app=knowsystem的pod全部关联进来,此时V1和V2版本的Pod就会都接入Service资源中
3.4.编写Gateway以及VirtualService资源编排文件
[root@k8s-master istio-knowsystem]# vim knowsystem-gw-vs.yaml apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata: name: knowsystem-gw namespace: prod-knowsystemspec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "knowsystem.jiangxl.com"#绑定程序使用的域名,支持泛域名,如*.jiangxl.com---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: knowsystem-vs namespace: prod-knowsystemspec: hosts: - "knowsystem.jiangxl.com"#绑定程序使用的域名,支持泛域名,如*.jiangxl.com gateways: - knowsystem-gw http: - route: - destination: host: knowsystem-svc port: number: 80
3.5.创建所有资源完成部署
1.创建所有资源[root@k8s-master istio-knowsystem]# kubectl apply -f knowsystem-v1.yaml -f knowsystem-v2.yaml -f knowsystem-svc.yaml -f knowsystem-gw.yaml deployment.apps/knowsystem-v1 createddeployment.apps/knowsystem-v2 createdservice/knowsystem-svc createdgateway.networking.istio.io/knowsystem-gw createdvirtualservice.networking.istio.io/knowsystem-vs created2.查看资源的状态[root@k8s-master istio-knowsystem]# kubectl get svc,pod -n prod-knowsystemNAMETYPE CLUSTER-IPEXTERNAL-IP PORT(S) AGEservice/knowsystem-svc ClusterIP 10.108.224.124 80/TCP 29sNAME READY STATUS RESTARTS AGEpod/knowsystem-v1-96d57f6c-hkknr 2/2 Running 0 29spod/knowsystem-v2-687b85db56-xmb88 2/2 Running 0 29s3.观察Service资源关联的Pod,分别是V1和V2版本的pod资源[root@k8s-master istio-knowsystem]# kubectl get ep -n prod-knowsystemNAME ENDPOINTS AGEknowsystem-svc 100.64.169.151:80,100.64.169.153:80 37s
3.6.访问知识点系统
绑定hosts解析。
192.168.20.15 knowsystem.jiangxl.com