Istio 基于“权重”、“Headers” 的灰度发布

ps:istio 的官方提供的 bookinfo 例子已经很齐全了,但我很讨厌拿 bookinfo 当作示例。因为是别人已经提供好的,包括 yaml 文件你自己根本没有从中学习到什么,所以想自己写一些 demoyaml 来使用

step1: 前提

在这里默认你已经自己提供了 demo,才可以往下进行。demo 可以如下图所示,默认上线 v1 版本
Istio 基于“权重”、“Headers” 的灰度发布_第1张图片
圈住的服务是 demo 其他无视。好的,v1 版本现在正常在线,现在测试一下 v1 版本然后上线 v2。

[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1

step2: 创建默认路由

1: 创建默认路由,默认路由到 v1 版本,防止我们上线 v2 版本之后大量的流量涌到 v2 版本,这样就傻了。不管是 headers 灰度发布还是权重灰度发布,在上线 v2 版本之前都要有默认的路由规则,默认到 v1 版本。
VirtualService 全部转发到 v1,不理解 VirtualService 以及 DestinationRule 的查看我前一篇博客 Istio VirtualService 结合 DestinationRule 基础使用。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: demo-default
  namespace: default
spec:
  host: java-demo-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-default
  namespace: default
spec:
  hosts:
  - java-demo-service
  http:
  - route:
    - destination:
        host: java-demo-service
        subset: v1

创建并查看:
Istio 基于“权重”、“Headers” 的灰度发布_第2张图片
测试:

[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1

没得问题,下一步灰度发布

step3: 灰度发布

上线 v2 版本。现在上线 v2 版本之后流量仍然是全部到 v1,没有问题。
Istio 基于“权重”、“Headers” 的灰度发布_第3张图片
测试:

[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsam
张三小企业一v1

step3.1: headers 灰度发布

更新创建默认路由时的模板。重要的部分已经注释

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-default
  namespace: default
spec:
  hosts:
  - java-demo-service
  http:
   # 请求匹配 headers 里面包含 test-user=tom 的流量转发到 v2 版本
   # 可以理解为 headers 里面包含 test-user=tom 的流量全部都是测试流量
   # 这里 test-user=tom 可以是任何,例如 test=zhangsan、aaa=bbb 等等
   - match:
     - headers:
         test-user:
           exact: tom
     route:
     - destination:
         host: java-demo-service
         subset: v2
  - route:
    - destination:
        host: java-demo-service
        subset: v1

在这里插入图片描述
测试:

[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=tom
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=tom
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=tom
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=tom
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=tom
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=lisi
张三小企业一v1

可以非常清楚的看出,name=tom 的流量全部转发到了 v2,我这里虽然是 name=tom 并不像我上面说的 test-user=tom 是因为我在源码里面接收的是一个 name 如下所示,当 name equals tom 时,我会直接在 headers 里面填充 headers.add("test-user", "tom")

@RequestMapping("/demo/client")
@RestController
public class ClientController {

    @GetMapping("/hello")
    public String hello(String name) {
        HttpHeaders headers = new HttpHeaders();
        if ("tom".equals(name)){
            headers.add("test-user", "tom");
        }
		..........
        return response.getBody();
    }
}

好了,基于 headers 的灰度发布基本完成了 90%,这个时候如果测试没有出现问题的话,就可以下线 v1 版本,然后将默认流量切换到 v2 版本。下线版本我就不试了,直接执行 kubectl delete deploy xxx -n namespace 即可。将流量全部切换到 v2 版本也很简单,如下所示:
同样是更新创建默认路由时的模板,把 match 部分删除,然后将 subset 修改为 v2 路由到 v2 版本。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: demo-default
  namespace: default
spec:
  host: java-demo-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-default
  namespace: default
spec:
  hosts:
  - java-demo-service
  http:
  - route:
    - destination:
        host: java-demo-service
        subset: v2

测试:

[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=qwert
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=qwert
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=adafsdfasf
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=wanger
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=sili
张三小企业一v2
[root@node4 simple]# curl 10.96.105.49:8083/demo/client/hello?name=zhangsan
张三小企业一v2

截止到这里,istio 基于 headers 的灰度发布已经成功完毕。

step3.2: 权重灰度发布

晚上写。

step4: 总结

你可能感兴趣的:(istio)