all_lessons/kubernetes_genai/18lesson 18 / 18

Part VI - Governance and capstone

Capstone: Production GenAI Platform

Lesson 17 was the last new mechanism: agents that loop, call tools, and hold state on the cluster. You now have every part — artifacts and registries, weight delivery, the GPU platform, multi-GPU topology, runtime tuning, autoscaling and routing, disaggregated serving, observability, guardrails, customization, training jobs, batch scheduling, RAG, and agents. What you do not yet have is the wiring that lets all of it change safely while serving live traffic. This capstone assembles the seventeen lessons into one production blueprint and gives that blueprint its missing organ: a control loop that proposes a change, proves it is safe, promotes it, watches it, and reverses it when the watch goes red.

Source coverage
Synthesis of the full PDF plus the operational layer the book implies but does not spell out: release management, governance, capacity planning, and incident response. Every section ties back to a numbered lesson in this track.
Linear position
Prerequisite: All of 0117 — you can package a model, land its weights, schedule it on GPUs, tune it, autoscale and route it, observe it, guardrail it, fine-tune it, ground it with RAG, and run it as an agent. Each gave you a working component.
New capability: A release control loop that lets you change any of those components — a new model version, a new routing policy, a new adapter — against live traffic with eval gates, canary, and rollback, so change is reversible and quality is measured rather than hoped for.
The plan
Five moves. (1) State the central idea: a production platform is a control loop, not a deployment. (2) Draw the full platform map — every lesson's component in one diagram — so you can see what flows through it: models, tokens, identity, state, evidence, and money. (3) Walk one release end to end as a numbered pipeline: propose a digest from the registry, gate on offline evals, shadow it, canary 5% watching TTFT/TPOT/quality/cost, then ramp or roll back. (4) Make FinOps a real number — derive dollars per 1M tokens from GPU price and throughput — and treat cost as an SLO, not a finance surprise. (5) Secure the full path, not just the app; then failure modes, a checklist, and the hand-off to applying the blueprint.

1 · A platform is a control loop, not a deployment

The instinct after sixteen lessons of mechanism is to think the job is "run vLLM in a pod and point a Service at it." That is a deployment, and a deployment is a frozen snapshot. A platform is the opposite of frozen: it is a system whose entire purpose is to change — new model versions ship weekly, prompts get edited, adapters get swapped, traffic shifts — while never dropping below its quality, latency, and cost guarantees. The only structure that makes constant change safe is a feedback loop, the same shape as a thermostat or a PID controller: propose a change → measure its effect → keep it or reverse it → feed what you learned back into the rules.

propose → a declared change: model digest, routing weight, adapter, replica count (lessons 04, 09, 13)
evaluate → prove it does not regress before it sees a real user: offline evals + shadow traffic (lessons 08, 11, 12)
promote → expose it to a controlled slice: canary at 1–5%, then ramp (lesson 09)
watch → SLOs in real time: TTFT, TPOT, error rate, quality, $/1M tokens (lesson 11)
reverse or commit → roll back on any red signal; otherwise ramp to 100% (lesson 09)
feed back → every incident becomes a new eval case and a new policy rule (lessons 12, 11)

Three terms define the loop. TTFT (time to first token) is the latency from request to the first output token — it is dominated by the prefill phase, where the model reads the prompt and fills its KV cache. TPOT (time per output token) is the steady-state inter-token latency during decode, when the model emits one token at a time. $/1M tokens is the unit cost of serving — section 4 derives it. These three plus error rate are the SLOs the "watch" stage guards; if a release moves any of them the wrong way, the loop reverses it automatically.

The mental model: routing (lesson 09) chose which one branch handles a request; this loop chooses which version of the whole stack is live, and it does so continuously rather than once. The deployment is just the loop's current set-point — the temperature the thermostat is currently holding. Push the set-point (propose a change), and the loop's job is to reach it without ever letting the room get uncomfortable.

Each stage maps to a piece of machinery you already built, which is why this is a capstone and not a new topic. The propose stage is a declarative diff (a registry digest, a routing weight, an adapter) reconciled by GitOps — section 3. Evaluate reuses the offline eval harness from guardrails (lesson 12) and the benchmark contracts from tuning (lesson 08). Promote is the weighted router from autoscaling/routing (lesson 09). Watch is the metric/trace pipeline from observability (lesson 11). Reverse is a routing-weight flip — cheap precisely because the incumbent never stopped running. And feed back is the discipline that turns each incident into a permanent eval case or policy rule, so the loop's rules tighten over time instead of decaying. A loop missing any one stage is not a slower loop — it is an open loop, which is to say a bet.

2 · The full platform map

Every lesson in this track is a box in one diagram. The hot path (left to right) is what a user's request actually traverses; the surrounding planes — registry, observability, policy, cost, and the eval-feedback edge — are the control loop wrapped around it.

                         ┌──────────── control plane ────────────┐
   git (source of truth)  │  registry/signing(04)  policy/RBAC(12,§5) │
        │ GitOps reconcile │  observability(11)     FinOps/quota(§4)   │
        v                  └───────────────┬───────────────────────┘
  ┌─────────────┐    ┌──────────────┐    ┌──┴────────────┐    ┌────────┐
  │ model        │    │ GPU runtime   │    │ router/gateway │    │ users  │
  │ artifact(04) │ -> │ vLLM on GPUs  │ -> │ autoscale +    │ -> │        │
  │ weights(05)  │    │ topology(07)  │    │ canary(09)     │    │        │
  │              │    │ tuning(08)    │    │ guardrails(12) │    │        │
  └─────────────┘    │ disagg(10)    │    └───────────────┘    └────┬───┘
   adapters(13)  ->   │ + RAG(16)     │      ^                        │
   training jobs(14)  │ + agents(17)  │      │ release gates          │ feedback
   batch/fairness(15) └──────────────┘      │ <- incidents <----------┘
                                            (cost/security/eval failures)

Read the map as flows, not just boxes. A model enters as a signed artifact (lesson 04), its weights are delivered into pods (lesson 05), it runs on a GPU node (lesson 06) across some tensor-parallel or pipeline topology (lesson 07) tuned for throughput (lesson 08), possibly disaggregated into separate prefill and decode pools (lesson 10), and adapted with LoRA adapters or fine-tuning jobs (lessons 1314) run under batch/fairness scheduling (lesson 15). Tokens flow through the router and gateway, autoscaled and canaried (lesson 09), filtered by guardrails (lesson 12). Identity rides every hop as RBAC and tenant context. State lives in the KV cache, RAG index (lesson 16), and agent memory (lesson 17). Evidence — traces, metrics, eval scores — pours into observability (lesson 11). And money is metered as GPU-hours and dollars per million tokens (section 4). The control loop is the act of changing any box and letting the surrounding planes tell you whether the change was good.

3 · One release, end to end

Concrete is the only way this lands. Walk a single release of a chat model from "a new checkpoint exists" to "100% of traffic is on it" — or back to where it started. GitOps is the substrate: the desired state of the platform (model references, routing weights, replica counts, policies) lives declaratively in a git repository, and a reconciler (Argo CD / Flux) continuously drives the cluster to match what git says. You do not kubectl apply to production; you open a pull request, and merging it is the release. This matters for the loop: git is the audit log of every set-point change, rollback is a git revert, and "what is deployed" is answerable by reading a file instead of interrogating the cluster.

The change that starts the release is a one-line diff to the routing config — a canary (a small slice of real traffic sent to the new version, named after the caged bird miners used as an early warning):

# platform/routing.yaml — the desired state, in git
model: chat-70b
candidate:
  ref: sha256:c3d4...            # new build, pinned by digest, not :latest
  weight: 5                       # canary: 5% of traffic
incumbent:
  ref: sha256:a1b2...            # still running, takes the other 95%
  weight: 95
1 · ProposeA PR bumps the model reference from digest sha256:a1b2… to sha256:c3d4… (the new build, lesson 04). The digest — not a mutable tag like :latest — is what gets deployed, so the exact bytes are pinned and the signature is verifiable.
2 · Offline eval gateAn eval gate is an automated pass/fail check wired into CI that blocks the merge unless the candidate clears a quality bar. CI pulls the candidate, serves it, and runs the eval suite (lessons 08/11/12): quality on a held-out set, refusal/safety rate, format compliance. If quality drops below baseline or unsafe-output rate rises, the gate fails and the PR cannot merge. This is the cheapest place to catch a bad model.
3 · Shadow trafficThe candidate gets a real copy of live requests but its responses are discarded — users never see them. You compare its TTFT/TPOT, error rate, and (sampled) quality against production on identical inputs, with zero user risk. Catches latency and stability regressions evals miss.
4 · Canary 5%The router (lesson 09) sends 5% of real traffic to the candidate and 95% to the incumbent. Now you watch the four SLOs side by side on real users at small blast radius.
5 · Ramp or roll backIf all SLOs hold for the bake window, ramp 5 → 25 → 50 → 100%. If any rollback criterion trips, the router instantly shifts traffic back to the incumbent — a routing-weight change, seconds not minutes, because the old version is still running.

The canary's rollback criteria are defined before rollout and encoded as alerts, e.g.:

# rollback if ANY of these fire on the canary during the bake window
canary_rollback_if:
  - p95_ttft_ms        > 1.15 * baseline_p95_ttft_ms   # >15% TTFT regression
  - p95_tpot_ms        > 1.15 * baseline_p95_tpot_ms
  - error_rate         > 0.5%                          # absolute ceiling
  - quality_score      < baseline_quality - 0.02       # eval regression
  - cost_per_1m_tokens > 1.20 * baseline_cost          # FinOps SLO (§4)
Rollback is the release plan, not the contingency
A model release without a defined, fast rollback path is not a release — it is a bet. Because the incumbent keeps serving 95% throughout the canary, rollback is just shifting a routing weight, which is why canary-with-rollback beats a hard cutover: the escape hatch is already open. The expensive failures in this track all share one root cause — change shipped faster than it could be measured or reversed.

4 · FinOps — cost is an SLO, with a real number

FinOps is making GPU spend visible and controllable in the same terms as latency and quality. The instinct is to treat a cost spike as a finance problem discovered at month-end. On a GPU platform that is far too late: idle GPUs and runaway token volume burn money by the hour. So cost becomes a platform SLO with its own alert (it was in the rollback list above), and the unit you reason in is dollars per 1M tokens.

Worked number — $/1M tokens from GPU price ÷ throughput
The formula is one line: $/1M tokens = (node $/hour) ÷ (aggregate output tokens/hour, in millions). Fill it in.

Numerator — node cost. Take an 8×H100 node at roughly $2.50/GPU-hour on-demand. Eight GPUs → 8 × $2.50 = $20.00/hour for the whole node, GPUs only (ignore CPU/network for the first cut).
Denominator — throughput. Lesson 08 measured a single H100 at 1,800–2,000 tokens/s — but on a small model with short synthetic prompts. Our node runs a 70B model tensor-parallel across all 8 GPUs (lesson 07), and the workload contract is realistic: long prompts, real concurrency. Sustained aggregate output is about 1,200 tokens/s for the node. (Fewer tokens/s than one GPU on a toy workload, because a 70B model is ~35× the weights to stream per token and the prompts are real — exactly the "a number is meaningless without its contract" lesson from 08.) That is 1,200 × 3600 = 4,320,000 = 4.32M tokens/hour.
Divide. $20/hour ÷ 4.32 M-tokens/hour ≈ $4.63 per 1M output tokens.

Now the lever is obvious: anything that raises tokens/hour at fixed node cost cuts $/1M proportionally. Better batching and tuning (lesson 08) that lifts node throughput to 1,800 tokens/s6.48M tokens/hour drops cost to $20 ÷ 6.48 ≈ $3.09 — a 33% cut with zero new hardware. Conversely, running the node at 50% utilization halves the denominator and doubles the effective cost to ≈ $9.26, which is why an idle GPU is a FinOps incident, not a spare. The same arithmetic exposes the trap in cheap-looking compression: int4 quantization (lesson 13) might raise throughput 40% yet, if it regresses quality, raises cost per successful task — the metric that actually matters.

The controls that defend this SLO are the same ones from autoscaling and scheduling, re-read as cost levers:

Quota
Per-tenant token/GPU budgets (lesson 15 fairness). Bounds worst-case spend per team and prevents one tenant starving the cluster.
Admission control
Reject or queue requests above a rate at the gateway before they consume GPU time. The cheapest token is the one you never decode.
Load shedding
Under overload, drop low-priority traffic to protect SLOs for the rest — a graceful degradation, not a crash.
Scale-to-floor
Autoscaling (lesson 09) removes idle replicas; a non-zero floor trades a little idle cost for avoiding cold-start TTFT spikes.

Track these per workload: $/GPU-hour, $/1M input tokens and $/1M output tokens (output is the expensive half — it is the decode phase), idle-GPU cost, cold-start waste, KV-cache/prefix-cache hit savings, and the metric that ties cost to value: cost per successful task. A cheap model that fails half its tasks is not cheap.

Attribute every one of those numbers to a tenant. Once each team's traffic carries an identity (the same identity RBAC uses in section 5), GPU-seconds and tokens can be metered per team and turned into chargeback (the team's budget is actually billed) or showback (they see the cost without being billed). This closes the FinOps loop: a team that owns its $/1M-token line will tune its own prompts and pick a smaller model when it can, in a way no central mandate achieves. The per-tenant quota from lesson 15 is then both a fairness control and a spend cap — the same mechanism reread through the cost lens.

5 · Security across the full path

The most common security mistake on a GenAI platform is securing the application — the pod, the Service, the API — while leaving the things that make it a model platform unguarded. The threat surface is the whole path: model artifacts, registries, prompts, retrieved documents (lesson 16), tool calls (lesson 17), adapters (lesson 13), training data (lesson 14), logs, and human-approval flows. Each is a place a secret can leak, a poisoned input can enter, or an unsafe action can fire.

LayerControlWhat it protects against
Identity / accessRBAC, least-privilege ServiceAccountsA compromised pod reading other tenants' secrets or models
NetworkNetworkPolicy (default-deny)Lateral movement; a breached RAG sidecar reaching the registry
WorkloadPod Security Admission (restricted)Privilege escalation, host mounts, running as root
SecretsExternal secret store, no plaintext in envAPI keys / registry creds leaking via logs or image layers
Supply chainArtifact signing + verification, SBOMs, license checksAn unsigned or known-vulnerable model/image reaching the cluster
Data pathPII redaction, tenant isolation, prompt/tool guardrails (lesson 12)Leaking retrieved data across tenants; a model invoking a destructive tool

Four of those terms earn a definition, because they are where GenAI platforms differ from ordinary web services. Pod Security Admission (PSA) is Kubernetes' built-in admission controller that enforces the Pod Security Standards: label a namespace restricted and the API server rejects any pod that runs as root, mounts the host filesystem, or asks for privileged capabilities — exactly the escape hatches a compromised model server would reach for. Artifact signing (Sigstore/cosign) attaches a cryptographic signature to a model or image; an admission policy then refuses to run anything whose signature does not verify, so an unsigned or tampered model never reaches a GPU. An SBOM (software bill of materials) is a machine-readable inventory of every dependency baked into an artifact — the manifest you grep when a CVE drops, instead of guessing which of 400 images is affected. Tenant isolation is the guarantee that team A's prompts, retrieved documents (lesson 16), KV cache, and logs can never be seen by team B — enforced by namespaces, per-tenant ServiceAccounts and NetworkPolicies, and per-tenant RAG indices, not by hoping the application filters correctly.

The platform principle that ties them together: make the secure path the easy path. If shipping a signed, SBOM-attested model through the GitOps pipeline is less work than side-loading an unsigned one, engineers do the safe thing by default — the policy gate is the path of least resistance, not a hurdle. Security that relies on people choosing the harder route fails the first busy week. The full upstream reference is the Kubernetes security checklist.

6 · Incident drills — closing the loop

The loop is only real if the "feed back" edge works: every incident must become a permanent test or policy so the same failure cannot ship twice. Map each incident class to its fast control and its durable follow-up artifact.

IncidentDetected byFast controlDurable follow-up
Latency regressionTTFT/TPOT SLO alert (11)Canary rollback (09)Benchmark case + SLO alert tuned (08)
Quality regressionEval score dropEval gate halts promoteNew eval example added to suite
Cost spike$/1M-token SLO alert (§4)Quota / admission / load shedCapacity model + quota update (15)
Unsafe output / tool callGuardrail trip / audit log (12,17)Policy block + auditGuardrail regression test

Run these as drills, not only as real incidents: deliberately deploy a slightly-worse model and confirm the eval gate catches it; inject latency and confirm the canary rolls back inside the bake window. A rollback path you have never exercised is a rollback path that does not work.

Failure modes

  • Deploy with no eval baseline or rollback path. A new model ships straight to 100% with nothing to compare it against and no fast reverse. The signal that reveals it: the first quality complaint comes from users, not from a gate, and "rollback" means rebuilding and redeploying the old image — minutes to hours of degraded traffic.
  • Cost as a finance surprise. Spend is reviewed monthly instead of alerting in real time, so a runaway-token incident or a fleet of idle GPUs burns for weeks. The signal: the cost graph is only ever looked at after the bill, and there is no $/1M-token SLO wired into the canary.
  • Security stops at the app. RBAC and NetworkPolicy guard the serving pod, but model artifacts are unsigned, prompts and retrieved docs are untrusted, and tool calls are ungated. The signal: you can name the pod's SecurityContext but not who can push to the model registry or what gates a destructive tool call.
  • Untested rollback / unmeasured canary. The pipeline has a canary stage but no defined rollback criteria, so "watch" is a human squinting at a dashboard. The signal: rollbacks are slow, manual, and argued about during the incident.
  • Mutable references. Deploying model:latest instead of a digest means two clusters can run different bytes under the same name, and you cannot reproduce or audit what served a given request.

Implementation checklist

  • Is runtime config, routing policy, model references, and infrastructure all in git as the single source of truth, reconciled by GitOps — never hand-applied to production?
  • Does every promotion pass offline evals and shadow traffic and a canary, with rollback criteria defined and encoded as alerts before rollout?
  • Are models referenced by signed digest, not mutable tags, with SBOM and license checks in the gate?
  • Do you track GPU capacity, $/1M input and output tokens, idle/cold-start cost, and cost per successful task — with cost wired in as a canary SLO?
  • Are quota, admission control, and load shedding configured as product controls, not just finance reports?
  • Is the full path secured — RBAC, default-deny NetworkPolicy, restricted Pod Security, external secrets, signing/SBOMs/license checks, PII redaction, tenant isolation — and is the secure path the easy path?
  • Does every incident class have a fast control and a durable follow-up test, and have you drilled the rollback recently?

Checkpoint exercise

Try it
Take any one component you would change in production — a new model version, a new LoRA adapter, or a routing-policy tweak — and write its release as a GitOps PR: the declared change, the offline eval gate it must pass, the shadow + canary plan, the four rollback criteria with numeric thresholds, and the one new eval case you would add if it failed. Then compute the candidate's $/1M output tokens from a GPU price and a throughput number, and decide whether the cost-per-1M SLO threshold in your rollback list is tight enough.

Where this points next

This is the last lesson — there is no next mechanism to add, because you now have all of them and the loop that wires them together. The hand-off is to practice: take a real workload and walk it around the loop until the muscle is reflexive. Two directions help. Re-read any component lesson — 08 tuning, 09 autoscaling/routing, 12 guardrails — now seeing each as a knob inside the release loop rather than a standalone topic, and return to the track index to see the whole arc at once. And for the layer above this one — how the platform serves a product, not just a model — the ML Systems Design capstone picks up where this leaves off. Then go browse the rest of all_lessons: the platform you built here is the substrate every other track's system runs on.

Takeaway
A production GenAI platform is not "run vLLM in a pod" — it is a control loop that moves models, tokens, identity, state, evidence, and money through a cluster with measurable quality and reversible change. The loop is: propose a declared change (a registry digest, a routing weight, an adapter, lessons 04/09/13) → prove it with offline evals and shadow traffic (08/11/12) → promote it through a canary watching TTFT/TPOT/error/quality/cost SLOs (09/11) → ramp or instantly roll back → feed every incident back into a new eval case and policy rule (12). GitOps makes git the source of truth and every release a pull request; a defined fast rollback turns change from a bet into an experiment. FinOps makes cost an SLO — $/1M tokens derived from GPU price ÷ throughput (≈$4.63 on 8×H100 at 1,200 tok/s), defended by quota, admission control, and load shedding. Security covers the full path — not just the pod but artifacts, prompts, retrieved data, tool calls, and adapters — and the platform's job is to make the secure, reversible path the easy one.

Interview prompts