hands-on labKubernetes in your browser

Rolling Updates, Rollback & Blue-Green for AI Inference

Ship a new model version without dropping requests. Master Kubernetes' three deployment strategies, rolling update with readiness probes, rollback after a bad release, and blue-green via Service-selector swap, all on a stand-in inference Deployment.

time
35 min
checked steps
5
level
Intermediate
setup
None

$29.99a month with Pro

Pro opens this lab and every other one. Cancel any time.

The job

An inference team ships model v2 on a Friday afternoon. Halfway through the rollout they realize v2 has a tokenizer regression, every third query returns garbage. The right answer isn't "shut everything down", it's kubectl rollout undo, instantly reverted to v1, no users notice. This lab teaches the deploy-and-recover muscle that NVIDIA platform engineers use weekly: rolling update with readiness probes, abort-and-rollback when a release is bad, and blue-green via Service-selector swap when you need a clean atomic cut.

5 steps, each checked when you finish it

A check runs your work at the end of every step. Hints and the full solution are there if you get stuck.

  1. 1

    Three deployment strategies and the readiness-probe contract

    You already know how to author a Deployment (last lab).

    read this step below ↓

  2. 2

    Rolling update: v1 → v2 with a readiness probe

    You're going to author an inference Deployment with 3 replicas and a readiness probe that simulates "model is loading", then update its VERSION from v1 to v2 and watch the rolling update happen pod-by-pod.

  3. 3

    Bad rollout: abort and rollback with `kubectl rollout undo`

    You're about to ship inference v3.

  4. 4

    Blue-green: atomic cutover via Service selector swap

    Two inference Deployments are already running side-by-side: inference-blue (v1) and inference-green (v2).

  5. 5

    Triage Day: three rollout-related failures

    The lab platform has just deployed three broken rollout scenarios, one per strategy you covered in earlier steps.

Step 1 as it appears in the lab

The lab’s own text. The hint and the solution stay inside the lab.

Step 1: Three deployment strategies and the readiness-probe contract

Three deployment strategies — and the readiness-probe contract

You already know how to author a Deployment (last lab). Now you're going to update one — replace v1 with v2 — without dropping inference traffic. Kubernetes gives you three native strategies for this. Picking the right one depends on what your workload tolerates during the cutover window.

StrategyWhat it doesWhen to use
Rolling Update (default)Within ONE Deployment, gradually replaces v1 pods with v2 pods. Overlap controlled by maxSurge and maxUnavailable. Both versions live during the rollout.The 90% case — stateless inference, idempotent requests, mixed-version operation is fine.
Rollback (via kubectl rollout undo)Restores the previous revision. The Deployment controller keeps the old ReplicaSet (scaled to 0) for instant rollback.When v2 is broken — bad model weights, regression in tokenizer, OOM at runtime. Decision-to-recovery in under a minute.
Blue-Green (via Service selector swap)TWO Deployments running side-by-side. ONE Service. Cutover = edit the Service's selector to point from blue → green.When you can't tolerate ANY mixed-version window — schema-incompatible changes, lockstep DB migrations. Costs 2× capacity during cutover.

A fourth pattern, canary, is two Deployments behind one Service with the traffic split coming from replica counts (9 v1 + 1 v2 = 10% canary). It's a useful primitive but real production canaries usually go through a service-mesh layer (Istio, Linkerd) for percentage-precise traffic splitting; we'll skip it for this lab and focus on the three Kubernetes-native ones.

The readiness probe is non-optional

The single most important field for any of these strategies is the pod template's readinessProbe. Without it, Kubernetes considers a pod Ready as soon as its container starts — not when the application inside is actually serving. For an inference server that needs 30 seconds to load weights from disk, that 30-second window is when:

  1. The Service routes incoming requests to the pod (because Endpoints sees Ready=True).
  2. The application returns 500s because model.from_pretrained() is still running.

Result: a successful "rolling update" that actually drops every Nth request through the rollout.

A readiness probe is one of three forms:

readinessProbe:
  # 1. HTTP — the most common, tests an app endpoint
  httpGet:
    path: /v1/models
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 5

  # 2. Exec — tests by running a command in the container
  exec:
    command: [test, -f, /tmp/ready]   # the app touches this file when serving
  initialDelaySeconds: 5
  periodSeconds: 2

  # 3. TCP — tests that a port is listening (weakest)
  tcpSocket:
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 5

In this lab we'll use exec probes against a /tmp/ready marker file — our stub container "loads its model" by sleeping a few seconds, then touch /tmp/ready to signal it's serving. The Service-routing flow is the same as production HTTP probes; we just don't run a real HTTP server.

Read what's there

Run the step's command (or click Run). It dumps:

  1. Every Deployment in the cluster.
  2. CoreDNS's strategy block — the cluster's own rolling-update settings, a baseline for what defaults look like.
  3. A summary of the three strategy fields you'll touch in the next steps.

Note the default rolling-update settings (maxSurge: 25%, maxUnavailable: 25%). For a 4-replica Deployment, that means at most 5 pods exist during a rollout (4 + 25%) and at most 1 can be Unavailable at a time (4 - 25%). For inference workloads, those defaults are usually fine.

Two production-relevant trade-offs

maxSurge controls cost during rollout. A larger value = faster rollout = more replicas in flight = more GPU/CPU. For 8-replica GPU inference, maxSurge: 1 (rather than 25% = 2) keeps you from briefly running 10 GPU pods.

maxUnavailable controls availability margin. A larger value = more pods can be down at once = lower capacity during the rollout. For a service near its capacity ceiling, maxUnavailable: 0 forbids any drop in available replicas during rollout (and maxSurge >= 1 is required to make progress).

Why this matters in practice: inference deployment is the most-frequent action a platform engineer takes. Knowing which strategy + which readinessProbe shape + which surge/unavailable trade-off your workload needs is the basic motor skill the NCA-AIIO exam tests under AI Infrastructure & Operations.

what you get

  • A Kubernetes cluster and terminal in your browser
  • A check at the end of every step
  • Hints and the full solution
  • Nothing to install or configure

before you start

  • Completed `nca-aiio-workload-controllers` (or comfortable with Deployment + Service)
  • Familiar with `kubectl describe`, reading pod events, and the rolling-update concept

Exam domains covered

AI Infrastructure & OperationsWorkload Management

Part of the GPU and Kubernetes track

Lab 10 of 20. GPU scheduling on your own Kubernetes cluster, the GPU Operator, CUDA kernels and profiling.

Questions about this lab

What's the difference between rolling update, blue-green, and canary?

All three are ways to replace v1 pods with v2 pods. Rolling update does it gradually within ONE Deployment, Kubernetes tears down old pods and brings up new ones simultaneously, with overlap controlled by maxSurge (how many extra pods may exist) and maxUnavailable (how many old pods may be torn down before replacements are Ready). Blue-green uses TWO Deployments running in parallel; a Service points at one of them via label selector, and you cut over by editing the Service's selector, atomic, but requires double the capacity during cutover. Canary also uses TWO Deployments behind one Service, but the traffic split comes from the replica counts (e.g., 9 v1 pods + 1 v2 pod = 10% canary). The right choice depends on your tolerance for partial-failure exposure during rollout (rolling = always exposing some fraction, canary = explicit small fraction, blue-green = atomic but expensive).

Why does my Deployment hand traffic to pods that aren't ready?

Because you didn't set a readinessProbe. Without one, the kubelet considers a pod "Ready" as soon as the container starts, not when the application inside is actually serving. For an inference server that takes 30 seconds to load model weights, that 30-second window is when Kubernetes is happily routing requests to a pod that's still doing from_pretrained() and returning 500s. The fix: every Deployment template needs a readinessProbe that genuinely tests the application, httpGet on a /health or /v1/models/ endpoint, an exec checking that a model file exists, or a tcpSocket test against the inference port (the weakest of the three but still better than nothing). The Service routes only to pods with Ready=True; with a real probe, that's an actual application-level check.

When should I use blue-green over rolling update?

Blue-green when you need an atomic cut with no overlap window where v1 and v2 are simultaneously live. Common use cases: schema-incompatible model changes (a new tokenizer that produces different inputs to the model), database migration in lockstep with the deployment, regulated environments where mixed-version operation is forbidden. The trade-off is capacity: during the cutover you're running 2N pods (the full v1 + the full v2). Rolling update only needs N + maxSurge pods. For an N=20 inference fleet on expensive GPUs, blue-green doubles your GPU bill for the rollout window, significant. Most production teams reach for rolling update by default and only escalate to blue-green when explicitly required.

How do I roll back a bad deployment?

kubectl rollout undo deployment/<name> reverts to the previous revision. The Deployment controller keeps the last revisionHistoryLimit ReplicaSets (default 10), they're the "saved games" you can roll back to. kubectl rollout history deployment/<name> lists them; kubectl rollout undo --to-revision=N reverts to a specific one. The rollback is itself a rolling update, Kubernetes scales the previous ReplicaSet back up while scaling the current one down. This is why revisionHistoryLimit matters: with 0, you have no rollback target; with the default 10, you can rewind through the last ten releases. For production inference, the right pattern is: rollout → smoke test (5-30 seconds of traffic) → if metrics look bad, kubectl rollout undo immediately. The decision-to-recovery loop is under a minute when you've practiced it.

What you'll learn

Shipping a new model version is a more dangerous action than most engineers realize. Without the right deployment strategy, a single bad release can drop all your inference traffic for the duration of the rollout, route requests to pods that are still loading their model, or, worst, leave the cluster in a half-rolled-out state with no clear recovery path. This lab teaches the three Kubernetes-native answers: rolling update (the default, replaces pods one at a time with overlap controlled by maxSurge/maxUnavailable), rollback (reverting a bad release with one command via kubectl rollout undo), and blue-green (running v1 and v2 side by side, swapping the Service's selector for an atomic cut).

Each strategy has the same building blocks, Deployments, ReplicaSets, Services, readiness probes, but combines them in different orders. By the end you'll have updated an inference Deployment from v1 to v2, watched a bad v3 rollout get stuck and reverted with one command, and run a v1/v2 blue-green cut by editing a Service's selector. You finish with a Triage Day where each strategy is broken in a strategy-specific way, and you fix each by reading the cluster's state.