11.4 Progressive Delivery Automation: Argo Rollouts, Flagger & Feature Flags
Key Takeaways
Progressive delivery is the automation of a release strategy — a controller shifts traffic in steps, evaluates metrics, and promotes or rolls back without human intervention.
Argo Rollouts replaces the Deployment object with a Rollout custom resource that owns the canary or blue/green steps natively.
Flagger drives an existing Deployment by manipulating a service mesh or ingress controller's traffic weights instead of replacing the workload object.
Automated analysis queries a metrics provider such as Prometheus against a success threshold, and a failed analysis aborts the rollout and restores full traffic to the stable version.
Feature flags separate deployment from release, so code can ship dark and be switched on for a user segment without another rollout.
11.4 Progressive Delivery Automation: Argo Rollouts, Flagger & Feature Flags
Quick Answer: Section 11.3 described what canary and blue/green releases are. Progressive delivery is the automation that actually runs them: a controller shifts traffic in defined steps, queries metrics after each step, and promotes or aborts on its own. Argo Rollouts replaces the
Deploymentobject with aRolloutCRD; Flagger leaves the Deployment in place and drives a service mesh or ingress controller. Feature flags go further still, decoupling deployment from release entirely.
A canary that nobody watches is not a canary — it is a slow outage. The automation is the point.
1. Why Native Deployments Are Not Enough
A Kubernetes Deployment gives you exactly one automated strategy, RollingUpdate, and its only health signal is the readiness probe. That probe answers "is the process accepting connections?" — not "is the new version returning correct answers at an acceptable error rate and latency?"
So a build that passes readiness but returns HTTP 500 on 20% of requests will roll out to 100% of your fleet, cheerfully, in about ninety seconds.
| Capability | Deployment | Progressive delivery controller |
|---|---|---|
| Incremental pod replacement | Yes | Yes |
| Precise traffic weights (5%, 25%, 50%) | No | Yes |
| Automated metric analysis between steps | No | Yes |
| Automatic abort on a bad metric | No | Yes |
| Manual promotion gate mid-rollout | No | Yes |
| Blue/green with a pre-promotion test hook | No | Yes |
2. Argo Rollouts
Argo Rollouts introduces a Rollout custom resource that is a drop-in replacement for a Deployment — same Pod template, plus a strategy block that describes the release as a sequence of steps.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api
spec:
replicas: 10
strategy:
canary:
canaryService: api-canary
stableService: api-stable
trafficRouting:
istio:
virtualService: { name: api-vs }
steps:
- setWeight: 5
- pause: { duration: 5m } # observe
- analysis: # automated gate
templates:
- templateName: success-rate
- setWeight: 25
- pause: { duration: 10m }
- setWeight: 50
- pause: {} # indefinite: wait for manual promotion
- setWeight: 100
template:
# ... identical to a Deployment pod template ...
Three kinds of step, and knowing the difference is the exam-relevant part:
setWeight— move a percentage of traffic to the canary.pause: { duration }— wait a fixed period so metrics accumulate.pause: {}with no duration — wait indefinitely for a human to runkubectl argo rollouts promote.analysis— run anAnalysisTemplateand continue only if it succeeds.
Argo Rollouts also implements blue/green with previewService, prePromotionAnalysis, and postPromotionAnalysis hooks, plus a configurable scaleDownDelaySeconds that keeps the old version warm for an instant rollback.
3. Flagger
Flagger takes the opposite design decision: it leaves your Deployment untouched and adds a Canary resource that drives it, manipulating the traffic weights of an underlying mesh or ingress (Istio, Linkerd, NGINX, Traefik, Gateway API).
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: api
spec:
targetRef: { apiVersion: apps/v1, kind: Deployment, name: api }
service: { port: 80 }
analysis:
interval: 1m
threshold: 5 # abort after 5 failed checks
maxWeight: 50
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange: { min: 99 }
interval: 1m
- name: request-duration
thresholdRange: { max: 500 }
interval: 1m
webhooks:
- name: load-test
url: http://flagger-loadtester/
| Argo Rollouts | Flagger | |
|---|---|---|
| Workload object | Replaces Deployment with Rollout | Keeps the Deployment, adds a Canary |
| Traffic control | Mesh, ingress, or replica ratio | Requires a mesh or supported ingress |
| Migration cost | Change kind: on existing manifests | Add one object, change nothing else |
| Home | Argo project (CNCF graduated) | Flux project (CNCF graduated) |
4. Automated Analysis Is the Real Feature
Both controllers reduce to the same loop: shift a little traffic, ask a metrics provider whether things are still healthy, then continue or abort.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 1m
count: 5
successCondition: result[0] >= 0.99
failureLimit: 2
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{job="api",code!~"5.."}[2m]))
/
sum(rate(http_requests_total{job="api"}[2m]))
Providers include Prometheus, Datadog, New Relic, CloudWatch, and Kubernetes Jobs for arbitrary checks. On failure the controller immediately returns 100% of traffic to the stable version and scales the canary to zero — mean time to recovery measured in seconds rather than in however long it takes to page someone.
This is also where sections 12.1 and 11.4 interlock: you cannot automate a promotion decision without the metrics from your observability stack. Progressive delivery is observability with a control loop attached.
5. Feature Flags: Decoupling Deployment from Release
Even a perfect canary still ties a user-visible change to a deployment. Feature flags break that link:
DEPLOY ── ship the code to production, flag OFF ──► nobody sees it
RELEASE ── flip the flag for 1% of users ─────────► gradual exposure
ROLLBACK ─ flip the flag back ────────────────────► instant, no redeploy
Benefits that a rollout controller alone cannot give you:
- Rollback in milliseconds — a configuration change, not a rollout.
- Targeting by attribute — internal staff, a beta cohort, a single region.
- Trunk-based development — merge incomplete work behind a flag instead of maintaining long-lived branches.
- Experimentation — the A/B testing pattern from section 11.3, controlled per user rather than per Pod.
OpenFeature is the CNCF project standardising the flag-evaluation API across vendors, so application code is written once against a vendor-neutral SDK.
The cost is real and should be stated: every flag is a branch in production, and un-retired flags accumulate into combinatorial complexity nobody can reason about. Mature teams treat flag removal as part of the definition of done.
6. Choosing
| Situation | Approach |
|---|---|
| Small internal service, low blast radius | Plain Deployment with a good readiness probe |
| User-facing service, mesh already installed | Flagger — least disruption to existing manifests |
| Complex multi-step release with manual gates and blue/green hooks | Argo Rollouts |
| Change must be reversible in seconds, or targeted at a user segment | Feature flags |
| Regulated environment requiring an explicit human approval | Rollout controller with an indefinite pause: {} step |
What does a progressive delivery controller add that a standard Kubernetes Deployment rolling update cannot provide?
The ability to replace Pods incrementally without downtime
Automated metric analysis between traffic steps, with automatic abort and rollback when a threshold such as success rate is breached
Support for readiness and liveness probes
The ability to store multiple revisions for manual rollback
What is the architectural difference between Argo Rollouts and Flagger?
Argo Rollouts replaces the Deployment with a Rollout custom resource, while Flagger leaves the Deployment in place and drives traffic weights through a mesh or ingress controller
Argo Rollouts only supports blue/green while Flagger only supports canary
Flagger requires no metrics provider whereas Argo Rollouts always does
Argo Rollouts runs outside the cluster while Flagger runs as an in-cluster controller
What problem do feature flags solve that a canary rollout does not?
They remove the need for readiness probes on new Pods
They decouple deployment from release, so code can ship disabled and be switched on or off for a chosen user segment in milliseconds without another rollout
They guarantee that a new version has no CVEs before it reaches production
They replace the need for a metrics provider during a release
Sections you finish are checked off in the contents.