A standard canary release validates only the service you deploy. It does not verify how that service interacts with upstream and downstream dependencies. When service A calls service B, which calls service C, releasing a canary version of A alone leaves the full request path untested.
End-to-end canary releases solve this by creating traffic lanes. A traffic lane tags requests at the ingress and propagates that tag through every service in the call chain. Each service checks the tag and routes the request to its canary version if one exists. If a service has no canary version deployed, it forwards the request to its base version but preserves the tag so the next downstream service still routes correctly. The result: canary traffic stays isolated from ingress to the final downstream service, and you validate multiple service changes together before promoting them to production.
This walkthrough integrates Kruise Rollouts with Microservices Engine (MSE) Microservices Governance in a Container Service for Kubernetes (ACK) cluster. After completing these steps, tagged requests flow through canary versions of multiple services while production traffic remains untouched.

How Kruise Rollouts works
Kruise Rollouts is the progressive delivery component of OpenKruise. You can use Kruise Rollouts to perform canary releases, blue-green deployments, and A/B testing. Unlike tools that require replacing your workload types, Kruise Rollouts operates as a bypass component: your existing Deployments, StatefulSets, or CloneSets stay unchanged, and Kruise Rollouts orchestrates the canary process alongside them. The release process can be automated in batches and paused based on the metrics of Managed Service for Prometheus. You need to only create a Rollouts resource in your ACK cluster to automate application releases and updates. Kruise Rollouts supports seamless integration with Helm and PaaS platforms at low costs.
Canary release lifecycle
When a Deployment image changes, Kruise Rollouts follows this sequence:
Pause the Deployment's native rolling update.
Create canary pods with the new image version.
Configure traffic routing so that matching requests reach the canary pods.
Wait for manual approval (or automated metric checks).
On approval, promote the canary version to all pods using a rolling update.
Remove the canary pods and restore native traffic routing.

Prerequisites
Before you begin, make sure that you have:
An ACK cluster running Kubernetes 1.19 or later. For more information, see Create an ACK managed cluster
kubectl-kruise installed. For more information, see kubectl-kruise
Microservices Governance activated. For more information, see Activate Microservices Governance
Step 1: Install required components
Install ack-kruise
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, find your target cluster and click its name. In the left-side navigation pane, choose Operations > Add-ons.
On the Manage Components page, click the Manage Applications tab.
Find the ack-kruise card and click Install.
In the confirmation dialog, click OK.
Install the MSE Ingress Controller
Create an MseIngressConfig and an IngressClass resource to enable MSE-based ingress for your cluster. For detailed steps, see Use MSE Ingresses to access applications in ACK clusters.
Enable Microservices Governance
Enable Microservices Governance for your target applications. For detailed steps, see Enable Microservices Governance for microservice applications in an ACK cluster.
Step 2: Deploy the demo applications
This demo uses three Spring Cloud applications -- A, B, and C -- that form a call chain: A calls B, which calls C. A Nacos server handles service discovery, and a MySQL instance provides data storage.
Create the application resources
Create a file named
mse-demo.yamlwith the following content:Deploy the applications:
kubectl apply -f mse-demo.yaml
Create the Ingress resource
Create a file named
mse-ingress.yamlwith the following content:Apply the Ingress configuration:
kubectl apply -f mse-ingress.yaml
Verify the deployment
Get the external IP address of the Ingress: Expected output:
kubectl get ingressNAME CLASS HOSTS ADDRESS PORTS AGE spring-cloud-a <none> * EXTERNAL_IP 80 12mSend a test request. Replace
<EXTERNAL_IP>with the IP address from the previous output: Expected output: This output confirms that the call chain A -> B -> C is working and all three services run the base version.curl http://<EXTERNAL_IP>/aA[192.168.42.115][config=base] -> B[192.168.42.118] -> C[192.168.42.101]
Step 3: Configure end-to-end canary releases
Define the Rollout and TrafficRouting resources
In this demo, the canary release is performed in three batches:
A/B testing is performed. Requests that contain
header[User-Agent]=xiaomingare forwarded to the canary version. Other requests are forwarded to the base version.Half of the pods run the canary version, and half of requests are forwarded to the canary version.
All the pods run the canary version, and all the requests are forwarded to the canary version.
Create and apply the Rollout resources as follows:
Create a file named
rollout.yamlwith the following content:What happens when you apply this configuration:
Each Rollout resource watches a Deployment. When the Deployment image changes, Kruise Rollouts:
Pauses the native rolling update.
Creates one canary pod (
replicas: 1) with the new image version.Applies the
patchPodTemplateMetadatalabels to the canary pod:alicloud.service.tag: gray-- tells MSE Microservices Governance to recognize this pod as part of the canary (gray) group.opensergo.io/canary-gray: gray-- enables OpenSergo-compliant traffic lane routing across the call chain.
Pauses and waits for manual approval before promoting.
The TrafficRouting resource defines the traffic-splitting rules:
Requests with the header
User-Agent: xiaomingmatch the canary rule.The
requestHeaderModifierinjects anx-mse-tag: grayheader into matching requests. MSE propagates this header through the entire call chain, enabling end-to-end canary routing. Every service in the chain checks this header and routes to its canary pod if one exists.
Deploy the Rollout resources:
kubectl apply -f rollout.yamlVerify the Rollout status: If the output shows
STATUS=Healthy, the Rollout resources are ready.kubectl get rollout
Trigger a canary release
Kruise Rollouts is a one-time configuration. After the Rollout resources are deployed, trigger a canary release by updating your Deployment image -- no additional Rollout configuration is needed. In addition to kubectl, you can use Helm or Vela to deploy the deployments to your cluster.
In
mse-demo.yaml, update the image versions for spring-cloud-a and spring-cloud-c frommse-2.0.0tomse-2.0.1: Application B stays atmse-2.0.0. Because B has no canary version, requests routed to the canary lane pass through B's base version but continue to C's canary version. This demonstrates the end-to-end traffic lane: even when a service in the middle of the chain has no canary deployment, the canary tag is preserved and downstream services still route correctly.# In the spring-cloud-a Deployment image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.1 # In the spring-cloud-c Deployment image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.1Apply the updated Deployments:
kubectl apply -f mse-demo.yamlCheck the Rollout progress: Expected output:
Field Value Meaning STATUSProgressingThe canary release is in progress CANARY_STATEStepPausedThe canary batch is deployed and the rollout is waiting for manual approval kubectl get rollouts rollout-a -n default kubectl get rollouts rollout-c -n defaultNAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE rollout-a Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m rollout-c Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m
Verify and promote the canary version
Send a canary test request by including the
User-Agent: xiaomingheader: Canary traffic flows through the canary versions of A and C, while B uses its base version. Verify the behavior through application logs and monitoring metrics.curl http://<EXTERNAL_IP>/a -H "User-Agent: xiaoming"After confirming the canary version works as expected, approve the rollout to promote it to production. Run the following command for each Rollout that has a canary version deployed (in this demo,
rollout-aandrollout-c). Replace<rollouts-demo>with the name of the Rollouts resource:rollout.rollouts.kruise.io/<rollouts-demo> approved
Roll back a canary release
If the canary version does not meet expectations, revert the image versions in mse-demo.yaml to their original values and reapply:
kubectl apply -f mse-demo.yamlNo changes to the Rollout resources are needed. Kruise Rollouts detects the Deployment change and handles the rollback automatically.
The end-to-end canary release feature of Microservices Governance provides lanes, which greatly facilitate verification during testing and release. You can use Microservices Governance together with Kruise Rollouts to significantly improve the stability of online applications in a DevOps process.