Skip to main content
In this guide you’ll learn how to perform a gradual release with Argo Rollouts using the Canary deployment strategy. Canary releases route a small percentage of production traffic to a new application revision, then incrementally increase that percentage while you monitor behaviour and optionally run automated checks. Argo Rollouts supports multiple strategies — Canary, Blue/Green, and Progressive Delivery. This article focuses on Canary, with concise examples, commands, and tips to run a canary rollout locally or in a cluster.

High-level overview: what a Rollout looks like

  • A Rollout is similar to a Kubernetes Deployment manifest but uses the Rollout kind and extra strategy fields.
  • Strategy steps let you incrementally shift traffic (weights) and pause at steps either for a duration or indefinitely for manual promotion.
  • A Rollout will create ReplicaSets and Pods — you will not see a Deployment object for that app.
ResourcePurposeExample use
RolloutDeclarative progressive delivery resourcekind: Rollout with strategy.canary
ReplicaSetManaged by Rollout per revisionCreated for each revision
ServiceRoutes traffic between revisions when using weight-based canaryService referenced by the Rollout traffic routing logic
Useful links:

Canary rollout — simple example

A basic Canary Rollout that controls traffic by weight and pauses between steps:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: example-rollout
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.15.4
          ports:
            - containerPort: 80
  minReadySeconds: 30
  revisionHistoryLimit: 3
  strategy:
    canary: # Use the Canary strategy
      maxSurge: "25%"
      maxUnavailable: 0
      steps:
        - setWeight: 10
        - pause:
            duration: "1h"   # pause for 1 hour
        - setWeight: 20
        - pause: {}         # pause indefinitely until manually promoted

Blue/Green (excerpt)

For comparison, here is an excerpt showing Blue/Green-related fields supported by Rollouts:
revisionHistoryLimit: 3

strategy:
  blueGreen:
    # Required: service that Rollout modifies as the active service
    activeService: active-service

    # Optional pre-promotion analysis
    prePromotionAnalysis:
      templates:
        - templateName: success-rate
      args:
        - name: service-name
          value: guestbook-svc.default.svc.cluster.local

    postPromotionAnalysis:
      templates:
        - templateName: success-rate
      args:
        - name: service-name
          value: guestbook-svc.default.svc.cluster.local

    previewService: preview-service
    previewReplicaCount: 1
    autoPromotionEnabled: false
    # When autoPromotionEnabled is false, Rollout remains paused until manually resumed.

Walkthrough: applying a Canary rollout

  1. Repository layout (example)
  • patterns/canary contains rollout.yml and service.yml.
  1. Example canary Rollout manifest for an application (app-rollout)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: app-rollout
  namespace: canary
spec:
  replicas: 10
  selector:
    matchLabels:
      app: app-rollout
  template:
    metadata:
      labels:
        app: app-rollout
    spec:
      containers:
        - name: app
          image: siddharth67/app:v1
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: {}               # pause indefinitely (manual promotion required)
        - setWeight: 40
        - pause:
            duration: "1m"
        - setWeight: 60
        - pause:
            duration: "1m"
        - setWeight: 80
        - pause:
            duration: "1m"
  1. Shorter demo pauses (use seconds) If you prefer fast demos, shorten pauses to seconds:
strategy:
  canary:
    steps:
      - setWeight: 20
      - pause: {}
      - setWeight: 40
      - pause:
          duration: "10s"
      - setWeight: 60
      - pause:
          duration: "10s"
      - setWeight: 80
      - pause:
          duration: "10s"
Pause duration examples (note valid formats — include a suffix):
strategy:
  canary:
    steps:
      - pause: { duration: "10" }   # invalid — missing a unit; use "10s", "10m", or "10h"
      - pause: { duration: "10s" }  # 10 seconds
      - pause: { duration: "10m" }  # 10 minutes
      - pause: { duration: "10h" }  # 10 hours
      - pause: {}                   # pause indefinitely (manual promotion)
  1. Create namespace, apply manifests, and verify
Run these commands from the patterns/canary directory (where rollout.yml and service.yml are located):
# ensure the kubectl argo rollouts plugin is available
kubectl argo rollouts version

# create namespace
kubectl create ns canary

# apply manifests
kubectl -n canary apply -f .

# verify resources
kubectl -n canary get all
kubectl get rollouts -n canary
Example outputs (trimmed):
# kubectl argo rollouts version
kubectl-argo-rollouts: v1.8.3+49fa151
BuildDate: 2025-06-04T22:15:54Z
GitCommit: 49fa1516cf71672b69e265267da4e1d16e1fe114
GoVersion: go1.23.9
Platform: linux/amd64

# applying manifests
rollout.argoproj.io/app-rollout created
service/app-rollout-service created

# checking resources
kubectl -n canary get all
NAME                                   READY   STATUS    RESTARTS   AGE
pod/app-rollout-76f479c6bf-251lrz      1/1     Running   0          8s
... (other pods) ...

NAME                         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
service/app-rollout-service  NodePort   10.109.7.217   <none>        80:30797/TCP    8s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/app-rollout-76f479c6bf      10        10        10      8s
Note: a Rollout is not a Deployment. You will see ReplicaSets and Pods, but not a Deployment object when using kind: Rollout.
  1. Access the application and observe versions
In the example the NodePort is 30797. Poll the /app endpoint to observe which version responds as the canary progresses. Polling script (bash) — polls every second and prints the version returned:
while true; do
  echo -n "$(date '+%H:%M:%S') - ";
  response=$(curl -s --max-time 1 http://localhost:30797/app 2>/dev/null)
  if [ -z "$response" ]; then
    echo "ERROR: Service unreachable"
  else
    echo "$response"
  fi
  sleep 1
done
  1. Promote a rollout to the next step
Promote manually either from the Argo Rollouts web UI (click Promote) or from the CLI using the kubectl plugin. Promote examples:
# Promote the named rollout to the next step (include -n <namespace> if not default)
kubectl argo rollouts promote app-rollout -n canary

# Promote repeatedly until the rollout reaches 100% or update the image to finish the rollout.
A screenshot of the Argo Rollouts web UI for an "app-rollout" canary deployment, showing a left-hand step timeline with "Set Weight" and "Pause" steps. The center/right panels display the strategy summary (set vs actual weight), container info, and revision details.

What happens during promotion

  • If a canary step sets weight to 20% and you have 10 replicas, Argo Rollouts will direct ~2 replicas (20% of 10) to the new ReplicaSet.
  • Subsequent promotions increase the percentage according to configured weights (40%, 60%, 80%, etc.).
  • Pauses are opportunities to run tests, observe metrics, or require manual approval before advancing.

Observing traffic during the rollout

  • While partially promoted, traffic is split based on weights. Your polling script should show intermittent responses from the new version (e.g., v2) until the rollout reaches 100% and all traffic flows to the new revision.

Rollback and automation

  • Argo Rollouts supports automated analysis and rollbacks via pre/post-promotion analysis templates.
  • Combine Rollouts with GitOps (for example, Argo CD) to let manifests in a Git repo drive the rollout state and history.
  • See the Argo Rollouts docs for configuring analysis templates and automated rollbacks.

Quick reference: common commands

ActionCommand
Check plugin versionkubectl argo rollouts version
Apply manifestskubectl -n canary apply -f .
List rolloutskubectl get rollouts -n canary
Promote rolloutkubectl argo rollouts promote app-rollout -n canary
To promote a rollout from the CLI, use: kubectl argo rollouts promote <rollout-name> -n <namespace>. If a step is paused indefinitely (pause: ), you must promote it manually.
Pause durations must include a time unit suffix (for example ”10s”, “1m”, “1h”) or be specified as an empty object (pause: ) to pause indefinitely.
That’s it — a compact walkthrough showing how to incrementally release a new application version using Argo Rollouts’ Canary strategy.

Watch Video

Practice Lab