OpenShift 4 之Istio-Tutorial (4) 流量控制和灰度发布

邹曦之
2023-12-01

OpenShift 4.x HOL教程汇总
说明:本文已经在OpenShift 4.12环境中验证

本章节我们先部署一个微服务的新版本,然后基于Istio流量控制功能实现灰度发布的微服务版本升级切换。通过VirtualService的流量控制机制可以实现不同场景的灰度发布,本文实现以下两种灰度发布。

按流量比例灰度发布

  1. 部署v2版本的recommendation微服务,然后确认部署进度。
$ oc apply -f recommendation/kubernetes/Deployment-v2.yml -n ${ISTIO_APP}
$ oc get pod -n ${ISTIO_APP} -l app=recommendation
NAME                                 READY   STATUS    RESTARTS   AGE
recommendation-v1-dd8544f7c-s64sx    2/2     Running   0          56m
recommendation-v2-5494578985-mx7ft   2/2     Running   0          18m
  1. 执行命令访问customer微服务(不要停止对customer微服务的连续访问),由于此时没有设置对recommendation的转发策略,因此请求是轮训发给recommendation-v1和recommendation-v2。
$ ./scripts/run.sh ${INGRESS_GATEWAY}/customer
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 1
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 96
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 2
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 97
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 3
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 98
...
  1. 然后在一个新的命令窗口执行以下命令创建名为recommendation的VirtualService和名为recommendation的DestinationRule对象,来实现将请求100%发到recommendation-v2上。
    在istiofiles/virtual-service-recommendation-v2.yml中定义VirtualService对象。其中“subset: version-v2”对应的是后面DestinationRule对象中“name: version-v1”的“subset”。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService                    
metadata:                               
  name: recommendation                  
spec:                                   
  hosts:                                
  - recommendation                      
  http:                                 
  - route:                              
    - destination:                      
        host: recommendation           # host对应的recommendation的Service的url,可以是short或long的url
        subset: version-v2             # subset对应的是DestinationRule中的subset名称,DestinationRule会按照这个lable找到对应的pod
      weight: 100

在istiofiles/destination-rule-recommendation-v1-v2.yml中定义DestinationRule对象。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: recommendation
spec:
  host: recommendation
  subsets:
  - labels:
      version: v1					# DestinationRule会按照这个lable找到对应的pod
    name: version-v1
  - labels:
      version: v2
    name: version-v2

执行以下命令分别创建VirtualService和DestinationRule,注意:当只运行第一个命令创建VirtualService后,第一个窗口会报错“customer => Error: 500 - ErrorInternal Server Error”,这是由于没有找到VirtualService中使用的subnet,这个subnet是在DestinationRule中定义的。

$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-recommendation-v2.yml
$ oc apply -n ${ISTIO_APP} -f istiofiles/destination-rule-recommendation-v1-v2.yml
  1. 查看第一个命令窗口,从输出确认请求被都发到了v2版的recommendation微服务上了。
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 24
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 25
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 26
...
  1. 在第二个窗口执行以下命令可以将请求全部转发到v1版的recommendation微服务上。
$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-recommendation-v1.yml
  1. 查看第一个命令窗口,从输出确认请求被都发到了v1版的recommendation微服务上了。
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 159
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 160
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 161
...
  1. 在第二个窗口执行以下命令可以将请求按照"9:1"的比例发给v1版的recommendation微服务和v2版的recommendation微服务上。
    在istiofiles/virtual-service-recommendation-v1_and_v2.yml中定义的分发策略。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
        subset: version-v1
      weight: 90
    - destination:
        host: recommendation
        subset: version-v2
      weight: 10

执行命令,更新VirtualService策略。

$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-recommendation-v1_and_v2.yml
  1. 在第二个窗口执行以下命令可以将请求按照"3:1"的比例发给v1版的recommendation微服务和v2版的recommendation微服务上。
$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-recommendation-v1_and_v2_75_25.yml
  1. 在第一个命令窗口终止run.sh运行。

按请求header灰度发布

通过VirtualService对请求转发分配策略,我们还可实现其它复杂的场景,其中灰度发布就是一种常用的场景。

按照浏览器厂商进行灰度发布

  1. 在istiofiles/virtual-service-safari-recommendation-v2.yml中定义的策略是让Safari浏览器访问的是v2版微服务的recommendation,而其它浏览器访问的是v1版的recommendation。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - match:
    - headers:
        baggage-user-agent:
          regex: .*Safari.*
    route:
    - destination:
        host: recommendation
        subset: version-v2
  - route:
    - destination: 
        host: recommendation
        subset: version-v1

执行命令修改VirtualService策略。

$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-safari-recommendation-v2.yml
  1. 模拟发送Safari浏览器和Firefox浏览器请求,确认返回结果。其中Safari浏览器访问的是v2版微服务的recommendation,而Firefox浏览器访问呢的v1版的recommendation。
$ curl -A Safari $INGRESS_GATEWAY/customer
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 24
$ curl -A Firefox $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 276

按浏览器类型进行灰度发布

  1. 执行命令修改VirtualService策略,让mobile浏览器访问的是v2版微服务的recommendation,而其它浏览器访问的是v1版的recommendation。
$ oc apply -n ${ISTIO_APP} -f istiofiles/virtual-service-mobile-recommendation-v2.yml 
  1. 模拟发送mobile浏览器和一般请求,确认返回结果的差异。
$ curl -A "Mozilla/5.0 Version/5.0.2 Mobile/8J2 Safari" $INGRESS_GATEWAY/customer
customer => preference => recommendation v2 from 'recommendation-v2-5494578985-mx7ft': 25
$ curl $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from 'recommendation-v1-dd8544f7c-s64sx': 277
 类似资料: