You can configure traffic management rules, such as virtual services and destination rules, to isolate a version of an application or an application with specific characteristics into an independent runtime environment, which is known as a lane. This way, request traffic that meets the rules is routed to the destination version or to the application with the specific characteristics. In addition, you can configure traffic shifting, which routes traffic to the specified version with a lower priority when the destination version is unavailable. This topic describes how to use traffic rules to configure traffic lanes and traffic shifting in Service Mesh (ASM).
Step 1: Deploy sample services
Enable automatic sidecar proxy injection for the default namespace. For more information, see the "Enable automatic sidecar injection" section of the Manage global namespaces topic.
For more information, see Enable automatic sidecar proxy injection.
Run the following commands to deploy sample services by using the kubeconfig file of the cluster on the data plane.
In this example, the mocka, mockb, and mockc services are deployed, and each of the three services has three versions: v1, v2, and v3.
kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v1/application-v1.yaml
kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v2/application-v2.yaml
kubectl apply -f https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/swimlane/v3/application-v3.yaml
Step 2: Create traffic rules to define traffic lanes
Create a destination rule.
Create a file named dr-mock.yaml and copy the following content to the file.
In this example, each of the mocka, mockb, and mockc services has three subsets: v1, v2, and v3.
Show the content of dr-mock.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mocka
namespace: istio-system
spec:
host: mocka.default.svc.cluster.local
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mockb
namespace: istio-system
spec:
host: mockb.default.svc.cluster.local
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mockc
namespace: istio-system
spec:
host: mockc.default.svc.cluster.local
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
Run the following command to apply the destination rule by using the kubeconfig file of the ASM instance:
kubectl apply -f dr-mock.yaml
Create a virtual service.
Create a file named vs-mock.yaml and copy the following content to the file.
The following code creates three lanes for three service call chains: mocka of version v1 to mockb of version v1 and then to mockc of version v1, mocka of version v2 to mockb of version v2 and then to mockc of version v2, and mocka of version v3 to mockb of version v3 and then to mockc of version v3. This way, requests from a service of a version can be sent only to services of the same version.
Show the content of vs-mock.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mockb
namespace: istio-system
spec:
hosts:
- mockb.default.svc.cluster.local
http:
- match:
- sourceLabels:
version: v1
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v2
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v2
- match:
- sourceLabels:
version: v3
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mockc
namespace: istio-system
spec:
hosts:
- mockc.default.svc.cluster.local
http:
- match:
- sourceLabels:
version: v1
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v2
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v2
- match:
- sourceLabels:
version: v3
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v3
Run the following command to apply the virtual service by using the kubeconfig file of the ASM instance:
kubectl apply -f vs-mock.yaml
Create traffic routing rules on the gateway.
Create a file named gw-mock.yaml and copy the following content to the file.
The following code creates traffic routing rules for the three service call chains. The gateway routes requests that are sent to the gateway to the v1, v2, or v3 version of the mocka service based on the value of the x-asm-prefer-tag
header in the requests.
Show the content of gw-mock.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: ingressgateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ingressgateway
namespace: istio-system
spec:
gateways:
- istio-system/ingressgateway
hosts:
- '*'
http:
- match:
- headers:
x-asm-prefer-tag:
exact: v1
uri:
exact: /mock
route:
- destination:
host: mocka.default.svc.cluster.local
subset: v1
- match:
- headers:
x-asm-prefer-tag:
exact: v2
uri:
exact: /mock
route:
- destination:
host: mocka.default.svc.cluster.local
subset: v2
- match:
- headers:
x-asm-prefer-tag:
exact: v3
uri:
exact: /mock
route:
- destination:
host: mocka.default.svc.cluster.local
subset: v3
Run the following command to apply the traffic routing rules by using the kubeconfig file of the ASM instance:
kubectl apply -f gw-mock.yaml
Step 3: Check whether the traffic lanes take effect
Obtain the public IP address of the ASM gateway. For more information, see Step 2: Query the IP address of the ASM instance's ingress gateway of the Integrate the cloud-native inference service KServe with ASM topic.
Run the following command to configure an environment variable.
xxx.xxx.xxx.xxx
is the IP address obtained in substep 1.
export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
Check whether the end-to-end canary release feature takes effect.
Run the following command to check whether the lane for services of version v1 takes effect:
for i in {1..100}; do curl -H 'x-asm-prefer-tag: v1' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
Expected output:
-> mocka(version: v1, ip: 172.17.0.54)-> mockb(version: v1, ip: 172.17.0.129)-> mockc(version: v1, ip: 172.17.0.130)
In the output, the traffic that carries the x-asm-prefer-tag: v1
HTTP header flows to the services of version v1. This meets the expectations.
Run the following command to check whether the lane for services of version v2 takes effect:
for i in {1..100}; do curl -H 'x-asm-prefer-tag: v2' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
Expected output:
-> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v2, ip: 172.17.0.126)-> mockc(version: v2, ip: 172.17.0.128)
In the output, the traffic that carries the x-asm-prefer-tag: v2
HTTP header flows to the services of version v2. This meets the expectations.
Run the following command to check whether the lane for services of version v3 takes effect:
for i in {1..100}; do curl -H 'x-asm-prefer-tag: v3' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
Expected output:
-> mocka(version: v3, ip: 172.17.0.132)-> mockb(version: v3, ip: 172.17.0.127)-> mockc(version: v3, ip: 172.17.0.69)
In the output, the traffic that carries the x-asm-prefer-tag: v3
HTTP header flows to the services of version v3. This meets the expectations.
Step 4: Configure traffic shifting in the traffic lanes
Copy the following content to vs-mock.yaml to modify the file.
The following code creates three lanes for three service call chains: mocka of version v1 to mockb of version v1 and then to mockc of version v1, mocka of version v2 to mockb of version v2 and then to mockc of version v2, and mocka of version v3 to mockb of version v3 and then to mockc of version v3. Moreover, if version v2 or v3 of the mockb or mockc service is unavailable, requests are sent to the v1 version of the corresponding service.
Show the content of vs-mock.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mockb
namespace: istio-system
spec:
hosts:
- mockb.default.svc.cluster.local
http:
- match:
- sourceLabels:
version: v1
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v2
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v2
fallback:
target:
host: mockb.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v3
route:
- destination:
host: mockb.default.svc.cluster.local
subset: v3
fallback:
target:
host: mockb.default.svc.cluster.local
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mockc
namespace: istio-system
spec:
hosts:
- mockc.default.svc.cluster.local
http:
- match:
- sourceLabels:
version: v1
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v2
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v2
fallback:
target:
host: mockc.default.svc.cluster.local
subset: v1
- match:
- sourceLabels:
version: v3
route:
- destination:
host: mockc.default.svc.cluster.local
subset: v3
fallback:
target:
host: mockc.default.svc.cluster.local
subset: v1
Run the following command to modify the original virtual service and apply the traffic shifting configuration by using the kubeconfig file of the ASM instance:
kubectl apply -f vs-mock.yaml
Step 5: Check whether traffic shifting takes effect
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, click the name of the cluster that you want to manage and choose in the left-side navigation pane.
On the Deployments page, find the mockb-v2 workload and click Scale in the Actions column. In the Scale dialog box, set Desired Number of Pods to 1 and click OK. In the OK message, click Confirm. This operation simulates the failure of version v2 of the mockb service.
Run the following command to check whether the lane for services of version v2 takes effect:
for i in {1..100}; do curl -H 'x-asm-prefer-tag: v2' http://${ASM_GATEWAY_IP}/mock ; echo ''; sleep 1; done;
Expected output:
-> mocka(version: v2, ip: 172.17.0.9)-> mockb(version: v1, ip: 172.17.0.126)-> mockc(version: v1, ip: 172.17.0.128)
In the output, the traffic that carries the x-asm-prefer-tag: v2
HTTP header first flows to the service of version v2. Then, the traffic that is supposed to flow to the mockb service of the v2 version is shifted to the call chain with the mockb service of the v1 version because the mockb service of the v2 version fails. Traffic shifting takes effect.