ps:istio
的官方提供的 bookinfo
例子已经很齐全了,但我很讨厌拿 bookinfo
当作示例。因为是别人已经提供好的,包括 yaml
文件你自己根本没有从中学习到什么,所以想自己写一些 demo
、yaml
来使用。
step1: 前提
在这里默认你已经自己提供了 demo,才可以往下进行。demo 可以如下图所示,默认上线 v1 版本
圈住的服务是 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
创建并查看:
测试:
[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
,没有问题。
测试:
[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: 权重灰度发布
晚上写。