Canary Releases with Traefik Mesh TrafficSplit: A Version-Aware Guide
A version-aware guide to using Traefik Mesh TrafficSplit for canary releases, with schema verification steps and conservative configuration examples.
21 Nov 2025, 04:25 UTC

Problem: Moving a Slice of Live Traffic to a New Build
Rolling out a new version of a service usually means an all-or-nothing cutover. A canary release reduces that risk by sending a small percentage of production requests to the new build while the majority stay on the stable version. Doing this inside the application adds code complexity; doing it in an external load balancer adds another moving part. The cleaner option is to make the routing decision in the service mesh data plane itself.
Thesis: TrafficSplit Puts Weighted Routing in the Proxy, Not the App
Traefik Mesh uses sidecar proxies to handle east-west traffic. Its TrafficSplit custom resource lets you define weighted routing rules between service versions without modifying application code. The proxy reads the resource and distributes incoming requests proportionally. However, the exact API schema, supported protocols, and observability surface are version-sensitive. Treat the configuration below as a template to verify against your specific Traefik Mesh deployment.
How the Split Works Conceptually
Each pod in a meshed service runs a sidecar proxy. When you create a TrafficSplit resource, the control plane configures the sidecars to route a percentage of requests to each backend. The weights are integers, and the proxy distributes traffic proportionally. Because the sidecar terminates and re-encrypts traffic, the split logic can operate on HTTP requests while preserving the mesh's mTLS guarantees.
Worked Example: A 90/10 HTTP Canary
The following steps illustrate the shape of a TrafficSplit deployment. Because Traefik Mesh has evolved across releases, confirm the exact resource schema before applying anything to a cluster.
- Deploy two versions with distinct labels. Run in your application namespace (e.g.,
shop):
Ensure each version has a Kubernetes Service or is reachable by the mesh.kubectl apply -n shop -f deployment-v1.yaml # labels: app=shop, version=v1 kubectl apply -n shop -f deployment-v2.yaml # labels: app=shop, version=v2 - Discover the TrafficSplit API. Run from any machine with cluster access (requires read permissions on custom resources):
Note thekubectl api-resources | grep -i trafficsplitAPIVERSIONandKIND. If the resource is missing, your Traefik Mesh version may use a different mechanism. - Create the TrafficSplit resource. Save the following as
trafficsplit.yamland adjust theapiVersionand fields to match the output from the previous step:
Apply it (requires create/update permissions in the namespace):apiVersion: # e.g., split.smi-spec.io/v1alpha1 or traefikmesh.io/v1alpha1 kind: TrafficSplit metadata: name: shop-canary namespace: shop spec: service: shop backends: - service: shop-v1 weight: 90 - service: shop-v2 weight: 10kubectl apply -f trafficsplit.yaml - Generate traffic and inspect. From any pod with
curl, or a load generator:
Check the logs of the v1 and v2 pods to see which version served each request.for i in $(seq 1 100); do curl -s http://shop.shop.svc.cluster.local/; done
Verifying the Result
Start with the resource status. If the CRD is accepted, kubectl get trafficsplit shop-canary -n shop should show the object. Next, confirm that the proxy is actually splitting traffic by comparing request counts in the pod logs of both versions. Traefik Mesh also exposes Prometheus metrics from its proxies; scrape the mesh's metrics endpoint and look for counters related to traffic splitting, but verify the exact metric name and label set in your version's documentation rather than assuming a fixed name.
To test a weight change, edit the resource—for example, shifting to 50/50—re-apply it, and repeat the request loop. If the log distribution moves toward the new ratio, the data plane is respecting the split.
Trade-offs and Limitations
- Protocol scope. Weighted splitting is a Layer-7 feature. Do not assume it applies to raw TCP or gRPC passthrough. Check your Traefik Mesh documentation for protocol support before designing a split for non-HTTP services.
- Namespace boundaries. TrafficSplit resources are namespaced. A split that crosses namespaces may require additional routing rules or a resource in the ingress namespace, which increases operational complexity.
- Schema drift. The CRD fields and API group have changed across Traefik Mesh releases. A manifest that works on one version may be rejected by another. Always validate against
kubectl api-resourcesand your control plane's OpenAPI schema.
Actionable Closing
Before you build a canary pipeline, run kubectl api-resources to confirm the TrafficSplit kind and API version in your cluster. Label your Deployments with a stable version tag, create the split with a conservative weight such as 95/5, and verify the distribution through pod logs and Prometheus counters. Increase the weight only after the new version demonstrates stability. Keep the split limited to protocols your Traefik Mesh version explicitly supports, and document the exact schema you validated so future upgrades do not silently break the canary.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.