Skip to content
DevOps Kubernetes CI/CD

Progressive Delivery on Kubernetes: Argo Rollouts + Service Mesh

Ian David Rossi
Ian David Rossi July 15, 2021 · 6 min read

TL;DR

Progressive Delivery on Kubernetes: Argo Rollouts + Service Mesh without the fluff: focus on outcomes, measure them, and stop pretending slides are progress.

“If every bad release still hits 100% of users at once, you are not doing progressive delivery—you just moved your deploy button.”

Why Progressive Delivery?

Traditional deployments flip traffic instantly to a new version. If it’s bad, everyone hurts. Progressive delivery lets you shift traffic gradually—validating real signals before full rollout. Argo Rollouts brings first‑class strategies to Kubernetes; a service mesh provides fine‑grained traffic control and telemetry to make this safe.

Progressive delivery isn’t only technical safety—it’s about tying releases to user and business metrics so the pipeline can prove value (or harm) before all customers feel it.

Core Strategies

  • Canary: Shift a small percentage of traffic to the new version; increase as metrics stay healthy.
  • Blue‑Green: Fully provision the new version, then swap traffic atomically with instant rollback.
  • A/B or Experimentation: Route based on attributes (user cohort, geography); evaluate business outcomes before full rollout.
  • Shadow/Preview: Mirror traffic to the new version without affecting users; capture telemetry before production impact.

Prerequisites

  • Kubernetes cluster with Istio, Linkerd, or another mesh capable of traffic splitting.
  • Metrics and logs (Prometheus + Grafana, Loki/OpenSearch) with golden signals (errors, latency, saturation) and business KPIs.
  • Health probes (readiness/liveness) and synthetic tests per service.
  • CI/CD pipeline and GitOps or Argo CD integration so manifest changes are reviewed and automated.
  • Rollback runbooks and feature flag tooling for kill switches.

Runbook: Progressive Delivery in Six Steps

  1. Baseline: Define SLIs/SLOs for the service. Instrument error rate, latency, saturation, and business KPIs (conversion, checkout success).
  2. Configure rollout: Write Argo Rollout spec (strategy, steps, analysis). Commit mesh VirtualService/DestinationRule or Linkerd ServiceProfile updates.
  3. Automate analysis: Create AnalysisTemplates for metrics and optionally log queries. Set success/fail conditions and timeouts.
  4. Dry run: Rehearse rollouts in staging with real traffic replay. Test abort/rollback paths and make sure alerts fire.
  5. Deploy to prod: Merge PR; watch Rollout progression, mesh telemetry, and analysis outputs. Pause if anomalies appear; require manual approve for high-risk services.
  6. Post-release: Capture outcome (success, abort, manual override). Update runbooks with new thresholds or pitfalls.

“A canary without intent is mural art; a canary with metrics is a brake pedal.”

Example: Canary with Argo Rollouts + Istio

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api
spec:
  replicas: 4
  strategy:
    canary:
      canaryService: api-canary
      stableService: api-stable
      trafficRouting:
        istio:
          virtualService: api-vs
          destinationRule: api-dr
      steps:
      - setWeight: 10
      - pause: {duration: 60}
      - setWeight: 25
      - pause: {duration: 120}
      - setWeight: 50
      - analysis:
          templates:
          - templateName: error-rate-check
          args:
          - name: threshold
            value: "0.02"

Pair with Istio routing:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: api-vs
spec:
  hosts: ["api.svc.cluster.local"]
  http:
  - route:
    - destination: {host: api, subset: stable, weight: 90}
    - destination: {host: api, subset: canary, weight: 10}
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: api-dr
spec:
  host: api
  subsets:
  - name: stable
    labels: {version: stable}
  - name: canary
    labels: {version: canary}

Automated Analysis

Define AnalysisTemplates that query Prometheus for error rate, latency, and saturation. Rollouts can pause or abort if thresholds fail.

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: error-rate-check
spec:
  metrics:
  - name: error-rate
    interval: 1m
    successCondition: result < 0.02
    provider:
      prometheus:
        address: http://prometheus:9090
        query: |
          sum(rate(http_requests_total{job="api",status=~"5.."}[5m])) /
          sum(rate(http_requests_total{job="api"}[5m]))

Rollback and Safety

  • Use max surge/unavailable to keep capacity during rollout.
  • Abort on failed analysis—traffic returns to stable automatically.
  • Keep feature flags for instant kill‑switches if behavior goes wrong.
  • Keep stable pods around until rollout success; avoid scale-to-zero.
  • Integrate rollback commands into CI (e.g., kubectl argo rollouts undo or Git revert) so response is seconds, not minutes.
  • Alert on stuck rollouts (paused too long) and provide runbooks in alerts.

Operational Practices

  • Stage changes in non‑prod; rehearse rollbacks monthly.
  • Alert on analysis failures, aborted rollouts, and manual overrides; annotate incidents with rollout IDs.
  • Track rollout history and reasons; annotate PRs with success/failure and metrics observed.
  • Gate rollouts on SLO burn: if the service is already burning error budget, freeze or limit traffic weights.

Observability and Metrics

  • Controller metrics: rollout phase, step progression, analysis successes/failures.
  • Mesh metrics: per-subset latency/error, SLO burn by version.
  • Business KPIs per version: conversions, revenue, latency budgets.
  • Alert when rollout error rate > threshold, analysis fails repeatedly, or steps take longer than expected.
  • Report change failure rate (number of aborted rollouts / total) and MTTR (time to rollback).

Tooling Stack

  • Argo Rollouts for strategy and analysis.
  • Service mesh (Istio/Linkerd/Ambassador) for traffic splitting and mTLS.
  • Metrics providers: Prometheus, Datadog, New Relic; ensure queries finish within analysis intervals.
  • Logging: Loki/ELK for log-based checks.
  • Feature flags: LaunchDarkly/OpenFeature for kill switches and A/B toggles.
  • GitOps: Argo CD/Flux or pipelines that keep manifests synced.

Keep the stack cohesive; too many variations lead to brittle releases.

Automated Analysis

Define AnalysisTemplates that query Prometheus for error rate, latency, saturation, or business metrics. Rollouts can pause or abort if thresholds fail.

Operational Practices

  • Stage changes in non‑prod; rehearse rollbacks regularly.
  • Alert on analysis failures and aborts; include runbooks in alerts.
  • Track rollout history and reasons; annotate PRs with outcomes.
  • Document known-good ramp schedules per service and update when traffic patterns change.

30/60/90 Adoption Plan

  • 30 days: Deploy Argo Rollouts in dev/stage; manually control canaries; instrument alerts and runbooks.
  • 60 days: Automate analysis (Prometheus/logs); integrate service mesh or ingress; run at least one prod canary.
  • 90 days: Expand to majority of services; tie rollouts to feature flags; measure change failure rate, MTTR, and business KPIs; enforce policy (no direct Deployments in prod).

Common Pitfalls and Fixes

  • Single-metric canaries: Only watching 500s ignores latency or business metrics. Add multiple analysis metrics.
  • Parallel rollouts: Deploying dependent services simultaneously hides root cause. Stagger or coordinate with App-of-Apps bundles.
  • Manual overrides: Developers bypass rollouts with kubectl. Enforce via RBAC + GitOps.
  • Mesh drift: VirtualService out-of-sync with Rollout. Co-locate configs and run CI linting.
  • No kill switch: Analysis fails but business still suffers until manual revert. Add feature flags or immediate abort triggers.

Case Study (Hypothetical)

A SaaS billing team uses Argo Rollouts with Istio. They run steps (10%→25%→50%→100%) with Prometheus analysis on error rate <2% and p95 latency <300 ms. At 25% weight, error rate hits 3%; Argo auto-aborts, returning traffic to stable. An alert in Slack includes the AnalysisRun, Grafana link, and runbook. Engineers fix a misconfigured timeout, push a new image, and the next rollout succeeds. Change failure rate drops from 18% to 6% and MTTR shrinks to 4 minutes.

Practical Checklist

  • Rollout spec committed with canary/blue-green steps and analysis.
  • Mesh routes/DestinationRules updated alongside rollout.
  • AnalysisTemplates tested manually (promtool/log queries).
  • Alerts wired to analysis failures, stuck rollouts, and manual overrides.
  • Feature flags ready for instant kill.
  • Runbook documents rollback commands (kubectl argo rollouts undo or Git revert) and required approvals.

Conclusion

Progressive delivery reduces incident impact and increases confidence. With Argo Rollouts and a service mesh, you get traffic shaping, automated analysis, and fast rollback—all encoded as code. Adopt canary first, then expand to blue‑green and A/B where it delivers clear value. Continuous practice—metrics, alerts, and drills—turns progressive delivery from a demo into a dependable habit.

Glossary (Tooltips)

  • mTLS: A common service-mesh feature for identity and encryption between services.
  • SLO: The user-centric bar canaries should protect.
  • MTTR: Progressive delivery’s promise is to shrink this through fast rollback.
  • p95: A better latency signal than averages for canary analysis.
  • RBAC: Prevents bypassing rollouts with ad-hoc kubectl.
  • CI: Where you lint and validate rollout configs before they reach production.