In a microservices architecture, some development requirements may involve changes to multiple microservice applications during a microservice call. In most cases, a canary environment or group is deployed for each microservice application to receive canary traffic. To allow traffic to flow from a canary environment of an upstream application into a canary environment of a downstream application, you must ensure that a request passes through canary environments. In this case, even if some microservice applications involved in the microservice call process do not have their respective canary environments, requests can still be routed to the canary environments of downstream applications. You can use the flexible routing feature provided by Alibaba Cloud Application Load Balancer (ALB) Ingress gateways and the end-to-end canary release capability provided by Microservices Engine (MSE) to meet the preceding requirements without the need to change your business code.
Implementation process
Precautions
If you use the Flannel network plug-in, the backend services of the ALB Ingress gateway must be of the NodePort or LoadBalancer type.
The vSwitch of the ALB Ingress gateway must be deployed in the same virtual private cloud (VPC) as the ACK cluster. For the regions that are supported by ALB Ingress gateways, see Supported regions and zones.
Sample scenario: Implement an end-to-end canary release by using domain name-based routing
In this example, the application architecture consists of an ALB Ingress gateway and Spring Cloud. Spring Cloud is a backend microservices architecture. Backend service calls involve three applications: a transaction center (Application A), a commodity center (Application B), and an inventory center (Application C). Client-based or HTML-based access to backend services is supported. A Nacos instance is used for service discovery among the applications.
You can use different domain names to distinguish between an online base environment and a canary environment. For a canary environment, you can separately configure a domain name. For example, requests that are destined for www.example.com
are routed to a canary environment, and requests that are destined for www.aliyundoc.com
are routed to a base environment.
The following figure shows the service call process. Service calls are initiated in the following order: ALB Ingress gateway > Application A > Application B > Application C. Application A can be a Spring Boot application.
Preparations
Create an ACK cluster
Create an ACK cluster whose Kubernetes version is V1.18 or later. For more information, see Create an ACK managed cluster or Create an ACK dedicated cluster.
Use kubectl to connect to an ACK cluster
Use kubectl to connect to an ACK cluster. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
Install the ALB Ingress Controller component
Install the ALB Ingress Controller component in the ACK cluster by using one of the following methods:
When you create an ACK cluster, select ALB Ingress for Ingress in the Component Configuration step to install the ALB Ingress Controller component in the cluster.
For an existing ACK cluster, you can install the ALB Ingress Controller component on the Add-ons page. For more information, see Manage components.
Enable MSE Microservices Governance for applications
On the Microservice Governance tab, activate Microservices Governance Professional Edition.
For more information about the billing of Microservices Governance, see Billing overview.
Enable Microservices Governance for microservice applications in the ACK cluster. You can select an appropriate method based on your business requirements. For more information, see Enable Microservices Governance for microservice applications in an ACK cluster.
Deploy demo applications
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, find the cluster that you want to manage and click its name. In the left-side pane, choose .
On the Deployments page, select a namespace and click Create from YAML. Then, configure the parameters, and click Create.
In this example, Applications A, B, and C are deployed. A base version and a canary version are deployed for each application. An application named nacos-server is deployed to implement service discovery.
# YAML code for the base version of Application A --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a spec: replicas: 2 selector: matchLabels: app: spring-cloud-a template: metadata: labels: msePilotCreateAppName: spring-cloud-a app: spring-cloud-a spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1 imagePullPolicy: Always name: spring-cloud-a ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # YAML code for the canary version of Application A --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-a-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-a-new strategy: template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-a app: spring-cloud-a-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre - name: profiler.micro.service.tag.trace.enable value: "true" image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1 imagePullPolicy: Always name: spring-cloud-a-new ports: - containerPort: 20001 livenessProbe: tcpSocket: port: 20001 initialDelaySeconds: 10 periodSeconds: 30 # YAML code for the base version of Application B --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b spec: replicas: 2 selector: matchLabels: app: spring-cloud-b strategy: template: metadata: labels: msePilotCreateAppName: spring-cloud-b app: spring-cloud-b spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1 imagePullPolicy: Always name: spring-cloud-b ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # YAML code for the canary version of Application B --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-b-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-b-new template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-b app: spring-cloud-b-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1 imagePullPolicy: Always name: spring-cloud-b-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20002 initialDelaySeconds: 10 periodSeconds: 30 # YAML code for the base version of Application C --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c spec: replicas: 2 selector: matchLabels: app: spring-cloud-c template: metadata: labels: msePilotCreateAppName: spring-cloud-c app: spring-cloud-c spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1 imagePullPolicy: Always name: spring-cloud-c ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # YAML code for the canary version of Application C --- apiVersion: apps/v1 kind: Deployment metadata: name: spring-cloud-c-new spec: replicas: 2 selector: matchLabels: app: spring-cloud-c-new template: metadata: labels: alicloud.service.tag: gray msePilotCreateAppName: spring-cloud-c app: spring-cloud-c-new spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1 imagePullPolicy: IfNotPresent name: spring-cloud-c-new ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 20003 initialDelaySeconds: 10 periodSeconds: 30 # Nacos Server --- 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: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/nacos-server:v2.1.2 imagePullPolicy: Always name: nacos-server dnsPolicy: ClusterFirst restartPolicy: Always # YAML code for the 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
Configure network settings
Configure two Kubernetes services spring-cloud-a-base and spring-cloud-a-gray for Application A that works as an ingress application. The spring-cloud-a-base service corresponds to the base version of Application A. The spring-cloud-a-gray service corresponds to the canary version of Application A.
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-base
spec:
ports:
- name: http
nodePort: 32605
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
sessionAffinity: None
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-gray
spec:
ports:
- name: http
nodePort: 31622
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a-new
sessionAffinity: None
type: NodePort
Step 1: Configure a route for the ALB Ingress gateway
Create an AlbConfig object. For more information, see Create an AlbConfig object.
ImportantYou must make sure that the vSwitch of the ALB Ingress gateway is deployed in the same VPC as the cluster. Otherwise, your business is adversely affected.
Configure an Ingress.
Copy the following content to the gray-ingress.yaml file.
Clusters that run Kubernetes versions earlier than V1.19
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: demo namespace: default spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: - path: /a backend: serviceName: spring-clud-a-base servicePort: 20001 - host: www.example.com http: paths: - backend: serviceName: spring-cloud-a-gray servicePort: 20001 path: /a pathType: ImplementationSpecific
Clusters that run Kubernetes V1.19 or later
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: # Specify a context path. - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base port: number: 20001 - host: www.example.com http: paths: # Specify a context path. - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base-gray port: number: 20001
Run the following command:
kubectl apply -f gray-ingress.yaml
If no information is displayed for ADDRESS in the output, go to the following page to view events and troubleshoot issues based on the "Preparations" section in this topic.
Step 2: Configure the end-to-end canary release feature in the MSE console
Log on to the MSE console, and select a region in the top navigation bar.
In the left-side navigation pane, choose Microservices Governance > Full link grayscale.
Click to Create lane groups and lanes.. If a lane group has already been created in the microservice space you have selected, click+to Create Lane Group.
In the Create Lane Group panel, configure the parameters and click OK.
Add the spring-cloud-a, spring-cloud-b, and spring-cloud-c applications to the lane group.
In the lower part of the Full link grayscale page, click Create First Split Lane. In the Create Lane panel, configure the parameters, select the tag gray, and then click OK.
Step 3: Verify the result
Route a request that is destined for
www.aliyundoc.com
to the base versions of the applications.# Test command curl -H"Host:aliyundoc.base.com" http://alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com/a # Test result A[172.18.XX.XX] -> B[172.18.XX.XX] -> C[172.18.XX.XX]%
Route a request that is destined for
www.example.com
to the canary versions of the applications.# Test command curl -H"Host:www.example.com" http://alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com/a # Test result Agray[172.18.XX.XX] -> Bgray[172.18.XX.XX] -> Cgray[172.18.XX.XX]%
In the preceding commands, alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com
indicates the endpoint of the ALB Ingress gateway.