All Products
Search
Document Center

Alibaba Cloud Service Mesh:Migrate TCP traffic with ASM

Last Updated:Aug 28, 2026

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

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 telnet client and Docker are available on the computer that you verify from. Step 4 uses telnet to open a TCP connection to the tcp-echo service, and Step 5 uses docker run to 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.

  1. Deploy two versions of the tcp-echo application.

    1. Log on to the ACK console. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Deployments.

    3. 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.

    4. Set Sample Template to Custom, paste the following YAML into the Template text box, and then click Create.

      Show the YAML file

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tcp-echo-v1
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tcp-echo
            version: v1
        template:
          metadata:
            labels:
              app: tcp-echo
              version: v1
          spec:
            containers:
            - name: tcp-echo
              image: docker.io/istio/tcp-echo-server:1.1
              imagePullPolicy: IfNotPresent
              args: [ "9000", "one" ]
              ports:
              - containerPort: 9000
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tcp-echo-v2
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tcp-echo
            version: v2
        template:
          metadata:
            labels:
              app: tcp-echo
              version: v2
          spec:
            containers:
            - name: tcp-echo
              image: docker.io/istio/tcp-echo-server:1.1
              imagePullPolicy: IfNotPresent
              args: [ "9000", "two" ]
              ports:
              - containerPort: 9000

      The two newly created versions of the tcp-echo application appear on the Deployments page.

  2. Create a Service to expose the tcp-echo application externally.

    1. Log on to the ACK console. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Network > Services.

    3. On the Services page, select the target Namespace at the top of the page, and then click Create in the upper-right corner.

    4. 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.

      Note

      Headless 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.

      Note

      The Service uses the app label of the associated Deployment as its selector, which determines the Deployment that the Kubernetes Service forwards traffic to. Because the tcp-echo-v1 and tcp-echo-v2 Deployments share the same app:tcp-echo label, the Service can route traffic to either Deployment.

      External Traffic Policy

      The Local and Cluster options are supported.

      Note

      External 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 annotation to the Service to configure load balancing parameters. For example, service.beta.kubernetes.io/alicloud-loadbalancer-bandwidth:20 sets 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.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. 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.

  3. Create a Gateway.

    1. On the details page of the ASM instance, choose ASM Gateways > Gateway in the left-side navigation pane. On the page that appears, click Create from YAML.

    2. 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:
          - "*"
  4. Create a VirtualService.

    1. On the details page of the ASM instance, choose Traffic Management Center > VirtualService in the left-side navigation pane. On the page that appears, click Create from YAML.

    2. 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
  5. Create a DestinationRule.

    1. On the details page of the ASM instance, choose Traffic Management Center > DestinationRule in the left-side navigation pane. On the page that appears, click Create from YAML.

    2. 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

Important

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.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.

  3. 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.

  1. 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}')
  2. Run the telnet command to send a connection request to the tcp-echo service.

    telnet $INGRESS_HOST $INGRESS_PORT
    Trying xxx.xxx.xxx.xxx...
    Connected to xxx.xxx.xxx.xxx.
    Escape character is '^]'
  3. Enter any string and press Enter.

    The returned string is prefixed with one, which indicates that the tcp-echo service is deployed and that all traffic is routed to the tcp-echo-v1 version.

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.

Note

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%.

  1. Modify the VirtualService configuration of the ASM instance.

    1. On the details page of the ASM instance, choose Traffic Management Center > VirtualService in the left-side navigation pane.

    2. On the VirtualService page, find the tcp-echo service and click YAML in the Actions column.

    3. 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
  2. Run the following command to send 10 requests to the tcp-echo service:

    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"; \
    done
    one 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 2018

    The output shows that 20% of the traffic is routed to tcp-echo-v2.