Chapter 15 of 47 · Workloads and Services

Deployment strategies: rolling, recreate, blue-green, canary

Shipping a new version means swapping old Pods for new ones. There are four common ways to do the swap. They differ in three things: is there downtime, do two versions run at the same time, and how many users see a broken release before you notice. Picking the right one is a trade-off, not a rule.

The four at a glance

Each lane shows how many users get the old version (green) and the new one (amber) over time:

Four deployment strategies over timeRolling: old version shrinks while new grows. Recreate: old stops, a gap with nothing, then new. Blue-green: old serves everyone, then all traffic switches at once to the new. Canary: a small slice gets the new version first, then it grows. Rolling Recreate down Blue-green switch Canary time →

Rolling update (the default)

You already know this one from chapter 10: Pods are swapped a few at a time. Old and new run side by side for a while, there is no downtime, and a broken version stalls instead of taking you down, if you have a readiness probe (chapter 13).

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1           # at most 1 extra Pod during the update
      maxUnavailable: 0     # never fewer ready Pods than replicas

Catch: for a few minutes, some users get v1 and some get v2. Your API and database must cope with both versions at once.

Recreate: stop everything, then start

spec:
  strategy:
    type: Recreate

All old Pods are stopped first; only then are new Pods created. Simple and clean: never two versions at once. The price is downtime while the new Pods start.

Use it when two versions truly cannot run together: a database migration that breaks the old code, or an app that must have one writer to a disk (ReadWriteOnce, chapter 31).

Blue-green: build the new one next door, then flip

Think of a theatre with two stages. The audience watches the blue stage while the crew sets up the green one. When green is ready and checked, the curtain moves: everyone watches green. If something is wrong, move the curtain back.

Kubernetes has no special object for it. You build it from two Deployments and one Service, and the Service selector is the curtain:

Service selects the blue Deploymentposts-srvselector: app=posts, version=blueposts-blue · v13 Pods, serving usersposts-green · v23 Pods, tested, no users

v2 is fully running next to v1. You can test it through a separate test Service before anyone sees it.

# two Deployments: posts-blue (labels app=posts, version=blue, image v1)
#                  posts-green (labels app=posts, version=green, image v2)

# the switch:
$ kubectl patch service posts-srv \
    -p '{"spec":{"selector":{"app":"posts","version":"green"}}}'

Canary: let a few users try it first

Miners once took a canary into the mine: if the air was bad, the bird showed it first. A canary release sends a small share of real traffic to the new version. If errors rise, only a few users were affected and you pull it back. If it looks good, you grow the share step by step.

The simple Kubernetes way: two Deployments whose Pods share the label the Service selects. The Service spreads requests over all those Pods, so the split follows the Pod count. Try it:

# posts-stable: replicas 9, labels app=posts, track=stable, image v1
# posts-canary: replicas 1, labels app=posts, track=canary, image v2
# posts-srv selector: app=posts          ← matches both, ~10% to v2

$ kubectl scale deployment posts-canary --replicas=3    # grow the canary
$ kubectl scale deployment posts-stable --replicas=7
# all good? update posts-stable to v2 and delete posts-canary

For precise percentages, let a router split the traffic by weight. With the Gateway API (chapter 27) it is built in:

rules:
  - backendRefs:
      - name: posts-stable
        port: 4000
        weight: 95
      - name: posts-canary
        port: 4000
        weight: 5

Tools that automate this

Doing canaries by hand means watching dashboards and editing numbers. Tools do the steps for you, check error rates and latency between steps, and roll back on their own:

ToolWhat it adds
Argo RolloutsA Rollout object that replaces a Deployment and supports blue-green and canary steps like "5%, wait 10 min, check metrics, 25%…".
FlaggerWorks next to your normal Deployment; drives a service mesh or ingress to shift traffic and checks metrics automatically.
KnativeA serverless layer whose services split traffic between revisions by percentage.

Some teams also add steps before and after a deploy, such as a database migration Job before and a smoke test after. Kubernetes has no built-in hook for that; CI pipelines, Helm hooks or the tools above handle it.

Side by side

RollingRecreateBlue-greenCanary
DowntimeNoneYesNoneNone
Two versions at onceYes, brieflyNeverRunning, but users see oneYes, on purpose
Extra capacityA little (maxSurge)NoneDoubleA little
Rollback speedMinutes (another rollout)MinutesSeconds (flip back)Seconds (remove canary)
Users hit by a bad releaseGrowing share until it stallsEveryoneEveryone, after the switchOnly the small share
Built into KubernetesYesYesBy hand (labels)By hand, or tools

Which one?

Recap

Quick check

You run 2 stable Pods and 1 canary Pod behind one Service. Roughly what share of users sees the canary?
Show answer

About a third. The Service spreads requests evenly over all matching Pods, so the split is 1 of 3. That is why "by Pod count" canaries are coarse with few replicas.

Deployment strategies: common questions

How do you do a blue-green deployment in Kubernetes?

Run two Deployments with different version labels and switch the Service selector from the old one to the new one. Switching back is the rollback.

How does a canary release work in Kubernetes?

Run a small canary Deployment next to the stable one behind the same Service, or split traffic by weight with the Gateway API, and grow it if metrics stay healthy.