All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use traffic rules to configure traffic lanes and traffic shifting

Last Updated:Aug 22, 2023

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

Prerequisites

Step 1: Deploy sample services

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

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

  1. Create a destination rule.

    1. 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
    2. Run the following command to apply the destination rule by using the kubeconfig file of the ASM instance:

      kubectl apply -f dr-mock.yaml
  2. Create a virtual service.

    1. 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
    2. Run the following command to apply the virtual service by using the kubeconfig file of the ASM instance:

      kubectl apply -f vs-mock.yaml
  3. Create traffic routing rules on the gateway.

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

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

  2. 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
  3. Check whether the end-to-end canary release feature takes effect.

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

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

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

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

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

  2. On the Clusters page, click the name of the cluster that you want to manage and choose Workloads > Deployments in the left-side navigation pane.

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

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