
September 09, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Releases fail when you push a new container image straight to every pod at once. Blue-Green and Canary Deploys on Kubernetes give you a safer path: run the new version beside the old one, send real traffic in controlled steps, and roll back by flipping a selector or weight. If you already run workloads on a cluster, these patterns fit naturally on top of Deployments, Services, and Ingress. This guide walks through practical manifests, traffic-split mechanics, and the trade-offs I weigh on production systems—including Laravel apps on Kubernetes and CI pipelines that mirror bare-metal blue-green CI/CD workflows.
What is the difference between Blue-Green and Canary Deploys on Kubernetes?
Both strategies reduce blast radius during a release. They differ in how fast traffic moves and how much observability you need before full promotion.
Blue-green keeps two full stacks alive. Stable pods sit behind one Service label set; candidate pods sit behind another. You validate green, then switch 100% of traffic in one step—usually by updating a Service selector or swapping an Ingress backend. Rollback is equally fast: point traffic back to blue.
Canary sends a small slice of live traffic to the new version first—often 5%, then 25%, then 50%, then 100%. You watch error rates, latency, and business metrics between steps. If metrics degrade, you drain canary weight to zero without touching stable pods.
Native Kubernetes Deployments use a RollingUpdate strategy by default. That is neither blue-green nor canary—it replaces pods incrementally with limited surge. For true blue-green or weighted canary, you add either manual Service wiring or a progressive delivery tool.
| Criteria | Blue-Green | Canary | RollingUpdate (built-in) |
|---|---|---|---|
| Traffic shift | Instant 0→100% | Gradual weights | Pod-by-pod replacement |
| Resource cost | 2× pods during cutover | 1× + small canary slice | ~1× with surge |
| Rollback speed | Seconds (selector flip) | Drain canary weight | kubectl rollout undo |
| Metric gates | Manual pre-switch checks | Automated between steps | None native |
| Complexity | Low with two Services | Medium—needs Ingress or mesh | Lowest |
| Best fit | Schema migrations, big jumps | High-traffic APIs, A/B risk | Small teams, low risk |
For a deeper strategy-only comparison, see the dedicated write-up on blue-green vs canary deployment strategies.
How do you implement a Blue-Green deployment on Kubernetes?
Blue-green on Kubernetes usually means two Deployments and one active Service selector. Stable runs as app=myapp,version=blue; candidate runs as app=myapp,version=green. Only one version receives production traffic at a time.
Step 1: Deploy both versions
Create separate Deployments so each version scales independently. Keep image tags explicit—never rely on :latest in production.
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
labels:
app: myapp
version: blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: registry.example.com/myapp:2.4.0
ports:
- containerPort: 8080
---
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
labels:
app: myapp
version: green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: registry.example.com/myapp:2.5.0
ports:
- containerPort: 8080
Step 2: Wire the active Service
Point your production Service at blue initially. Green pods start but receive no traffic until you patch the selector.
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
version: blue
ports:
- port: 80
targetPort: 8080
Step 3: Validate green, then switch
Run smoke tests against green through a headless or internal Service. When satisfied, flip the selector to green.
kubectl apply -f green-deployment.yaml
kubectl run curl-test --rm -it --image=curlimages/curl -- \
curl -sf http://myapp-green-internal:8080/health
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
Rollback is the same patch with "version":"blue". Keep blue scaled for one release cycle if disk and budget allow. That gives you an instant fallback without rebuilding pods.
On clusters I help maintain, I pair this pattern with Velero backups before schema changes. Blue-green gives you a clean cutover window; backups cover the rare case where rollback needs data repair too.
How do you run a Canary deployment on Kubernetes with traffic splitting?
Canary needs a layer that understands weights. Plain ClusterIP Services round-robin evenly—they cannot send 10% to canary. You typically use Ingress canary annotations, a service mesh, or Argo Rollouts.
Option A: NGINX Ingress canary annotations
If your cluster runs the NGINX Ingress Controller, annotate a second Ingress resource to mirror the stable one but route by weight or header.
# stable ingress (existing)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-stable
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-stable
port:
number: 80
---
# canary ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-canary
port:
number: 80
Increase weight in steps: 10 → 25 → 50 → 100. Watch Prometheus or your APM between each bump. Drop weight to zero if error rate spikes.
Option B: Argo Rollouts
Argo Rollouts replaces Deployment for progressive delivery. It integrates with NGINX, Istio, and ALB for automated weight shifts and analysis runs.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 25
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 5m}
- setWeight: 100
canaryService: myapp-canary
stableService: myapp-stable
trafficRouting:
nginx:
stableIngress: myapp-stable
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: registry.example.com/myapp:2.5.0
ports:
- containerPort: 8080
GitOps teams often manage Rollouts through Argo CD. The Rollout CRD owns promotion logic; Argo CD syncs the desired state from Git.
Validate JSON health payloads during canary soak with a local JSON formatter before you wire automated analysis queries. Small schema drift in /health responses has caused false-positive rollbacks for me.
Which tools support Blue-Green and Canary Deploys on Kubernetes?
Pick tooling based on what you already run. Adding Istio solely for canary is heavy if you only ship twice a month.
- Native kubectl —
kubectl rollout statusandkubectl rollout undofor RollingUpdate; manual Service patches for blue-green. - NGINX Ingress — Canary annotations by weight, header, or cookie. No mesh required.
- Argo Rollouts — CRD with built-in steps, analysis templates, and rollback.
- Istio / Linkerd — Fine-grained traffic split via VirtualService or TrafficSplit.
- Flagger — Operator that automates canary with Prometheus, Grafana, or CloudWatch checks.
- Helm — Package dual Deployments and Ingress pairs; see Helm charts for Kubernetes apps.
The official Kubernetes Deployment documentation covers RollingUpdate well. It does not replace progressive delivery controllers for weighted canary—you extend the platform with Ingress or a Rollout CRD.
For autoscaling during canary, tie Horizontal Pod Autoscaling to both stable and canary Deployments. A 10% traffic slice still needs enough canary replicas to handle peak RPS without throttling.
When should you choose Blue-Green vs Canary on Kubernetes?
Neither pattern wins every time. Match the strategy to release risk, traffic volume, and team maturity.
Choose blue-green when:
- You run database migrations that require a hard cutover window.
- Your app cannot serve two API versions simultaneously.
- You need rollback in seconds without gradual drain.
- Traffic is moderate and doubling pod count briefly is affordable—often Rs 8,000–15,000/month (~USD 60–110) extra on a small DOKS cluster.
Choose canary when:
- You serve high RPS APIs where 1% bad traffic still hurts revenue.
- Prometheus or Datadog already tracks SLIs you trust.
- You release frequently and want promotion automated in CI.
- You can tolerate longer rollout windows—30–90 minutes is normal.
On a production Laravel booking app, I default to canary for API pods and blue-green for worker Deployments. Workers do not sit behind Ingress; flipping their Deployment is cleaner than partial queues.
What are common mistakes with Blue-Green and Canary Deploys on Kubernetes?
These patterns fail in predictable ways. Most are configuration gaps, not Kubernetes bugs.
Shared state and session stickiness
Blue-green breaks when sessions live in pod memory. Externalize sessions to Redis 8.10 or a database before you attempt either pattern. Canary has the same requirement—users routed to canary must not lose auth state.
Forgetting readiness probes
Green pods marked Ready before the app accepts traffic cause 502s the moment you switch. Align readinessProbe with real dependencies—DB, cache, migrations complete. Debug failing pods with the steps in CrashLoopBackOff troubleshooting.
Canary without metrics
Manual weight bumps without SLI checks are just slow rolling updates. Define abort thresholds upfront: HTTP 5xx above 1%, p99 latency 2× baseline, or business KPI dips.
Resource quotas and HPA conflicts
Blue-green at 2× replicas can hit namespace quotas. Pre-scale green before cutover. Review resource limits and requests so neither stack gets OOMKilled under load.
Ignoring DNS and Ingress caching
Some CDNs cache by URL regardless of backend. Purge edge cache after blue-green switch. Canary header routing fails if clients ignore custom headers—use weight-based splits for browser traffic.
Lock down who can patch production Services. A mistaken selector flip is a production incident. Tight RBAC policies limit patch rights to your CD pipeline service account.
Key Takeaways
- Blue-Green and Canary Deploys on Kubernetes run parallel versions; blue-green switches traffic instantly via Service selectors, canary shifts weight in gated steps.
- Plain Deployments only offer RollingUpdate—add NGINX Ingress canary annotations, Argo Rollouts, or a mesh for true weighted canary.
- Validate green internally before patching the production Service; keep blue scaled briefly for fast rollback.
- Automate canary promotion with SLI checks—error rate, latency, and custom PromQL—not manual guesswork.
- Externalize sessions and state before either pattern; readiness probes must reflect real app readiness.
- Match strategy to risk: schema migrations favor blue-green; high-traffic APIs favor canary with observability.
People Also Ask
Can Kubernetes Deployments do canary releases natively?
No. Standard Deployments support RollingUpdate and Recreate only. Weighted canary requires Ingress annotations, a service mesh, or a progressive delivery controller like Argo Rollouts. You can approximate canary by running two Deployments and manually adjusting replica counts, but that is coarse and not weight-accurate.
How is blue-green different from a RollingUpdate?
RollingUpdate replaces old pods incrementally while traffic always hits a mixed pool. Blue-green keeps 100% of traffic on one version until you deliberately switch. Rollback with RollingUpdate uses revision history; blue-green rollback is a Service selector patch back to the idle stack.
Does blue-green deployment cost more on Kubernetes?
Yes, temporarily. You run two full replica sets during the overlap window. Plan for roughly double CPU and memory until you scale down blue. Canary usually costs less because the new version starts at a small replica count and traffic slice.
What is the fastest rollback method after a bad canary?
Set canary Ingress weight to zero or run kubectl argo rollouts abort myapp if you use Argo Rollouts. Stable pods never left the pool, so traffic returns immediately. Then investigate the failed image tag before retrying.
Ship safer releases on Kubernetes
Blue-Green and Canary Deploys on Kubernetes turn releases from a single risky event into a controlled experiment. Start with manual blue-green on two Deployments if your team is new to the cluster. Add Argo Rollouts or Ingress canary once Prometheus dashboards and runbooks exist. The goal is not fancy tooling—it is sleeping through deploy night.
If you want help designing a progressive delivery pipeline for your app—or migrating from symlink Deployer releases to Kubernetes—Linux and Kubernetes administration and ongoing support cover cluster setup through production runbooks. See how similar systems were shipped on Adventure Third Pole Trek and Notary Kathmandu, or contact us to plan your rollout strategy.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

