利用Istio的virtualservice sourcelabel配置实现全链路的灰度发布
一、背景
用户在产品优化迭代时直接将新版本上线发布,一旦遇到线上事故或BUG,影响极大,解决问题周期较长,甚至有时不得不回滚到前一版本,严重影响了使用体验。同时也存在多个服务同时有新版本进行发布,新版本之间要求流量匹配。这时我们可以通过istio进行灰度流量控制。
二、全链路灰度发布以及sourceLabel功能原理
当前集群中,多个微服务,每个微服务都有多个版本,如果能做到流量传递只会发生在同版本的服务之间,就能做到全链路的灰度发布。如下图所示,在入口网关流量按照权重分配到appa的v1版本和v2版本后,appa的v1版本pod访问appb业务时,只会访问appb的v1版本;而appa的v2版本pod访问appb业务时,只会访问appb的v2版本。
我们可以利用virtualService中的sourceLabels能力对源负载进行标签匹配,如下virtualService配置说明,如果源pod label为 app:appa & subset: v1(即上图的appa-v1)访问appb service,则转发给 host:appb & subnet:v1 对应的endpoint(即上图的appb-v1)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-appb
spec:
hosts:
- appb
http:
- route:
- destination:
host: appb
subset: v1
match:
- sourceLabels: # 关键配置,用于规定源Pod为appa-v1访问appb对应的转发后端
app: appa
version: v1
- route:
- destination:
host: appb
subset: v2
match:
- sourceLabels: # 关键配置,用于规定源Pod为appa-v2访问appb对应的转发后端
app: appa
version: v2
- route:
- destination: # 默认规则,用于规定其他源Pod访问appb对应的转发后端
host: appb
subset: v1
该virtualService创建后,会作用到所有的envoy上(包括appa-v1和appa-v2),当业务访问appb clusterip或者域名后,对应的envoy就会拦截业务流量,根据virtualService、destinationRule规则判断进行后端选择。
三、操作示例
3.1 部署deployment、service
部署appa的v1和v2版本、app2的v1和v2版本和appa、appb对应的service
apiVersion: v1
kind: Service
metadata:
name: appa
labels:
app: appa
service: appa
spec:
ports:
- port: 8000
name: http
selector:
app: appa
---
apiVersion: v1
kind: Service
metadata:
name: appb
labels:
app: appb
service: appb
spec:
ports:
- port: 8000
name: http
selector:
app: appb
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appa-v1
labels:
app: appa
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: appa
version: v1
template:
metadata:
labels:
app: appa
version: v1
spec:
imagePullSecrets:
- name: default-secret
containers:
- name: default
image: swr.cn-north-4.myhuaweicloud.com/k8s-solution/go-http-sample:1.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: v1
- name: app
value: appa
- name: upstream_url
value: "http://appb:8000/"
ports:
- containerPort: 8000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appb-v1
labels:
app: appb
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: appb
version: v1
template:
metadata:
labels:
app: appb
version: v1
spec:
imagePullSecrets:
- name: default-secret
containers:
- name: default
image: swr.cn-north-4.myhuaweicloud.com/k8s-solution/go-http-sample:1.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: v1
- name: app
value: appb
ports:
- containerPort: 8000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appa-v2
labels:
app: appa
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: appa
version: v2
template:
metadata:
labels:
app: appa
version: v2
spec:
imagePullSecrets:
- name: default-secret
containers:
- name: default
image: swr.cn-north-4.myhuaweicloud.com/k8s-solution/go-http-sample:1.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: v2
- name: app
value: appa
- name: upstream_url
value: "http://appb:8000/"
ports:
- containerPort: 8000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appb-v2
labels:
app: appb
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: appb
version: v2
template:
metadata:
labels:
app: appb
version: v2
spec:
imagePullSecrets:
- name: default-secret
containers:
- name: default
image: swr.cn-north-4.myhuaweicloud.com/k8s-solution/go-http-sample:1.0
imagePullPolicy: IfNotPresent
env:
- name: version
value: v2
- name: app
value: appb
ports:
- containerPort: 8000
3.2 打通入口gateway按比例转发到appa的v1和v2版本
gateway到appa可以按照比例,也可以按照head信息等,由于本文重点表述sourceLabels能力,不做详细说明。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: dr-appa
spec:
host: appa
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-gateway-appa
namespace: istio-system
spec:
gateways:
- istio-system/app-gw
- mesh
hosts:
- 192.168.1.106
- appa.default.svc.cluster.local
http:
- delegate:
name: vs-appa
namespace: default
match:
- uri:
prefix: /
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-appa
spec:
http:
- match:
- gateways:
- istio-system/app-gw
route:
- destination:
host: appa
subset: v1
weight: 10
- destination:
host: appa
subset: v2
weight: 90
- match:
- gateways:
- mesh
route:
- destination:
host: appa
subset: v1
weight: 100
- destination:
host: appa
subset: v2
weight: 0
3.3 通过sourceLabels控制源Pod,使得不同label源Pod定向访问后端
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: dr-appb
spec:
host: appb
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-appb
spec:
hosts:
- appb
http:
- route:
- destination:
host: appb
subset: v1
match:
- sourceLabels:
app: appa
version: v1
- route:
- destination:
host: appb
subset: v2
match:
- sourceLabels:
app: appa
version: v2
- route:
- destination:
host: appb
subset: v1
3.4 测试验证
访问入口网关gateway ip,while true;do curl http://gatewayip:86/;sleep 1;echo "";done 可以回显appa 和 appb的响应通道
从上图可见,appa v2的pod 访问appb ,只会访问appb的v2 ,appa v1的pod访问appb,只会访问appb的v1,实现了全链路的灰度发布。
四、优缺点分析
- 优点:在开源istio的基础上,可以借助原生的sourceLabels进行治理,实现全链路的流量拓扑。配置简单明了,四层流量七层流量均可使用sourceLables进行路由匹配
- 缺点:当多个微服务多版本上线时,访问链路中某个微服务只有一个版本,下游流量汇聚到该服务后,该服务发出的流量不再携带多版本的labels,则流量标记会被清除
如果我们强行将appc部署成两个服务appc-v1和appc-v2,提供相同的能力,也可以继续使用sourceLabels全链路。
- 点赞
- 收藏
- 关注作者
评论(0)