All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use traffic lanes and Hash tagging plug-in to implement canary release by user segment

Last Updated:Nov 21, 2024

Service Mesh (ASM) allows you to isolate a version or certain features of an application into an independent runtime environment (known as swimlane). Then, you can configure swimlane rules to route requests that meet the rules to the destination version or features of the application. In a development environment, developers may isolate stable versions and canary versions by setting swimlanes, and route users to different swimlanes. In this case, you can direct a specific proportion of users to the version to test the functionality, while the remaining users are randomly routed to the canary release versions based on the weight-based routing rule. This topic describes how to configure swimlanes and Hash tagging plug-ins to implement canary release by user segment.

Prerequisites

Procedure

In this example, three applications are created, and the call chain is shown in the following figure.

  • mocka in version 1.

  • mockb in version 1.

  • mockc in version 1 and 2.

image

In this example, the applications identifies user identity based on the x-user-id request header, and the header is passed among applications. The traffic routing rules are as follows:

  • The user requests containing x-user-id: jason header are routed to the new version of the application.

  • A specified proportion of user requests containingx-user-id header are routed to the new version of the applications based on Hash value.

Step 1: Deploy an application

  1. Create a sample.yaml file with the following content.

    Click to view YAML file

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-v1
      labels:
        app: mocka
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mocka
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-v1
      labels:
        app: mockb
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockb
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockb
            - name: upstream_url
              value: "http://mockc:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v1
      namespace: default
      labels:
        app: mockc
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockc
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v2
      namespace: default
      labels:
        app: mockc
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v2
          ASM_TRAFFIC_TAG: v2
      template:
        metadata:
          labels:
            app: mockc
            version: v2
            ASM_TRAFFIC_TAG: v2
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v2
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
  2. Run the following command to deploy an application by using the kubeconfig file of the cluster on the data plane.

    kubectl apply -f sample.yaml

Step 2: Create gateway rules

Run the following command to create an Istio gateway named ingressgateway in the Istio-system namespace. For more information, see Manage Istio gateways.

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:
        - '*'

Step 3: Create a lane group and a lane

  1. Create a lane group.

    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 target ASM instance. In the left-side navigation pane, select Traffic Management Center > Traffic Swimlane.

    3. On the Traffic Swimlane page, click Create Swimlane Group. Configure the relevant settings in the Create Swimlane Group panel, and click OK.

      Parameter

      Description

      Name of Swim lane Group

      In this example, enter canary.

      Ingress Type

      Select ingressgateway.

      Lane Mode

      Select Loose Mode.

      Pass-through Mode of Trace Context

      Select Pass-through Trace Id.

      Trace ID Request Header

      In this example, set it to x-user-id.

      Request Routing Header

      Enable the gateway to route traffic to different lanes based on the request content and pass through the header in lane context. This parameter is user-defined. In this example, enter x-asm-prefer-tag.

      Swimlane Service

      Select the target cluster in Kubernetes clusters filed and select default in namespace field. Select the mocka, mockb, and mockc services in the list below, and click the 移动 icon to add the target services to the Selected pane.

  2. Create swimlanes s1 and s2, and bind them with versions 1 and 2 respectively.

    1. On the Traffic Swimlane page, click Create Swimlanes in the Traffic Rule Definition pane.

    2. In the Create Swimlanes dialog box, configure the relevant settings, and then click OK.

      Parameter

      Description

      Swimlane Name

      Enter s1 and s2 respectively.

      Configure Service Tag

      Label Key: Select ASM_TRAFFIC_TAG

      Label Value: Select v1 and v2 for the two lanes respectively.

      Add Service

      Lane s1: Select mocka(default), mockb(default), mockc(default).

      Lane s2: Select mockc(default).

      The following figure shows an example of configuring swimlane s1:

      image

      The two swimlanes are as follows:

      image

      Note

      By default, the first lane you create in a lane group serves as the baseline lane. You are allowed to modify the services in this baseline lane. When a request is sent to services that do not exist in other lanes, the request is forwarded to the baseline lane through a fallback mechanism. For more information, see Modify the baseline lane in loose mode.

  3. Create request routing rules for the swimlanes.

    1. Create request routing rules for the swimlanes with the following content. The rules are as follows:

      1. Requests containing x-user-id: jason header are routed to swimlane s2. The x-asm-prefer-tag: s2 header that is provided for a request indicates that the request is routed to swimlane s2.

      2. Requests containing x-asm-prefer-tag: s2 header are routed to swimlane s2.

      3. Requests containing x-asm-prefer-tag: s1 header are routed to swimlane s1.

      Click to view YAML content

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: swimlane-ingress-vs
        namespace: istio-system
      spec:
        gateways:
        - istio-system/ingressgateway
        hosts:
        - '*'
        http:
        # Routing rule 1: Request containing x-user-id: jason header is routed to swimlane s2
        # The x-asm-prefer-tag: s2 header that is provided for a request indicates that the request is routed to swimlane s2
        - match:
          - headers:
              x-user-id:
                exact: jason
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1
            headers:
              request:
                set:
                  x-asm-prefer-tag: s2
        # Routing rule 2: Requests containing x-asm-prefer-tag: s2 header are routed to swimlane s2
        - match:
          - headers:
              x-asm-prefer-tag:
                exact: s2
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2
            # If mocka application is not included in lane s2, the request is forwarded to mocka in swimlane s1
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1
        # Routing rule 3: Requests containing x-asm-prefer-tag: s1 header are routed to swimlane s1
        - match:
          - headers:
              x-asm-prefer-tag:
                exact: s1
            uri:
              exact: /
          name: r1
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s1

Step 4: Deploy a Hash tagging plug-in

  1. Create a wasm.yaml file with the following content.

    apiVersion: extensions.istio.io/v1alpha1
    kind: WasmPlugin
    metadata:
      name: hash-tagging
      namespace: istio-system
    spec:
      imagePullPolicy: IfNotPresent 
      selector:
        matchLabels:
          istio: ingressgateway
      url: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-wasm-hash-tagging:v1.22.6.2-g72656ba-aliyun 
      phase: AUTHN
      pluginConfig:
        rules:
          - header: x-user-id
            modulo: 100
            tagHeader: x-asm-prefer-tag
            policies:
              # 20% of user requests are routed to swimlane s2
              - range: 20
                tagValue: s2
              # 80% of user requests are routed to swimlane s1
              - range: 100
                tagValue: s1
  2. Run the following command to deploy a Hash tagging plug-in by using the kubeconfig file of the ASM instance.

    kubectl apply -f wasm.yaml

Step 5: Verify routing rules

  1. Run the following command to configure a temporary environment variable for the ingress gateway address.

    export GATEWAY_ADDRESS=`kubectl get svc -n istio-system | grep istio-ingressgateway | awk '{print $4}'`
  2. Run the following command to access the application as Jason.

    curl ${GATEWAY_ADDRESS} -H 'x-user-id: jason'

    Expected output:

    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)%     

    The result shows that the request is directly routed to version 2 of the mockc application.

  3. Run the following command to route specific users to the new version.

     for i in 'bob' 'stacy' 'jessie' 'vance' 'jack'; do curl ${GATEWAY_ADDRESS} -H "x-user-id: $i";echo "   user $i requested"; done

    Expected output:

    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user bob requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user stacy requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)   user jessie requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user vance requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)   user jack requested

    The results show that the requests of users Jessie and Jack are directly routed to version 2 of the mockc application, while the requests from other users are routed to the version 1.