Kubernetes Administration — Level by Level›21 · Release strategies: rolling, blue-green, canary

Lesson 21 of 32 · Level 3 — Application delivery

Release strategies: rolling, blue-green, canary

Choose how new versions reach users: rolling updates (the Kubernetes default), blue-green switches with instant rollback, and canaries that shift traffic gradually while watching metrics, done by hand with Services, Ingress and the Gateway API, or automated with Argo Rollouts and Flagger.

Practitioner → Advanced
Key wordsrolling updaterecreateblue-greencanarymaxSurgemaxUnavailablecanary-weightHTTPRoute weightsArgo RolloutsFlaggerfeature flagsexpand and contract
Rolling update Blue-green Canary pod v1 pod v1 pod v2 pod v2 pods replaced a few at a time cheap; both versions live briefly Service selector: version=green blue v1 (idle) green v2 (live) switch all traffic at once; instant rollback, double capacity Ingress / Gateway / mesh weights stable v1 · 90% canary v2 · 10% shift weight step by step, watch metrics, abort on errors
Rolling update, blue-green and canary side by side.

Why strategy matters

Every release is a change, and most incidents follow changes. The release strategy decides how many users see a bad version and how fast you can undo it.

A school changing its lunch menu can swap dishes table by table (rolling), set up a whole second kitchen and switch all tables at once (blue-green, easy to switch back), or let one table taste the new dish first and only serve everyone if that table is happy (canary).

Rolling update (default)

Kubernetes replaces pods a few at a time (lesson 17):

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1          # at most 1 extra pod during the rollout
      maxUnavailable: 0    # never drop below the desired count
  • Cheap and automatic; readiness probes gate each step.
  • Old and new versions serve traffic at the same time for a while.
  • Rollback = another rollout (kubectl rollout undo), which also takes time.
  • Recreate stops all old pods first: simple, but causes downtime (sometimes needed when two versions can't coexist).

Blue-green

Run two complete Deployments, shop-blue (v1, live) and shop-green (v2), and point the Service at one of them by label:

apiVersion: v1
kind: Service
metadata:
  name: shop
spec:
  selector: { app: shop, version: blue }    # change to green to switch
  ports: [ { port: 80, targetPort: http } ]
$ kubectl apply -f shop-green.yaml                  # deploy v2 alongside v1
$ kubectl rollout status deploy/shop-green
$ kubectl run t --rm -it --image=busybox -- wget -qO- http://shop-green-preview   # test v2 directly (a second Service)
$ kubectl patch svc shop -p '{"spec":{"selector":{"app":"shop","version":"green"}}}'   # switch
$ kubectl patch svc shop -p '{"spec":{"selector":{"app":"shop","version":"blue"}}}'    # instant rollback if needed
  • Instant switch and rollback; test the new version fully before users see it.
  • Needs double capacity during the release; long-lived connections may stay on the old pods until they close.

Canary

Send a small percentage of traffic to the new version, watch, then increase.

With ingress-nginx (a second, "canary" Ingress for the same host):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"     # 10% of requests
spec:
  ingressClassName: nginx
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend: { service: { name: shop-v2, port: { number: 80 } } }

With the Gateway API (lesson 20), use weights on HTTPRoute backendRefs (90/10). Service meshes offer the same for internal traffic (see Service Mesh — Istio & Linkerd, lesson 05).

Automate it: progressive delivery

Manual canaries depend on someone watching dashboards. Argo Rollouts and Flagger automate the steps and the decision:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: shop
spec:
  replicas: 5
  selector:
    matchLabels: { app: shop }
  template:
    metadata:
      labels: { app: shop }
    spec:
      containers:
        - name: shop
          image: registry.example.com/shop:2.4.0
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: { duration: 10m }
        - setWeight: 50
        - pause: { duration: 10m }

Add an analysis (a Prometheus query for error rate or latency) so the rollout aborts automatically when metrics degrade. With traffic-routing integrations (ingress, Gateway API, meshes) weights are exact; without them, weights are approximated by replica counts. Argo Rollouts also supports blue-green.

Choosing

Strategy Blast radius Rollback speed Extra capacity Needs
Rolling Growing during rollout Minutes Small (surge) Readiness probes
Blue-green All at switch time (after testing) Seconds 2× Two Deployments, selector switch
Canary Small, controlled Seconds (shift weight back) Small Traffic splitting + good metrics

Whatever you choose:

  • Data compatibility: old and new versions overlap, so schema changes use expand → migrate → contract (see SRE & Production Incident Response, lesson 04).
  • Feature flags separate deploying code from releasing features, and give the fastest "off switch".
  • Decide the abort rule before starting (e.g. error rate above the SLO burn threshold).

Related planning topics: how much capacity a cluster needs (Cluster Design — Architect Track, lesson 04), and proving a platform in a PoC before production (lessons 02–03 of the same track).

Try it: all three

  1. Deploy podinfo v1 (lesson 17) and do a rolling update to a newer tag while curling in a loop; watch versions mix.
  2. Build blue and green Deployments with a version label, switch the Service selector, and switch back.
  3. Add a canary Ingress at 10% and count responses per version over 100 requests; raise it to 50%.
  4. Install Argo Rollouts, convert the Deployment to a Rollout with the steps above, and use kubectl argo rollouts get rollout shop --watch.
  5. Make the canary return errors and abort the rollout.

Going deeper: release engineering

  • Tie canary analysis to your SLOs (burn-rate queries) rather than ad-hoc thresholds.
  • Roll out platform changes (ingress, CNI, policies) progressively too: cluster by cluster, site by site (see GitOps with Argo CD, lesson 07).
  • Keep rollback as one action (Git revert, rollouts abort), and practise it.

Recap

  • Rolling: default, cheap, gradual; versions overlap.
  • Blue-green: full second copy, instant switch and rollback, double capacity.
  • Canary: small share first, metrics decide; automate with Argo Rollouts/Flagger.
  • Keep data changes compatible, use feature flags, and agree the abort rule up front.

This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.