All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use Argo CD to implement end-to-end canary releases of application services

Last Updated:Mar 26, 2024

Argo CD monitors the changes to application orchestration in a Git repository, compares the application configuration with the status of the corresponding application in a cluster, and automatically deploys the changes to the cluster. Argo CD also allows you to manually deploy the changes to the cluster. If you face risks and challenges when you launch new versions of microservices applications and want to make a smooth transition and gradually verify new features, you can use Argo CD to implement end-to-end canary releases of application services. Argo CD uses refined traffic scheduling and version management methods to ensure seamless transitions between the old and new versions, minimize the impact on online services, and improve system stability and reliability.

Prerequisites

Background information

Argo CD allows you to implement a GitOps approach to deploy and publish application services. As a developer, you can define application and traffic management resources by using YAML files and submit the definitions to a Git repository. Application resources include Deployments and Services. Traffic management resources include VirtualServices, Gateways, and DestinationRules. Argo CD monitors the status of resources in the cluster and compares the status with the expected orchestration of resources in the Git repository. When resources change in the Git repository, Argo CD automatically synchronizes the changes to the resources in the cluster. Argo CD also allows you to manually synchronize the changes to the resources in the cluster.

ASM allows you to use a traffic lane to isolate Services of specific versions of an application or an application with certain characteristics into an independent runtime environment. This helps you implement end-to-end canary releases of Services of an application. In ASM instances of v1.20.6.27 or later, you can use ASMSwimLaneGroup and ASMSwimLane CustomResourceDefinitions (CRDs) to define traffic lanes. You can use Argo CD to manage these two CRDs to implement end-to-end canary releases. For more information, see Overview of traffic lanes.

Step 1: Use Argo CD to deploy an application service and traffic lane rules

  1. Create a mock application and implement an end-to-end carry release of the application.

    1. On the Argo CD UI, click NEW APP and set the parameters.

      image

      Parameter

      Description

      Application Name

      The application name. For this example, enter mock.

      SYNC POLICY

      The application synchronization policy. For this example, select Automatic. This means that the latest resource definitions in the Git repository are automatically synchronized when resource definitions in the Git repository change. If you select PRUNE RESOURCES, a resource is deleted when its definition no longer exists in the Git repository.

      Repository URL

      The URL of the Git repository from which you want to synchronize the resource definitions. For this example, enter https://github.com/AliyunContainerService/asm-labs.git. You can fork the Git repository and modify the YAML code on the forked Git repository.

      Revision

      The Git tag or branch name of the Git repository from which the resource definitions are synchronized. For this example, enter argocd-asm.

      Path

      The code path in the Git repository from which the resource definitions are synchronized. For this example, enter the argo-cd/swimlane path on which resources used by the following example are located.

      Cluster URL

      The endpoint of the Kubernetes API server of the cluster to which the resource definitions are synchronized. For this example, enter https://kubernetes.default.svc. This is the endpoint of the Kubernetes API server of the cluster in which Argo CD is installed.

  2. After you set the parameters, click CREATE at the top of the page.

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

    image

  3. Click the mock application to view the synchronization status of resources.

    image

    You can see that in addition to the Deployments and Services resources, the Git repository also contains resources such as VirtualServices, Gateways, ASMSwimLaneGroup, and ASMSwimLane.

Step 2: Verify an end-to-end canary release by using traffic lanes

In this example, the ASMSwimLaneGroup and ASMSwimLane CRDs are used to isolate v1 and v2 of Services. You can create a virtual service to enable the ingress gateway to forward requests to the two versions of the Services at a ratio of 1:1. You can repeatedly access the ingress gateway to verify the end-to-end canary release.

  1. Obtain the public IP address of the ingress gateway in the ASM console. For more information, see the "Step 2: Obtain the IP address of the ASM ingress gateway" section of the Integrate KServe with ASM to implement inference services based on cloud-native AI models topic.

  2. Run the following command to configure environment variables.

    xxx.xxx.xxx.xxx is the IP address obtained in substep 1.

    export ASM_GATEWAY_IP=xxx.xxx.xxx.xxx
  3. Run the following command to repeatedly access the ingress 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 mock application includes three Services, mocka, mockb, and mockc. Each Service has two versions v1 and v2. The three Services are called in the following sequence: mocka > mockb > mockc. Requests are sent to the v1 and v2 versions of the mock application at a ratio of nearly 1:1. In addition, the v1 and v2 versions of the Services are called independently. The end-to-end canary release is implemented as expected.

Related operations

Publish a new version of a Service

The following figure shows the structure of the sample Git repository file used in this example.

image.png

File

Description

mock-v1.yaml

mock-v2.yaml

Specifies the deployment of v1 and v2 of the mocka, mockb, and mockc Services.

swimlanegroup.yaml

Specifies the lane group. A lane group is associated with one or more lanes. A lane group defines the information that is shared among multiple traffic lanes. The information includes services and ingress. The services field specifies the Services for which the traffic lane needs to be created. The ingress field specifies the Istio gateways through which the Services in the lane group are accessed.

swimlanes.yaml

Specifies the lanes. Two ASMSwimLane CRDs are used to define two lanes for Services of v1 and v2. The labelSelector field is used to distinguish different versions of Services in a lane.

mock-route.yaml

Specifies the Istio gateway and virtual service that apply to the ingress gateway. These resources control the way how the ingress gateway forwards requests to Services in a lane.

To publish a new version of a Service, you can fork the argocd-asm branch of the sample Git repository https://github.com/AliyunContainerService/asm-labs.git, modify the preceding YAML resources in the argo-cd/swimlane path, and then submit the modification to the remote Git repository. After you submit the modification, Argo CD automatically synchronizes changes in the Git repository. You must enter the URL of the forked Git repository in the Repository URL field in Step 1.

For example, you publish the v3 versions of the mocka, mockb, and mockc Services. You must make the following modifications to the YAML resources in the Git repository:

  1. Create an argo-cd/swimlane/mock-v3.yaml file.

    The YAML file defines the deployment of the v3 versions of the mocka, mockb, and mockc Services.

    Show the YAML code

    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. Change the content in the argo-cd/swimlane/swimlanes.yaml file to the YAML code in the following code block.

    In this example, an ASMSwimLane CRD named v3 is added to the file. The ASMSwimLane CRD is associated with the ASMSwimLaneGroup CRD named mock and specifies that pods with the version:v3 label run v3 Services.

    Show the YAML code

    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. Change the content in the argo-cd/swimlane/mock-route.yaml file to the YAML code in the following code block.

    In this example, the virtual service named mock in the file is modified to add the mocka Service of the v3 version to the route destination. The subset field specifies the name of the traffic lane. The weight fields in the virtual service are modified. The ratio for the canary release of Services of v1, v2, and v3 is changed to 6:3:1.

    Show the YAML code

    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