All Products
Search
Document Center

Alibaba Cloud Service Mesh:End-to-end canary release with Argo CD

Last Updated:Jun 20, 2026

To safely release new versions of a microservice application and gradually validate new features, use Argo CD to perform an end-to-end canary release. This method provides fine-grained traffic scheduling and version management, ensuring a seamless switch between versions. This minimizes the impact on online services and improves system stability.

Prerequisites

Background information

Argo CD uses the GitOps approach to deploy and release application services. Developers commit YAML manifests for application resources such as Deployments and Services, and traffic management rules such as VirtualServices, Gateways, and DestinationRules to a Git repository. Argo CD monitors the status of these resources in the cluster and compares them with the desired state defined in the Git repository. With the Git repository as the source of truth, Argo CD can automatically or manually synchronize the resources when changes are detected.

Service Mesh ASM supports using traffic lanes to isolate specific versions (or other characteristics) of an application into an independent runtime environment to facilitate end-to-end canary releases for application services. Starting from version 1.20.6.27, ASM supports defining traffic lanes by using two custom resources written in YAML: ASMSwimLaneGroup and ASMSwimLane. You can use Argo CD to manage these custom resources to implement end-to-end canary releases. For more information, see Traffic lane overview.

Step 1: Deploy application and traffic lanes

  1. Create an end-to-end canary release sample for the mock application.

    1. In the Argo CD UI, click NEW APP and configure the following parameters.

      Parameter

      Description

      Application Name

      The name of the application. In this example, enter mock.

      SYNC POLICY

      The application's sync policy. In this example, select Automatically. This setting automatically synchronizes the latest resource definitions from the Git repository. Select PRUNE RESOURCES to ensure that resources are deleted from the cluster if their definitions are removed from the Git repository.

      Repository URL

      The URL of the source Git repository. In this example, enter the sample repository URL https://github.com/AliyunContainerService/asm-labs.git. If you want to modify the sample, fork this repository and enter the URL of your forked repository.

      Revision

      The Git tag or branch name to synchronize from. In this example, enter the sample repository branch argocd-asm.

      Path

      The path in the repository that contains the resource manifests. In this example, enter the path of the resources used in the sample: argo-cd/swimlane.

      Cluster URL

      The API server address of the destination cluster. In this example, enter the API server address of the Kubernetes cluster where Argo CD is deployed: https://kubernetes.default.svc.

  2. After you complete the configuration, click CREATE at the top of the page.

    On the Applications page in Argo CD, you can view the status of the mock application that you just created.

    The application status should be Healthy and the sync status should be Synced, which indicates that the application is successfully deployed and synchronized.

  3. Click the mock application to view the sync status of its resources.

    The resource view shows that the application status is Healthy and the sync status is Synced, and all resources are synchronized without errors.

    In addition to the Deployment and Service resources that define the application, the Git repository also contains traffic management resources such as VirtualService and Gateway, and ASM traffic lane resources such as ASMSwimLaneGroup and ASMSwimLane.

Step 2: Verify the end-to-end canary release

In this example, the ASMSwimLaneGroup and ASMSwimLane resources isolate the v1 and v2 environments for the application services. A VirtualService resource directs the ASM gateway to forward traffic to the two versions at a 1:1 ratio. You can repeatedly access the ASM gateway to verify the end-to-end canary release.

  1. Obtain the public IP address of the gateway from the ASM console. For more information, see Obtain the IP address of an ASM gateway.

  2. Run the following command to set an environment variable.

    Replace xxx.xxx.xxx.xxx with the IP address from the previous step.

    export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
  3. Run the following command to repeatedly access the ASM gateway.

    for i in {1..100}; do curl http://${ASM_GATEWAY_IP}/mock; echo ''; sleep 1; done;

    Expected output:

    -> mocka(version: v2, ip: 10.0.239.73)-> mockb(version: v2, ip: 10.0.239.136)-> mockc(version: v2, ip: 10.0.239.139)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v2, ip: 10.0.239.73)-> mockb(version: v2, ip: 10.0.239.136)-> mockc(version: v2, ip: 10.0.239.139)
    -> mocka(version: v2, ip: 10.0.239.73)-> mockb(version: v2, ip: 10.0.239.136)-> mockc(version: v2, ip: 10.0.239.139)
    -> mocka(version: v2, ip: 10.0.239.73)-> mockb(version: v2, ip: 10.0.239.136)-> mockc(version: v2, ip: 10.0.239.139)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    -> mocka(version: v2, ip: 10.0.239.73)-> mockb(version: v2, ip: 10.0.239.136)-> mockc(version: v2, ip: 10.0.239.139)
    -> mocka(version: v1, ip: 10.0.239.75)-> mockb(version: v1, ip: 10.0.239.138)-> mockc(version: v1, ip: 10.0.239.137)
    ...

    The output indicates that the sample application consists of three services: mocka, mockb, and mockc. The service call chain is mockamockbmockc, and each service has a v1 and a v2 version. Requests are sent to the v1 and v2 versions of the application at an approximate 1:1 ratio. The isolated service call chain for each version demonstrates a successful end-to-end canary release.

Related operations

Release a new service version

The sample Git repository used in this example has the following file structure:

File

Description

mock-v1.yaml

mock-v2.yaml

Deployment definitions for the v1 and v2 versions of the mocka, mockb, and mockc services.

swimlanegroup.yaml

The lane group definition. A lane group is associated with one or more traffic lanes and defines shared information for them. This specifies the services that require isolated environments and the ingress gateway rule for accessing the services in the lane group.

swimlanes.yaml

The traffic lane definitions. This file defines two ASMSwimLane resources: v1 and v2. A traffic lane primarily uses a labelSelector to distinguish service versions by their labels.

mock-route.yaml

Defines the Gateway and VirtualService resources that apply to the ASM ingress gateway. These traffic management resources control how the ASM gateway routes requests to services in each traffic lane.

To release a new application service version, fork the argocd-asm branch of the https://github.com/AliyunContainerService/asm-labs.git sample repository. Modify the YAML resources in the argo-cd/swimlane path and commit the changes. After you push the commit, Argo CD automatically synchronizes the changes. Ensure that the Repository URL in Step 1 is set to your forked repository's URL.

For example, to release a new v3 version for the mocka, mockb, and mockc services, modify the YAML resources in your Git repository as follows:

  1. Add the argo-cd/swimlane/mock-v3.yaml file.

    This YAML file defines the Deployments for the v3 versions of the mocka, mockb, and mockc services.

    YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: mocka-v3
     labels:
     app: mocka
     version: v3
    spec:
     replicas: 1
     selector:
     matchLabels:
     app: mocka
     version: v3
     ASM_TRAFFIC_TAG: v3
     template:
     metadata:
     labels:
     app: mocka
     version: v3
     ASM_TRAFFIC_TAG: v3
     spec:
     containers:
     - name: default
     image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/go-http-sample:1.0
     imagePullPolicy: IfNotPresent
     env:
     - name: version
     value: v3
     - name: app
     value: mocka
     - name: upstream_url
     value: "http://mockb:8000/"
     ports:
     - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: mockb-v3
     labels:
     app: mockb
     version: v3
    spec:
     replicas: 1
     selector:
     matchLabels:
     app: mockb
     version: v3
     ASM_TRAFFIC_TAG: v3
     template:
     metadata:
     labels:
     app: mockb
     version: v3
     ASM_TRAFFIC_TAG: v3
     spec:
     containers:
     - name: default
     image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/go-http-sample:1.0
     imagePullPolicy: IfNotPresent
     env:
     - name: version
     value: v3
     - name: app
     value: mockb
     - name: upstream_url
     value: "http://mockc:8000/"
     ports:
     - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: mockc-v3
     labels:
     app: mockc
     version: v3
    spec:
     replicas: 1
     selector:
     matchLabels:
     app: mockc
     version: v3
     ASM_TRAFFIC_TAG: v3
     template:
     metadata:
     labels:
     app: mockc
     version: v3
     ASM_TRAFFIC_TAG: v3
     spec:
     containers:
     - name: default
     image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/go-http-sample:1.0
     imagePullPolicy: IfNotPresent
     env:
     - name: version
     value: v3
     - name: app
     value: mockc
     ports:
     - containerPort: 8000
  2. Modify the argo-cd/swimlane/swimlanes.yaml file with the following content.

    A new traffic lane (ASMSwimLane) named v3 is added. This resource is associated with the mock lane group (ASMSwimLaneGroup) and specifies that Pods with the version:v3 label belong to the v3 service version.

    YAML

    apiVersion: istio.alibabacloud.com/v1
    kind: ASMSwimLane
    metadata:
     labels:
     swimlane-group: mock
     name: v1
    spec:
     labelSelector:
     version: v1
    ---
    apiVersion: istio.alibabacloud.com/v1
    kind: ASMSwimLane
    metadata:
     labels:
     swimlane-group: mock
     name: v2
    spec:
     labelSelector:
     version: v2
    ---
    apiVersion: istio.alibabacloud.com/v1
    kind: ASMSwimLane
    metadata:
     labels:
     swimlane-group: mock
     name: v3
    spec:
     labelSelector:
     version: v3
  3. Modify the argo-cd/swimlane/mock-route.yaml file with the following content.

    The VirtualService named mock is modified by adding the v3 version of the mocka service to the route destinations. The subset field maps to the name of the traffic lane (ASMSwimLane). The weight field in the VirtualService is adjusted to split the traffic between the v1, v2, and v3 versions in a 6:3:1 ratio.

    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: mock
     namespace: istio-system
    spec:
     gateways:
     - ingressgateway
     hosts:
     - '*'
     http:
     - match:
     - uri:
     exact: /mock
     route:
     - destination:
     host: mocka.default.svc.cluster.local
     subset: v1
     weight: 60
     - destination:
     host: mocka.default.svc.cluster.local
     subset: v2
     weight: 30
     - destination:
     host: mocka.default.svc.cluster.local
     subset: v3
     weight: 10