Elke deployment is een risico. De vraag is niet óf er iets fout gaat — maar hoeveel schade het veroorzaakt wanneer het gebeurt.

Traditionele Kubernetes deployments zijn alles-of-niets. Je pusht een nieuwe versie, en binnen seconden raakt 100% van je traffic de nieuwe code. Als er een bug is, ziet iedereen het. Als de service crasht, zijn alle gebruikers getroffen.

Progressive delivery verandert deze vergelijking. In plaats van naar iedereen tegelijk te deployen, verschuif je geleidelijk traffic naar de nieuwe versie, en valideer je bij elke stap. Als er iets misgaat, is slechts een fractie van de gebruikers getroffen.

Argo Rollouts brengt progressive delivery naar Kubernetes als drop-in vervanging voor Deployments.

Waarom Progressive Delivery?

Overweeg wat er gebeurt met een standaard Deployment tijdens een bug release:

Tijd 0:00 - Deploy nieuwe versie
Tijd 0:02 - Alle pods draaien nieuwe versie
Tijd 0:05 - Errors beginnen te verschijnen
Tijd 0:08 - Alerts gaan af
Tijd 0:15 - Engineer onderzoekt
Tijd 0:25 - Rollback gestart
Tijd 0:27 - Alle pods terug naar oude versie

Blast radius: 100% van gebruikers voor ~25 minuten

Met progressive delivery:

Tijd 0:00 - Deploy nieuwe versie (5% traffic)
Tijd 0:05 - Geautomatiseerde analyse detecteert errors
Tijd 0:06 - Automatische rollback

Blast radius: 5% van gebruikers voor ~6 minuten

Dit is resilience. Niet failures voorkomen, maar hun impact beperken.

Twee Strategieën: Canary vs Blue-Green

Argo Rollouts ondersteunt meerdere strategieën. De twee meest voorkomende:

Canary

Traffic verschuift geleidelijk van oude naar nieuwe versie:

Stap 1:  5% nieuw, 95% oud   (test the waters)
Stap 2: 20% nieuw, 80% oud   (uitbreiden als gezond)
Stap 3: 50% nieuw, 50% oud   (halverwege)
Stap 4: 100% nieuw, 0% oud   (volledige rollout)

Best voor: Stateless services, high-traffic applicaties waar je geleidelijke validatie wilt.

Blue-Green

Twee complete omgevingen, directe switch:

Voor:    100% blue (oud)     0% green (nieuw)
Deploy:  100% blue           green klaar, ontvangt geen traffic
Switch:    0% blue         100% green

Best voor: Services die directe rollback vereisen, database migraties, wanneer je beide versies simultaan wilt draaien voor testen.

Argo Rollouts Installeren

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

Voor GitOps met ArgoCD, voeg het toe als Application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argo-rollouts
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://argoproj.github.io/argo-helm
    chart: argo-rollouts
    targetRevision: 2.35.1
    helm:
      values: |
        dashboard:
          enabled: true
  destination:
    server: https://kubernetes.default.svc
    namespace: argo-rollouts
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Canary Rollout Voorbeeld

Vervang je Deployment door een Rollout:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 10
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:v2.0.0
          ports:
            - containerPort: 8080
  strategy:
    canary:
      steps:
        - setWeight: 5
        - pause: { duration: 5m }
        - setWeight: 20
        - pause: { duration: 5m }
        - setWeight: 50
        - pause: { duration: 5m }
        - setWeight: 100

Dit creëert een geleidelijke rollout van 20 minuten:

  1. Stuur 5% van traffic naar nieuwe versie, wacht 5 minuten
  2. Als gezond, verhoog naar 20%, wacht 5 minuten
  3. Als gezond, verhoog naar 50%, wacht 5 minuten
  4. Voltooi rollout naar 100%

Op elk moment, als je rollback doet, keert traffic direct terug naar de oude versie.

Traffic Management

Standaard gebruikt Argo Rollouts replica count om traffic weight te benaderen. Voor precieze traffic controle, integreer met je ingress:

Met Traefik

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  strategy:
    canary:
      canaryService: my-app-canary
      stableService: my-app-stable
      trafficRouting:
        traefik:
          weightedTraefikServiceName: my-app-weighted
      steps:
        - setWeight: 10
        - pause: { duration: 2m }
        - setWeight: 50
        - pause: { duration: 2m }

Met ondersteunende TraefikService:

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: my-app-weighted
spec:
  weighted:
    services:
      - name: my-app-stable
        port: 80
        weight: 100  # Beheerd door Argo Rollouts
      - name: my-app-canary
        port: 80
        weight: 0    # Beheerd door Argo Rollouts

Met Nginx Ingress

apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
  strategy:
    canary:
      canaryService: my-app-canary
      stableService: my-app-stable
      trafficRouting:
        nginx:
          stableIngress: my-app-ingress

Met Istio

apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
  strategy:
    canary:
      trafficRouting:
        istio:
          virtualService:
            name: my-app-vsvc
            routes:
              - primary

Blue-Green Rollout

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 5
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:v2.0.0
  strategy:
    blueGreen:
      activeService: my-app-active
      previewService: my-app-preview
      autoPromotionEnabled: false
      prePromotionAnalysis:
        templates:
          - templateName: smoke-tests
      postPromotionAnalysis:
        templates:
          - templateName: load-test

Dit creëert:

  • my-app-active: Wijst naar huidige productie versie
  • my-app-preview: Wijst naar nieuwe versie voor testen

De nieuwe versie wordt gedeployed maar ontvangt geen productie traffic totdat je promoot.

Geautomatiseerde Analyse

De echte kracht van progressive delivery is geautomatiseerde rollback. Argo Rollouts kan metrics analyseren tijdens rollout en afbreken als er iets misgaat.

Analysis Template

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 1m
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{service="{{args.service-name}}",status=~"2.."}[5m])) /
            sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))

Deze template:

  • Queryt Prometheus elke minuut
  • Checkt of success rate >= 95% is
  • Faalt de rollout na 3 opeenvolgende failures

Analysis Gebruiken in Rollout

apiVersion: argoproj.io/v1alpha1
kind: Rollout
spec:
  strategy:
    canary:
      steps:
        - setWeight: 5
        - pause: { duration: 2m }
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: my-app
        - setWeight: 50
        - pause: { duration: 5m }
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: my-app

Nu doet de rollout:

  1. Verschuift 5% traffic
  2. Wacht 2 minuten
  3. Draait analyse — als het faalt, automatische rollback
  4. Als analyse slaagt, verschuift naar 50%
  5. Draait analyse opnieuw
  6. Voltooit rollout

Meerdere Analysis Metrics

Combineer meerdere checks:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: comprehensive-check
spec:
  args:
    - name: service-name
  metrics:
    # HTTP success rate
    - name: success-rate
      interval: 1m
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{service="{{args.service-name}}",status=~"2.."}[5m])) /
            sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))

    # P99 latency
    - name: latency-p99
      interval: 1m
      successCondition: result[0] < 0.5
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="{{args.service-name}}"}[5m])) by (le))

    # Error rate
    - name: error-rate
      interval: 1m
      successCondition: result[0] < 0.01
      failureLimit: 2
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{service="{{args.service-name}}",status=~"5.."}[5m])) /
            sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))

Web-Based Job Analyse

Voor niet-Prometheus checks (smoke tests, integratie tests):

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: smoke-test
spec:
  metrics:
    - name: smoke-test
      provider:
        job:
          spec:
            backoffLimit: 1
            template:
              spec:
                containers:
                  - name: smoke
                    image: curlimages/curl
                    command:
                      - /bin/sh
                      - -c
                      - |
                        curl -f http://my-app-canary/health || exit 1
                        curl -f http://my-app-canary/api/status || exit 1
                restartPolicy: Never

Dashboard en CLI

Monitor rollouts met de Argo Rollouts kubectl plugin:

# Installeer plugin
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-darwin-amd64
chmod +x kubectl-argo-rollouts-darwin-amd64
mv kubectl-argo-rollouts-darwin-amd64 /usr/local/bin/kubectl-argo-rollouts

# Watch rollout progress
kubectl argo rollouts get rollout my-app -w

# Handmatig promoten (als autoPromotion disabled is)
kubectl argo rollouts promote my-app

# Afbreken en rollback
kubectl argo rollouts abort my-app

# View dashboard
kubectl argo rollouts dashboard

Het dashboard toont real-time traffic distributie en analyse status.

Integratie met GitOps

Bij gebruik van ArgoCD werken Rollouts naadloos. Update de image tag in Git, ArgoCD synct, en de progressive rollout begint.

# In je GitOps repo
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: my-app:v2.1.0  # Update deze regel

De semantic versioning pipeline maakt de tag, die een update triggert naar de GitOps repo, die ArgoCD synct, die de Rollout start.

Notificaties

Word genotificeerd over rollout events:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
  annotations:
    notifications.argoproj.io/subscribe.on-rollout-completed.slack: my-channel
    notifications.argoproj.io/subscribe.on-rollout-aborted.slack: my-channel

Configureer de notification controller separaat (deelt configuratie met ArgoCD notifications).

Mijn Productie Setup

Hier is mijn daadwerkelijke Rollout configuratie:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api
spec:
  replicas: 5
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: registry.example.com/api:v1.0.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
  strategy:
    canary:
      canaryService: api-canary
      stableService: api-stable
      trafficRouting:
        traefik:
          weightedTraefikServiceName: api-weighted
      steps:
        # Fase 1: Smoke test
        - setWeight: 5
        - pause: { duration: 2m }
        - analysis:
            templates:
              - templateName: smoke-test

        # Fase 2: Beperkte blootstelling
        - setWeight: 25
        - pause: { duration: 5m }
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: api

        # Fase 3: Meerderheid traffic
        - setWeight: 75
        - pause: { duration: 10m }
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: api

        # Fase 4: Volledige rollout
        - setWeight: 100
      rollbackWindow:
        revisions: 2

Belangrijke beslissingen:

  • Meerdere analyse fases — Vroege smoke test, dan metric-gebaseerde validatie
  • Toenemende pause duren — Meer tijd bij hogere traffic percentages
  • Rollback window — Kan snel terug naar laatste 2 versies

Wanneer Geen Progressive Delivery

Progressive delivery voegt complexiteit toe. Sla het over wanneer:

  • Breaking database schema changes — Je hebt de hele app op één versie nodig
  • Single-user applicaties — Geen zinvolle traffic om te splitsen
  • Simpele interne tools — De overhead is het niet waard
  • Tight coupling tussen services — Wanneer services samen moeten upgraden

Voor de meeste productie services die echte gebruikers bedienen, is progressive delivery de investering waard.

Waarom Dit Ertoe Doet

Elke deployment is een gecontroleerd experiment. Je test de hypothese dat je nieuwe code werkt in productie.

Progressive delivery maakt dat experiment veiliger:

  • Kleinere blast radius — Problemen raken minder gebruikers
  • Snellere detectie — Geautomatiseerde analyse vangt issues vroeg
  • Directe recovery — Één commando keert terug naar bekende-goede staat

Dit is resilience in de praktijk. Niet hopen dat deployments slagen, maar systemen ontwerpen die graceful omgaan met wanneer ze dat niet doen.


De beste deployment strategie is niet degene die nooit faalt — het is degene die schade minimaliseert wanneer failure gebeurt. Progressive delivery beperkt je blast radius en geeft je tijd om te reageren.