微服务软件架构下,业务新功能上线前搭建完整的一套测试系统进行验证是相当费人费时的事,随着所拆分出微服务数量的不断增大其难度也俞大。这一整套测试系统所需付出的机器成本往往也不低,为了保证应用新版本上线前的功能正确性验证效率这套系统还必须一直单独维护好。当业务变得庞大且复杂时,往往还得准备多套,这是整个行业共同面临且难解的成本和效率挑战。如果能在同一套生产系统中完成新版本上线前的功能验证的话,所节约的人力和财力是相当可观的。
除了开发阶段的功能验证,生产环境中引入灰度发布才能更好地控制新版本软件上线的风险和爆炸半径。灰度发布是将具有一定特征或者比例的生产流量分配到需要被验证的服务版本中,以观察新版本上线后的运行状态是否符合预期。
阿里云基于 Service Mesh 所构建的全链路灰度方案,能很好帮助解决以上两个场景的问题。
关于 ASM 服务网格全链路流量管理实现原理,请参考 《基于 Istio 的全链路灰度方案探索和实践》
前提条件
Demo 背景
本文所演示的灰度发布场景如下:
以 Bookinfo 为例,入口流量会带上期望的 tag 分组,sidecar 通过获取请求上下文(Header 或 Context) 中的期望 tag,将流量路由分发到对应 tag 分组,若对应 tag 分组不存在,默认会 fallback 路由到 base 分组,具体 fallback 策略可配置。
操作步骤
一:ASM 实例和 ACK 集群准备
A. 创建 ASM 专业版实例
- 登录ASM控制台。
- 在左侧导航栏,选择服务网格 > 网格管理。
- 在网格管理页面单击创建新网格。
注意 需要创建 ASM 专业版。
B. 将 ACK 集群加入 ASM 专业版实例
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏选择数据平面(服务发现) > Kubernetes集群,然后在右侧页面单击添加。
- 在添加集群面板,选中需要添加的集群,然后单击确定。
C. 创建 ASM 入口网关
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格详情页面左侧导航栏单击ASM网关。
- 在ASM网关页面,单击创建
二:部署 Bookinfo 示例应用
A. 开启命名空间注入
1、分别在 ACK 和 ASM 控制台创建 同名命名空间
2、开启该命名空间自动注入
B. 部署 Bookinfo 示例应用
1、在 ACK 已开启自动注入的命名空间中部署示例应用
################################################################################################## # Details service ################################################################################################## apiVersion: v1 kind: Service metadata: name: details labels: app: details service: details spec: ports: - port: 9080 name: http selector: app: details --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-details labels: account: details --- apiVersion: apps/v1 kind: Deployment metadata: name: details-v1 labels: app: details version: v1 spec: replicas: 1 selector: matchLabels: app: details version: v1 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: details version: v1 spec: serviceAccountName: bookinfo-details containers: - name: details image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-details-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Ratings service ################################################################################################## apiVersion: v1 kind: Service metadata: name: ratings labels: app: ratings service: ratings spec: ports: - port: 9080 name: http selector: app: ratings --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-ratings labels: account: ratings --- apiVersion: apps/v1 kind: Deployment metadata: name: ratings-v1 labels: app: ratings version: v1 spec: replicas: 1 selector: matchLabels: app: ratings version: v1 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: ratings version: v1 spec: serviceAccountName: bookinfo-ratings containers: - name: ratings image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-ratings-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ######### #Ratings ######### apiVersion: apps/v1 kind: Deployment metadata: name: ratings-v2 labels: app: ratings version: v2 spec: replicas: 0 selector: matchLabels: app: ratings version: v2 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: ratings version: v2 spec: serviceAccountName: bookinfo-ratings containers: - name: ratings image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/asmratings:v2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 --- ################################################################################################## # Reviews service ################################################################################################## apiVersion: v1 kind: Service metadata: name: reviews labels: app: reviews service: reviews spec: ports: - port: 9080 name: http selector: app: reviews --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-reviews labels: account: reviews --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v1 labels: app: reviews version: v1 spec: replicas: 1 selector: matchLabels: app: reviews version: v1 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: reviews version: v1 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-reviews-v1:1.16.2 imagePullPolicy: IfNotPresent env: - name: LOG_DIR value: "/tmp/logs" ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp - name: wlp-output mountPath: /opt/ibm/wlp/output volumes: - name: wlp-output emptyDir: {} - name: tmp emptyDir: {} --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v2 labels: app: reviews version: v2 spec: replicas: 0 selector: matchLabels: app: reviews version: v2 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: reviews version: v2 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-reviews-v2:1.16.2 imagePullPolicy: IfNotPresent env: - name: LOG_DIR value: "/tmp/logs" ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp - name: wlp-output mountPath: /opt/ibm/wlp/output volumes: - name: wlp-output emptyDir: {} - name: tmp emptyDir: {} --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v3 labels: app: reviews version: v3 spec: replicas: 0 selector: matchLabels: app: reviews version: v3 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: reviews version: v3 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-reviews-v3:1.16.2 imagePullPolicy: IfNotPresent env: - name: LOG_DIR value: "/tmp/logs" ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp - name: wlp-output mountPath: /opt/ibm/wlp/output volumes: - name: wlp-output emptyDir: {} - name: tmp emptyDir: {} --- ################################################################################################## # Productpage services ################################################################################################## apiVersion: v1 kind: Service metadata: name: productpage labels: app: productpage service: productpage spec: ports: - port: 9080 name: http selector: app: productpage --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-productpage labels: account: productpage --- apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v1 labels: app: productpage version: v1 spec: replicas: 1 selector: matchLabels: app: productpage version: v1 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: productpage version: v1 ASM_TRAFFIC_TAG: prod spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/examples-bookinfo-productpage-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {} --- apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v2 labels: app: productpage version: v2 spec: replicas: 0 selector: matchLabels: app: productpage version: v2 template: metadata: annotations: sidecar.istio.io/logLevel: trace labels: app: productpage version: v2 ASM_TRAFFIC_TAG: gray spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: registry-vpc.cn-shenzhen.aliyuncs.com/containerdemo/asmproductpage:v2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {} ---
2、在 ASM 部署 Gateway、VirtualService 资源,通过 Istio-ingressgateway 暴露 Bookinfo 服务
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage subset: v1 port: number: 9080 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: productpage spec: host: productpage subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: gray labels: version: v2 - name: prod labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3 - name: gray labels: version: v2 - name: prod labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: ratings spec: host: ratings subsets: - name: v1 labels: version: v1 - name: gray labels: version: v2 - name: prod labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: details spec: host: details subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 ---
测试:http://<istio-ingressgatway SLB/productpage
三:全链路灰度配置
A. 全链路灰度配置
在 ASM 部署 TafficLabel 资源
apiVersion: istio.alibabacloud.com/v1beta1 kind: TrafficLabel metadata: name: default spec: rules: - labels: - name: trafficLabel valueFrom: - $getContext(x-request-id) //若使用aliyun arms,对应为x-b3-traceid - $(localLabel) attachTo: - opentracing # 表示生效的协议,空为都不生效,*为都生效 protocols: "*"
ASM Pro 中引入了全新的 TrafficLabel CRD 用于定义 Sidecar 所需透传的流量标签从哪里获取。下面所例举的 YAML 文件中,定义了流量标签来源和需要将标签存储 OpenTracing 中(具体是 x-trace 头)。其中流量标的名为 trafficLabel,取值依次从 $getContext(x-request-id) 到最后从本地环境的$(localLabel)中获取
B. 灰度 Reviews 服务
- 在 ASM 部署 VirtualService 资源
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: $trafficLabel weight: 100 fallback: case: noinstances|noavailabled target: host: reviews subset: prod
- 新部署 reviews-v2 服务(副本从0扩为1),测试:http://<istio-ingressgatway SLB/productpage
A. 灰度 Ratings 服务
- 在 ASM 部署 VirtualService 资源
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - route: - destination: host: ratings subset: $trafficLabel weight: 100 fallback: case: noinstances|noavailabled target: host: ratings subset: prod
- 新部署 ratings-v2 服务(副本从0扩为1),测试:http://<istio-ingressgatway SLB/productpage