Practical Traffic Splitting and Canary Deployments with Istio

Introduction

As applications evolve, releasing new versions safely is crucial. Traditional deployment methods often risk downtime or entire system failures if a new release is faulty. Canary deployments allow gradual rollout of new versions while monitoring performance.

With Istio, we can implement traffic splitting to control how much traffic goes to each version, ensuring a smooth transition without disruptions.

In this post, we’ll walk through:
✅ Setting up Istio in Minikube
✅ Deploying two versions of an app
✅ Using Istio’s VirtualService and DestinationRule for canary rollout

Step 1: Install and Configure Istio in Minikube

Since we are working in a local Minikube cluster, first enable Istio:

minikube start
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled

The istio-injection=enabled label ensures that Istio automatically injects sidecar proxies into our pods.

Step 2: Deploy Application Versions

We’ll deploy two versions of our application (v1 and v2).

Create myapp:v1 Deployment

Save the following YAML as deployment-v1.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      version: v1
  template:
    metadata:
      labels:
        app: myapp
        version: v1
    spec:
      containers:
        - name: myapp
          image: myapp:v1  # Using locally built image
          ports:
            - containerPort: 80
Click Here to Copy YAML

Create myapp:v2 Deployment

Save the following YAML as deployment-v2.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      version: v2
  template:
    metadata:
      labels:
        app: myapp
        version: v2
    spec:
      containers:
        - name: myapp
          image: myapp:v2  # Using locally built image
          ports:
            - containerPort: 80
Click Here to Copy YAML

Apply both deployments:

kubectl apply -f deployment-v1.yaml
kubectl apply -f deployment-v2.yaml

Step 3: Define an Istio Service

We need a service to route traffic to both versions.

Save the following as service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
Click Here to Copy YAML

Apply the service:

kubectl apply -f service.yaml

Step 4: Create Istio VirtualService for Traffic Splitting

Now, let’s configure Istio to split traffic between v1 and v2.

Save the following YAML as virtual-service.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
    - myapp
  http:
    - route:
        - destination:
            host: myapp
            subset: v1
          weight: 80
        - destination:
            host: myapp
            subset: v2
          weight: 20
Click Here to Copy YAML

This configuration sends 80% of traffic to v1 and 20% to v2.
Apply the VirtualService:

kubectl apply -f virtual-service.yaml

Step 5: Define an Istio DestinationRule

To allow version-based routing, we need a DestinationRule.

Save the following YAML as destination-rule.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
Click Here to Copy YAML

Apply the DestinationRule:

kubectl apply -f destination-rule.yaml

Step 6: Test Traffic Splitting

Now, let’s check the traffic distribution:

kubectl run -it --rm --image=curlimages/curl test -- curl http://myapp

Run this multiple times—you should see 80% responses from v1 and 20% from v2.

Conclusion

By implementing Istio’s VirtualService and DestinationRule, we successfully built a canary deployment that gradually rolls out a new version without impacting all users at once.

Key Takeaways:
✅ Istio simplifies traffic control for Kubernetes applications.
✅ Canary deployments allow safe testing of new versions.
✅ Traffic splitting can be adjusted dynamically as confidence in v2 increases.

This approach ensures zero downtime deployments, improving stability and user experience. 

What’s your experience with Istio? Drop a comment below!👇

Leave a comment