A manifest that applies cleanly and a workload that's actually ready for production traffic are two different things — the API server will happily accept a Deployment with no resource limits, no probes, and a single replica. Here's what we check before calling something production-ready.
Resource requests and limits, set from real usage
Without requests, the scheduler is guessing. Without limits, one noisy pod can starve every other workload on the node. Set both from actual observed usage (a load test, or a few days of real traffic in staging) — not a round number picked because it looked safe.
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"Readiness and liveness probes — and knowing which is which
A liveness probe failing gets your container killed and restarted — use it for "this process is deadlocked and will never recover." A readiness probe failing just pulls the pod out of the Service's load-balancing rotation — use it for "I'm alive but not ready for traffic yet" (still warming a cache, still connecting to a database). Confusing the two means a slow-starting pod gets killed in a restart loop instead of just being given time.
A PodDisruptionBudget, so a node drain doesn't take you to zero
Cluster upgrades and node maintenance drain nodes voluntarily, one at a time. Without a PDB, Kubernetes is free to evict every replica of a Deployment during that drain if they all happen to land on the node being drained.
apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
minAvailable: 1
selector:
matchLabels:
app: your-appAutoscaling that's actually wired up
HPA and the cluster autoscaler solve different problems and you usually need both — we've written about that distinction separately, since it's the single most common autoscaling misconfiguration we see.
What this checklist doesn't cover
Network policies, secrets management, and RBAC scoping are just as important and deliberately left out here — they're a security posture, not a readiness checklist, and deserve their own review. And none of this replaces an actual load test against your specific workload; a checklist tells you what's missing, not how your application behaves under load.