通过Nginx Ingress提供的全链路灰度能力,可以在不需要修改任何您的业务代码的情况下,实现全链路流量控制。本文介绍通过Nginx Ingress实现全链路灰度功能。
前提条件
- 已创建Kubernetes集群,请参见创建Kubernetes托管版集群。
- 已开通MSE微服务治理专业版,请参见开通MSE微服务治理。
背景信息
在微服务场景中,当您部署的Spring Cloud应用或Dubbo应用存在升级版本时,由于应用间的调用是随机的,会导致无法将具有一定特征的流量路由到应用的目标版本。全链路流量控制功能将应用的相关版本隔离成一个独立的运行环境(即泳道),通过设置Ingress路由规则,将满足规则的请求流量路由到目标版本应用。
本文以电商架构中的下单场景为例介绍从Ingress网关到微服务的全链路流控功能。假设应用的架构由Ingress-nginx网关以及后端的微服务架构(Spring Cloud)组成,后端调用链路有3个:交易中心(A)、商品中心(B)、库存中心(C),可以通过客户端或者是HTML来访问后端服务,这些服务之间通过Nacos注册中心实现服务发现。
客户下单后流量从Ingress网关进来,调用交易中心,交易中心再调用商品中心,商品中心调用下游的库存中心。

使用限制
由于全链路灰度功能整合了标签路由功能,因此不推荐已经加入全链路流量控制的应用同时配置金丝雀发布、标签路由规则。限制项 | 限制值 | 备注 |
---|---|---|
Spring Cloud版本 | Spring Cloud Edgware及以上版本。 | 无。 |
Dubbo版本 | 2.5.3~2.7.8 | Dubbo 3.0+版本支持当前处于灰度中,如有场景需求,请加入钉群(钉群号:34754806)联系技术支持。 |
客户端类型 |
| 无。 |
Java应用JDK版本 | 目前支持JDK 1.6、1.7、1.8版本应用接入 | JDK 11版本当前处于灰度中,如有场景需求,请加入钉群(钉群号:34754806)联系技术支持。 |
负载均衡类型 |
| 无。 |
Spring Cloud Gateway版本 | Spring Cloud Gateway 2.1.0.RELEASE+ | 无。 |
Spring Cloud Zuul版本 | 1.3.x | 无。 |
注册中心类型 |
| 微服务治理能力无关注册中心,可以是MSE托管注册中心,也可以是自建注册中心。 |
名词解释
- 泳道
为相同版本应用定义的一套隔离环境。只有满足了流控路由规则的请求流量才会路由到对应泳道里的打标应用。一个应用可以属于多个泳道,一个泳道可以包含多个应用,应用和泳道是多对多的关系。
- 泳道组
泳道的集合。泳道组的作用主要是为了区分不同团队或不同场景。
准备工作
安装Ingress-nginx组件
- 登录ack-ingress-nginx应用市场,在页面右上方单击一键部署,在创建面板中选择集群和命名空间,设置组件发布名称,然后单击下一步。说明 推荐使用默认命名空间kube-system。
- 在参数配置向导中确认组件参数信息,然后单击确定。安装完成后,在命名空间kube-system中出现ack-ingress-nginx-default应用,表示安装成功。
开启MSE微服务治理
开通微服务治理专业版:
- 单击开通MSE微服务治理。
- 微服务治理版本选择专业版,选中服务协议,然后单击立即开通。
关于微服务治理的计费详情,请参见计费概述。
安装MSE微服务治理组件:
- 在容器服务控制台左侧导航栏中,选择 。
- 在应用市场页面单击应用目录页签,然后搜索并单击ack-onepilot组件。
- 在ack-onepilot页面右上方单击一键部署,在创建面板中选择集群和命名空间,设置组件发布名称,然后单击下一步。说明 推荐使用默认的命名空间ack-onepilot。
- 在参数配置向导中确认组件参数信息,然后单击确定。
安装完成后,在命名空间ack-onepilot中出现ack-onepilot应用,表示安装成功。
为应用开启微服务治理:
- 登录MSE治理中心控制台。
- 在左侧导航栏选择 。
- 在K8s集群列表页面搜索目标集群,单击
图标,然后单击目标集群操作列下方的管理。
- 在集群详情页面命名空间列表区域,单击目标命名空间操作列下方的开启微服务治理。
- 在开启微服务治理对话框中单击确认。
部署Demo应用程序
- 在容器服务控制台左侧导航栏中,单击集群。
- 在集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情。
- 在集群管理页左侧导航栏中,选择 。
- 在无状态页面选择命名空间,然后单击使用YAML创建资源。
- 对模板进行相关配置,完成配置后单击创建。本文示例中部署A、B、C三个应用,每个应用分别部署一个基线版本和一个灰度版本;并部署一个Nacos server应用,用于实现服务发现。
- A应用
- 基线(base)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a spec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: annotations: msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30
- 灰度(gray)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-a labels: app: spring-cloud-a-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-a-new ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30
- 基线(base)版本YAML:
- B应用
- 基线(base)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b spec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: annotations: msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-b ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30
- 灰度(gray)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-b-new template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-b labels: app: spring-cloud-b-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-b-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30
- 基线(base)版本YAML:
- C应用
- 基线(base)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c spec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: annotations: msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT imagePullPolicy: Always name: spring-cloud-c ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30
- 灰度(gray)版本YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: annotations: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-c labels: app: spring-cloud-c-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT imagePullPolicy: IfNotPresent name: spring-cloud-c-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30
- 基线(base)版本YAML:
- Nacos Server应用YAML:
apiVersion: apps/v1 kind: Deployment metadata: name: nacos-server spec: replicas: 1 selector: matchLabels: app: nacos-server template: metadata: labels: app: nacos-server spec: containers: - env: - name: MODE value: standalone image: nacos/nacos-server:latest imagePullPolicy: Always name: nacos-server dnsPolicy: ClusterFirst restartPolicy: Always # Nacos Server Service 配置 --- apiVersion: v1 kind: Service metadata: name: nacos-server spec: ports: - port: 8848 protocol: TCP targetPort: 8848 selector: app: nacos-server type: ClusterIP
- A应用
- 针对入口应用A,配置两个K8s Service。
步骤一:创建泳道组
- 登录MSE治理中心控制台,并在顶部菜单栏选择地域。
- 在顶部菜单栏选择地域。
- 在左侧导航栏,选择 。
- 在全链路灰度页面,单击创建泳道组及泳道。如果您选择的微服务空间内已经创建过泳道组,则单击+创建泳道组。
- 在创建泳道组面板中设置泳道组相关参数,然后单击确定。
表 1. 泳道组配置参数说明 参数 描述 泳道组名称 自定义设置泳道组的名称。支持大小写字母、数字、短划线(-)和下划线(_),长度不超过64个字符。 入口类型 选择ingress/自建网关。 泳道组涉及所有应用 单击+添加灰度链路涉及应用,选择您的入口应用或入口网关所涉及的所有相关服务。 泳道组创建完成后,在全链路灰度页面的泳道组涉及应用区域出现您所创建的泳道组。请检查入口应用和所涉及的应用是否正确,如需变更泳道组信息,请单击右侧的图标并修改相关信息。
步骤二:创建泳道
- 在全链路灰度页面上方选择创建和泳道组时相同的微服务空间,然后底部单击点击创建第一个分流泳道。
如果您选择的微服务空间内已经创建过泳道,则单击创建泳道。
重要 加入全链路流量控制的应用,将不再支持金丝雀发布、标签路由等功能。 - 在创建泳道面板中设置流控泳道相关参数,然后单击确定。重要 如果您的网关应用是Ingress网关,需要去容器控制台配置Ingress路由规则。
表 2. 泳道配置参数说明 参数 描述 泳道名称 自定义设置流控泳道的名称。支持大小写字母、数字、短划线(-)和下划线(_),长度不超过64个字符。 配置应用标签 配置方式:在容器ACK控制台中去应用YAML的 spec.template.metadata.annotations
下增加alicloud.service.tag:{tag}
。添加应用 当STPE 2配置好后,单击刷新按钮,下拉框中会出现相应的标签列表,选择对应的标签,就会自动添加相应的应用。 - 在全链路灰度页面的流量分配面板查看泳道,有以下两种展现形式:
- 单击
图标,您可以查看该泳道的流量比例。
- 单击
图标,您可以设置该泳道上应用的状态。
操作列的开启或关闭有如下含义:- 开启:创建的泳道将会生效,即流量会按照泳道方式进行流转,会优先流向标记有当前泳道对应标签的应用版本,如果没有对应标签的应用版本则流向未打标的应用版本。
- 关闭:关闭创建的泳道,即该应用往后的流量会流向未打标的应用版本。
- 单击
- 配置流量入口的Ingress规则,访问
www.base.com
路由到A应用的base版本,访问www.gray.com
路由到A应用的gray版本。apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: spring-cloud-a-base spec: rules: - host: www.base.com http: paths: - backend: serviceName: spring-cloud-a-base servicePort: 20001 path: / --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: spring-cloud-a-gray spec: rules: - host: www.gray.com http: paths: - backend: serviceName: spring-cloud-a-gray servicePort: 20001 path: /
验证特征流量路由到目标应用
结果验证
- 访问
www.base.com
路由到基线环境- Curl命令:
curl -H"Host:www.base.com" http://106.14.XX.XX/a
- 返回结果:
A[172.18.XX.XX] -> B[172.18.XX.XX] -> C[172.18.XX.XX]%
- Curl命令:
- 访问
www.gray.com
路由到灰度环境- Curl命令:
curl -H"Host:www.gray.com" http://106.14.XX.XX/a
- 返回结果:
Agray[172.18.XX.XX] -> Bgray[172.18.XX.XX] -> Cgray[172.18.XX.XX]%
- Curl命令:
- 访问
查看打标应用的流量监控图
- 在全链路灰度页面单击目标泳道组页签。
- 在泳道组涉及应用区域单击目标应用名称,即可在右侧出现相应的QPS监控图。
查看所有应用监控图
您除了查看单个应用的监控图外,您还可以查看泳道组内所有应用的监控图。通过比对分析所有应用的监控图,可以分析出更多有用信息。
在QPS监控图右侧单击查看所有应用监控(流量逃逸观测),您可以查看该泳道所有应用的流量监控视图。
- 您可以查看同一时刻,调用的应用概览信息。
- 您可以分析流量逃逸问题,判断逃逸对象。