Service Mesh (ASM) Traffic Management Center smoothly migrates TCP application traffic when you optimize network topology, scale out application servers, or adjust service traffic, ensuring business continuity and high availability. This topic uses the Istio TCP-Traffic-Shifting task to describe canary traffic shifting between two versions of a TCP service.
Prerequisites
Cloud services and resources
The following Alibaba Cloud services are activated:
An ACK cluster is created. For instructions, see Create an ACK managed cluster and Create an ACK dedicated cluster (Discontinued).
The ACK cluster is added to an ASM instance. For instructions, see Create an ASM instance and Add a cluster to an ASM instance.
Local client tools
The kubectl client is installed and connected to the Kubernetes cluster. For instructions, see Obtain the kubeconfig file and use kubectl to connect to the cluster.
A
telnetclient and Docker are available on the computer that you verify from. Step 4 usestelnetto open a TCP connection to thetcp-echoservice, and Step 5 usesdocker runto send test requests.
Step 1: Deploy the sample application
The sample application tcp-echo runs in two versions: v1 prefixes each response with one, and v2 prefixes each response with two. The prefix identifies the version that handles a request, which is how you observe the traffic distribution later in this topic.
Deploy two versions of the
tcp-echoapplication.-
Log on to the ACK console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of your cluster. In the left navigation pane, click .
On the Deployments page, select the target Namespace at the top of the page, and then click Create Resources in YAML in the upper-right corner.
Set Sample Template to Custom, paste the following YAML into the Template text box, and then click Create.
The two newly created versions of the
tcp-echoapplication appear on the Deployments page.
-
Create a Service to expose the
tcp-echoapplication externally.-
Log on to the ACK console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of your cluster. In the left navigation pane, click .
On the Services page, select the target Namespace at the top of the page, and then click Create in the upper-right corner.
In the Create Service dialog box, configure the parameters described in the following table, and then click Confirm.
Parameter
Description
Service
Enter tcp-echo.
Service Type
Select the access method for the Service. Supported types are ClusterIP, NodePort, and LoadBalancer.
NoteHeadless Service can be set only when Service Type is set to Cluster IP. Use a Headless Service to interface with other service discovery systems instead of binding to the Kubernetes implementation.
Backend
Set Name to app and Value to tcp-echo.
NoteThe Service uses the
applabel of the associated Deployment as its selector, which determines the Deployment that the Kubernetes Service forwards traffic to. Because thetcp-echo-v1andtcp-echo-v2Deployments share the sameapp:tcp-echolabel, the Service can route traffic to either Deployment.External Traffic Policy
The Local and Cluster options are supported.
NoteExternal Traffic Policy can be set only when the Service type is Node Port or Server Load Balancer.
Port Mapping
In this topic, set Name to tcp, set Service Port and Container Port to 9000, and set Protocol to TCP.
Annotations
Add an
annotationto the Service to configure load balancing parameters. For example,service.beta.kubernetes.io/alicloud-loadbalancer-bandwidth:20sets the peak bandwidth of the Service to 20 Mbit/s, which controls the traffic of the Service. For more information about the parameters, see Configure a Classic Load Balancer (CLB) instance by using annotations.Label
Add a label to identify the Service.
After you create the Service, the new tcp-echo Service appears on the Services page.
-
Step 2: Configure routing rules
Configure an Istio Gateway, a VirtualService, and a DestinationRule in Service Mesh to route all traffic to the v1 version of the tcp-echo service. The Gateway listens on port 31400, so external traffic reaches these rules only after you add port 31400 to the ingress gateway service in Step 3.
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
Create a Gateway.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
On the Create page, set Namespace to default, select any Scenario Template, paste the following YAML, and then click Create.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: tcp-echo-gateway spec: selector: istio: ingressgateway servers: - port: number: 31400 name: tcp protocol: TCP hosts: - "*"
-
Create a VirtualService.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
On the Create page, set Namespace to default, select any Scenario Template, paste the following YAML, and then click Create.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: tcp-echo spec: hosts: - "*" gateways: - tcp-echo-gateway tcp: - match: - port: 31400 route: - destination: host: tcp-echo port: number: 9000 subset: v1
-
Create a DestinationRule.
-
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
On the Create page, set Namespace to default, select any Scenario Template, paste the following YAML, and then click Create.
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: tcp-echo-destination spec: host: tcp-echo subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2
-
Step 3: Deploy an ingress gateway
Allocate one CLB instance to each Kubernetes Service. If multiple Kubernetes Services share the same CLB instance, the following risks and limitations apply:
Using an existing CLB instance forcibly overwrites its existing listeners, which can make your application inaccessible.
You cannot reuse a CLB instance that Kubernetes creates through a Service. Only CLB instances that are created manually in the console or by calling an OpenAPI operation can be reused.
Multiple Services that share the same CLB instance cannot use the same frontend listener port. Otherwise, a port conflict occurs.
When you reuse a CLB instance, Kubernetes uses the listener name and the virtual server group name as unique identifiers. Do not modify these names.
You cannot reuse a CLB instance across clusters.
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
On the Ingress Gateway page, click Create, complete the configuration, and then click Create.
The following table describes some of the configuration items. For more information, see Create an ingress gateway.
Parameter
Description
Cluster
Select the cluster in which you want to deploy the ingress gateway.
CLB instance type
In this topic, select Access over the Internet.
Select CLB Instance
Select one of the following options. Use Existing CLB Instance: select an instance from the list of existing CLB instances. Create CLB Instance: click Create SLB Instance and select the required CLB specification from the drop-down list.
Port Mapping
Click Add Port, set Name to tcp, and set Service Port to 31400.
Step 4: Verify the deployment
Use kubectl to confirm that traffic to the tcp-echo service is routed as expected.
Run the following commands to obtain the address and port of the service:
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')Run the
telnetcommand to send a connection request to thetcp-echoservice.telnet $INGRESS_HOST $INGRESS_PORTTrying xxx.xxx.xxx.xxx... Connected to xxx.xxx.xxx.xxx. Escape character is '^]'Enter any string and press Enter.
The returned string is prefixed with
one, which indicates that thetcp-echoservice is deployed and that all traffic is routed to thetcp-echo-v1version.
Step 5: Route traffic to v2 by weight
This step routes 20% of the traffic to the tcp-echo-v2 version and the remaining 80% to tcp-echo-v1.
With a small sample of 10 requests, the results may not always show 2 out of 10 requests routed to tcp-echo-v2. However, over a longer period, the overall ratio approaches 20%.
Modify the VirtualService configuration of the ASM instance.
-
On the details page of the ASM instance, choose in the left-side navigation pane.
On the VirtualService page, find the
tcp-echoservice and click YAML in the Actions column.In the text box on the Edit page, enter the following YAML content and then click OK.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: tcp-echo spec: hosts: - "*" gateways: - tcp-echo-gateway tcp: - match: - port: 31400 route: - destination: host: tcp-echo port: number: 9000 subset: v1 weight: 80 - destination: host: tcp-echo port: number: 9000 subset: v2 weight: 20
-
Run the following command to send 10 requests to the
tcp-echoservice:for i in {1..10}; do \ docker run -e INGRESS_HOST=$INGRESS_HOST -e INGRESS_PORT=$INGRESS_PORT -it --rm busybox sh -c "(date; sleep 1) | nc $INGRESS_HOST $INGRESS_PORT"; \ doneone Mon Nov 12 23:38:45 UTC 2018 two Mon Nov 12 23:38:47 UTC 2018 one Mon Nov 12 23:38:50 UTC 2018 one Mon Nov 12 23:38:52 UTC 2018 one Mon Nov 12 23:38:55 UTC 2018 two Mon Nov 12 23:38:57 UTC 2018 one Mon Nov 12 23:39:00 UTC 2018 one Mon Nov 12 23:39:02 UTC 2018 one Mon Nov 12 23:39:05 UTC 2018 one Mon Nov 12 23:39:07 UTC 2018The output shows that 20% of the traffic is routed to
tcp-echo-v2.