Argo CD decides what runs; a Deployment's rolling update decides how Pods are replaced — and it cannot pause at 10% traffic or check error rates. Argo Rollouts (a sister project) adds that. It is a controller plus a CRD, Rollout, that you keep in Git like any other manifest.
Canary
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: shop-api
spec:
replicas: 5
selector: { matchLabels: { app: shop-api } }
template: { ... same Pod template as the Deployment ... }
strategy:
canary:
canaryService: shop-api-canary
stableService: shop-api-stable
trafficRouting:
nginx: { stableIngress: shop-api }
steps:
- setWeight: 10
- pause: { duration: 5m }
- analysis: { templates: [{ templateName: error-rate }] }
- setWeight: 50
- pause: {} # wait for a human: kubectl argo rollouts promote
- setWeight: 100
Analysis with Prometheus
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: error-rate
spec:
metrics:
- name: error-rate
interval: 1m
count: 5
failureLimit: 1
successCondition: result[0] < 0.01
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{app="shop-api",rollout="canary",code=~"5.."}[2m]))
/ sum(rate(http_requests_total{app="shop-api",rollout="canary"}[2m]))
If the analysis fails, the Rollout aborts: traffic goes back to the stable version automatically, without waiting for a human.
Blue-green
strategy:
blueGreen:
activeService: shop-api
previewService: shop-api-preview
autoPromotionEnabled: false
prePromotionAnalysis: { templates: [{ templateName: smoke }] }
The new version runs next to the old one behind a preview Service; promotion switches the active Service in one step.
| Canary | Blue-green | |
|---|---|---|
| Traffic shift | Gradual (10% → 50% → 100%) | All at once |
| Extra capacity | Small | A full second stack while both run |
| Best for | High-traffic APIs with good metrics | Apps that need a full check before any user sees them |
Working with Argo CD
- Argo CD knows the Rollout's health: Paused shows as Suspended, an aborted rollout as Degraded.
- A Git commit with a new image starts the rollout; promotion and abort happen through the Rollouts plugin or UI, not through Git.
- With selfHeal, avoid changing
specby hand during a rollout; use the plugin commands.
kubectl argo rollouts get rollout shop-api -n shop-prod --watch
kubectl argo rollouts promote shop-api -n shop-prod
kubectl argo rollouts abort shop-api -n shop-prod