Zero-Downtime Kubernetes Deployments with Argo Rollouts

2025-06-01 08:00:41 -0300

If you’ve been burned by a deployment gone wrong — a moment of downtime, broken styles, inconsistent APIs, or a weird bug that only happens during rollout — then you already know how fragile production updates can be with Kubernetes’ native strategies.

Fortunately, there’s a battle-tested solution that can help: Argo Rollouts.

In this post, I’ll walk you through why Kubernetes’ default rollout mechanisms fall short, show you how to use Argo Rollouts to achieve zero downtime deployments, and give you a production-ready setup using the **Blue/Green strategy **.

Why Kubernetes’ Default Rollout Strategies Are Not Enough

By default, Kubernetes offers two strategies for updating applications: Recreate and RollingUpdate.

1. Recreate

This strategy terminates all existing pods before spinning up the new ones. It’s simple — and brutal. Your app goes down while the new version is starting. Not ideal unless you like your pager going off at midnight.

2. RollingUpdate

This is the default for most Kubernetes deployments. It introduces new pods gradually and retires old ones in batches. Sounds great, right?

But here’s the catch:

  • During the update process, both the old and new versions coexist.
  • The load balancer (typically a Service or Ingress) randomly routes traffic to either version.
  • That means:

    • JS/CSS assets might not match your HTML (resulting in broken UIs).
    • API contract changes could lead to inconsistent behavior.
    • Session or state handling may break.

This “half-old, half-new” state is especially painful for modern web apps, which are tightly coupled between frontend and backend versions.

The “right way” to avoid these issues is to design your application so that every version is backward and forward compatible — meaning the frontend and backend can operate seamlessly regardless of version mismatches. But let’s be honest: that’s hard. It requires meticulous planning, strict contract enforcement, and a lot of discipline. In the real world, especially when you’re building a full-stack application where you control both the frontend and backend, you don’t need to suffer this pain. You can avoid the complexity of compatibility gymnastics by treating the frontend and backend as a single unit and deploying them together — which is why many teams opt for strategies like blue-green deployments or immutable versioned releases.

Argo Rollouts to the Rescue 🚀

Argo Rollouts is a Kubernetes controller and set of CRDs (Custom Resource Definitions) that enable advanced deployment strategies like Blue/Green and Canary.

It was designed to fill the gaps in Kubernetes’ built-in deployment methods and to give teams more control, more safety, and zero downtime when shipping new code.

In this guide, we’ll focus on the Blue/Green strategy, which is the first step for those who want a clean and predictable switch between versions.

Zero-Downtime Deployment with Blue/Green Strategy

In Blue/Green deployments, we have two environments running side by side:

  • Blue (Active): The current, live version of your app.
  • Green (Preview): The new version you’re testing.

When you’re ready, you promote the Green version to become the new Active (Blue). This switch is instant and does * *not** require downtime or pod restarts.

Regular you can setup the promotion o be automatic using autoPromotionEnabled as true

Here’s how to set this up with Argo Rollouts.

Step-by-Step Guide

1. Install Argo Rollouts

You’ll need to install the Argo Rollouts controller in your cluster and add the plugin to kubectl.

Follow the official guide here: 🔗 https://argoproj.github.io/argo-rollouts/installation/

✅ Most teams only need to do this once.

2. Convert Your Deployment to a Rollout

Start by copying your existing Deployment YAML into a new file, e.g., rollout.yml.

Then, change the following:

  • apiVersion: apps/v1argoproj.io/v1alpha1
  • kind: DeploymentRollout
  • Replace the strategy block with the Blue/Green configuration:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: my-app:latest
          ports:
            - containerPort: 80
  strategy:
    blueGreen:
      activeService: my-app-svc-active
      previewService: my-app-svc-preview
      autoPromotionEnabled: true

3. Define the Services

Create two Service objects:

  • One for the active environment (receives live traffic)
  • One for the preview environment (used for validation)
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc-active
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc-preview
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80

⚠️ Don’t delete your existing service right away. You’ll need to update your Ingress (see below) before switching.

4. Update Your Ingress

Your Ingress should now point to the active service. That way, when Argo Rollouts switches from Blue to Green, the user-facing traffic is instantly redirected — no downtime, no waiting for pods to restart.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
spec:
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: my-app-svc-active
                port:
                  number: 80

✅ Final Thoughts

With Argo Rollouts and Blue/Green deployments:

  • You get true zero-downtime deploys.
  • You avoid mixing old and new versions.
  • You validate changes in preview before flipping the switch.
  • You can rollback safely without exposing bad versions.

If you care about user experience, deployment reliability, or simply peace of mind, Argo Rollouts is a must-have in your Kubernetes toolbox.