Back to Blog
Software EngineeringTechnologyJune 19, 20263 min read

Argo Rollouts: Implementing Progressive Delivery and Canary Deployments

Master Argo Rollouts for automated canary deployments. Learn how to implement Kubernetes GitOps and traffic shifting to improve your software delivery pipeline.

KubernetesArgo RolloutsDevOpsCI/CDIstioSREGitOpsLinuxServer

Argo Rollouts: Implementing Progressive Delivery and Canary Deployments

We’ve all been there. It’s 4:55 PM on a Friday, and you’re about to merge a PR. You run kubectl apply, your heart rate spikes, and you spend the next two hours staring at Grafana dashboards praying nothing breaks. Standard Kubernetes deployments are binary: either the new version is live, or it isn’t. If it’s broken, you’re scrambling to roll back while users complain.

That’s why I stopped using standard Deployment objects for critical services. If you want to sleep better, you need Argo Rollouts for Progressive Delivery.

What is Progressive Delivery?

Progressive delivery is the evolution of CI/CD. Instead of a "big bang" release, we shift traffic incrementally. Canary deployments allow us to expose the new version to 5% of users, run automated tests, and only proceed if the telemetry looks healthy. If the 5% see 5xx errors or latency spikes, the system automatically reverts.

Prerequisites

To follow along, ensure you have:

  • A Kubernetes cluster (v1.24+)
  • Argo Rollouts controller installed (kubectl create namespace argo-rollouts && kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml)
  • kubectl plugin: krew install argo-rollouts

Configuring Your First Canary Deployment

Forget the standard kind: Deployment. We’re swapping it for kind: Rollout. Here’s how you define a basic canary strategy in your Kubernetes GitOps repository:

YAML
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: web-app
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {duration: 1m}
      - setWeight: 40
      - pause: {duration: 1m}
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: my-registry/app:v2.0.0

When you update the image tag in Git, Argo Rollouts takes over. It creates a "canary" replica set, shifts 20% of your traffic, waits a minute, then bumps it to 40%. It’s declarative, version-controlled, and automated.

Mastering Traffic Shifting

The example above uses simple replica weighting, which is fine for small apps. But in production environments, you usually need traffic shifting at the ingress or service mesh level.

If you're using Istio, you can shift traffic based on actual request percentages rather than pod counts. This is much more precise. Update your strategy block like this:

YAML
  strategy:
    canary:
      canaryService: web-app-canary
      stableService: web-app-stable
      trafficRouting:
        istio:
          virtualService:
            name: web-app-vs
            routes:
            - primary

By offloading the routing to Istio, you ensure that even if your canary pod count is low, the traffic distribution remains exact.

Automated Analysis: The Secret Sauce

The real power of Argo Rollouts lies in AnalysisTemplates. You shouldn't be manually checking dashboards during a release. Let Argo do it for you.

Define an AnalysisTemplate to query your metrics provider (like Prometheus):

YAML
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  metrics:
  - name: success-rate
    successCondition: result[0] >= 0.99
    provider:
      prometheus:
        address: http://prometheus.monitoring.svc:9090
        query: |
          sum(irate(http_requests_total{status!~"5.*"}[1m])) 
          / 
          sum(irate(http_requests_total[1m]))

Now, link this to your Rollout strategy. If the success rate drops below 99% during the canary phase, the rollout immediately halts and triggers an automated rollback.

Lessons From the Trenches

I’ve implemented this across several microservices, and here’s what I’ve learned:

  1. Observability is non-negotiable. If your metrics aren't accurate, your automated analysis will either flake out or let bad code slip through. Invest in your Prometheus queries before you invest in the automation.
  2. Start small. Don't try to implement sophisticated traffic shifting on your most complex legacy service on day one. Start with a simple replica-based canary on a non-critical internal tool.
  3. GitOps is the source of truth. Never kubectl edit your rollouts in production. Keep them in your Git repository. If you change a strategy, the PR is your audit log.

Wrapping Up

Argo Rollouts turns the anxiety of production releases into a boring, automated background task. By adopting progressive delivery, you’re not just protecting your users; you’re protecting your team’s sanity.

Start by defining your first Rollout today. Once you see the traffic shift automatically in the CLI (kubectl argo rollouts get rollout web-app -w), you’ll never want to go back to standard deployments again.

Similar Posts