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/v1
→argoproj.io/v1alpha1
kind: Deployment
→Rollout
- 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.