代码继续接着前面的文章【云原生】整合K8s + SpringCloudK8s + gRpc + RocketMQ + Istio + Envoy,本篇文章我们测试下请求路由功能。
生产中我们上了个新接口或者新功能,一般会经过 内灰 -> 外灰5% -> 外灰10% ...... 外灰100%的过程,这篇文章我们就来模拟下。为了方便测试,我修改yaml文件,同一个应用部署多个版本,每个版本代表着一个新的功能。
apiVersion: v1
kind: Namespace
metadata:name: service-k8s-demolabels:name: service-k8s-demo---apiVersion: v1
kind: ServiceAccount
metadata:name: service-k8s-demonamespace: service-k8s-demo---kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:namespace: service-k8s-demoname: service-k8s-demo
rules:- apiGroups:- ""resources:- services- configmaps- endpoints- nodes- pods- secrets- namespacesverbs:- get- list- watch---apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: service-k8s-demonamespace: service-k8s-demo
subjects:
- kind: ServiceAccountname: service-k8s-demonamespace: service-k8s-demo
roleRef:kind: ClusterRolename: service-k8s-demoapiGroup: rbac.authorization.k8s.io---apiVersion: apps/v1
kind: Deployment
metadata:name: service-provider-v1namespace: service-k8s-demolabels:app: service-providerversion: v1
spec:replicas: 1selector:matchLabels:app: service-providerversion: v1template:metadata:name: service-providerlabels:app: service-providerversion: v1spec:containers:- name: service-providerimage: service-provider:1.0imagePullPolicy: IfNotPresentenv:- name: SPRING_PROFILES_ACTIVEvalue: "dev"ports:- name: httpprotocol: TCPcontainerPort: 30000- name: grpcprotocol: TCPcontainerPort: 9090serviceAccountName: service-k8s-demorestartPolicy: Always
---
apiVersion: apps/v1
kind: Deployment
metadata:name: service-provider-v2namespace: service-k8s-demolabels:app: service-providerversion: v2
spec:replicas: 1selector:matchLabels:app: service-providerversion: v2template:metadata:name: service-providerlabels:app: service-providerversion: v2spec:containers:- name: service-providerimage: service-provider:1.0imagePullPolicy: IfNotPresentenv:- name: SPRING_PROFILES_ACTIVEvalue: "dev"ports:- name: httpprotocol: TCPcontainerPort: 30000- name: grpcprotocol: TCPcontainerPort: 9090serviceAccountName: service-k8s-demorestartPolicy: Always
---
apiVersion: apps/v1
kind: Deployment
metadata:name: service-provider-v3namespace: service-k8s-demolabels:app: service-providerversion: v3
spec:replicas: 1selector:matchLabels:app: service-providerversion: v3template:metadata:name: service-providerlabels:app: service-providerversion: v3spec:containers:- name: service-providerimage: service-provider:1.0imagePullPolicy: IfNotPresentenv:- name: SPRING_PROFILES_ACTIVEvalue: "dev"ports:- name: httpprotocol: TCPcontainerPort: 30000- name: grpcprotocol: TCPcontainerPort: 9090serviceAccountName: service-k8s-demorestartPolicy: Always
---apiVersion: v1
kind: Service
metadata:name: service-providernamespace: service-k8s-demo
spec:selector:app: service-providerports:- port: 80targetPort: 30000name: http- port: 9090targetPort: 9090name: grpctype: NodePort
dashboard里的展示
为每个应用定义版本
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: service-provider-rule-allnamespace: service-k8s-demo
spec:host: service-providersubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v3labels:version: v3
---
一般使用userId来做,把内部员工的userId收集起来,先让他们来体验。但是我没有测试成功,而且内灰用户有很多,match的规则支持exact、prefix和regex这三种,所以有很多内灰用户的话,该怎么配呢?有大佬知道可以告诉下小弟我哦。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: service-k8s-demo-gatewaynamespace: service-k8s-demo
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 31400name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-k8s-demo-virtual-servicenamespace: service-k8s-demo
spec:hosts:- "maple.example.com"gateways:- service-k8s-demo-gatewayhttp:- match:- uri:prefix: /consumerroute:- destination:host: service-consumerport:number: 80- match:- headers:user-id:exact: "123456"- uri:prefix: /providerroute:- destination:host: service-providersubset: v1- route:- destination:host: service-providerport:number: 80subset: v3
v1给50%流量,v2给30%,v3给20%,这里是测试成功的。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: service-k8s-demo-gatewaynamespace: service-k8s-demo
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 31400name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-k8s-demo-virtual-servicenamespace: service-k8s-demo
spec:hosts:- "maple.example.com"gateways:- service-k8s-demo-gatewayhttp:- match:- uri:prefix: /consumerroute:- destination:host: service-consumerport:number: 80- match:- uri:prefix: /providerroute:- destination:host: service-providersubset: v1port:number: 80weight: 50- destination:host: service-providersubset: v2port:number: 80weight: 30- destination:host: service-providersubset: v3port:number: 80weight: 20
也可以针对某个接口配置,下面我就为 /provider/grpc/queryMember 这个接口配置路由到v3版本上,但是这里需要注意一下,要把最细分的 exact: /provider/grpc/queryMember 放在另一个规则prefix: /provider的前面,不然它按照顺序执行,就会被 prefix: /provider 直接拦截掉了。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: service-k8s-demo-gatewaynamespace: service-k8s-demo
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 31400name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-k8s-demo-virtual-servicenamespace: service-k8s-demo
spec:hosts:- "maple.example.com"gateways:- service-k8s-demo-gatewayhttp:- match:- uri:prefix: /consumerroute:- destination:host: service-consumerport:number: 80- match:- uri:exact: /provider/grpc/queryMemberroute:- destination:host: service-providersubset: v3port:number: 80- match:- uri:prefix: /providerroute:- destination:host: service-providersubset: v1port:number: 80weight: 50- destination:host: service-providersubset: v2port:number: 80weight: 30- destination:host: service-providersubset: v3port:number: 80weight: 20
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: service-k8s-demo-gatewaynamespace: service-k8s-demo
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 31400name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-k8s-demo-virtual-servicenamespace: service-k8s-demo
spec:hosts:- "maple.example.com"gateways:- service-k8s-demo-gatewayhttp:- match:- uri:prefix: /consumerroute:- destination:host: service-consumerport:number: 80- match:- uri:prefix: /providerroute:- destination:host: service-providerport:number: 80subset: v3
测试
发了5次请求,结果发现只有v3打印了日志,测试成功
service-consumer的代码里硬编码等待2s
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: service-k8s-demo-gatewaynamespace: service-k8s-demo
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 31400name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-k8s-demo-virtual-servicenamespace: service-k8s-demo
spec:hosts:- "maple.example.com"gateways:- service-k8s-demo-gatewayhttp:- match:- uri:prefix: /consumerroute:- destination:host: service-consumerport:number: 80subset: v1- match:- uri:exact: /provider/grpc/queryMemberroute:- destination:host: service-providersubset: v3port:number: 80timeout: 0.5s #测试超时- match:- uri:prefix: /providerroute:- destination:host: service-providersubset: v1port:number: 80weight: 50 #测试切流- destination:host: service-providersubset: v2port:number: 80weight: 30- destination:host: service-providersubset: v3port:number: 80weight: 20